本文整理汇总了C++中G_Sound函数的典型用法代码示例。如果您正苦于以下问题:C++ G_Sound函数的具体用法?C++ G_Sound怎么用?C++ G_Sound使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了G_Sound函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: NPC_BSGM_Attack
//.........这里部分代码省略.........
NPC_UpdateAngles( qtrue, qtrue );
return;
}
//If we don't have an enemy, just idle
if ( NPC_CheckEnemyExt() == qfalse || !NPC->enemy )
{
NPC->enemy = NULL;
NPC_BSGM_Patrol();
return;
}
enemyLOS = enemyCS = qfalse;
bMove = qtrue;
faceEnemy = qfalse;
shoot = qfalse;
hitAlly = qfalse;
VectorClear( impactPos );
enemyDist = DistanceSquared( NPC->currentOrigin, NPC->enemy->currentOrigin );
if ( NPC->client->ps.torsoAnim == BOTH_ATTACK4 ||
NPC->client->ps.torsoAnim == BOTH_ATTACK5 )
{
shoot = qfalse;
if ( TIMER_Done( NPC, "smackTime" ) && !NPCInfo->blockedDebounceTime )
{//time to smack
//recheck enemyDist and InFront
if ( enemyDist < MELEE_DIST_SQUARED && InFront( NPC->enemy->currentOrigin, NPC->currentOrigin, NPC->client->ps.viewangles, 0.3f ) )
{
vec3_t smackDir;
VectorSubtract( NPC->enemy->currentOrigin, NPC->currentOrigin, smackDir );
smackDir[2] += 30;
VectorNormalize( smackDir );
//hurt them
G_Sound( NPC->enemy, G_SoundIndex( "sound/weapons/galak/skewerhit.wav" ) );
G_Damage( NPC->enemy, NPC, NPC, smackDir, NPC->currentOrigin, (g_spskill->integer+1)*Q_irand( 5, 10), DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK, MOD_CRUSH );
if ( NPC->client->ps.torsoAnim == BOTH_ATTACK4 )
{//smackdown
int knockAnim = BOTH_KNOCKDOWN1;
if ( PM_CrouchAnim( NPC->enemy->client->ps.legsAnim ) )
{//knockdown from crouch
knockAnim = BOTH_KNOCKDOWN4;
}
//throw them
smackDir[2] = 1;
VectorNormalize( smackDir );
G_Throw( NPC->enemy, smackDir, 50 );
NPC_SetAnim( NPC->enemy, SETANIM_BOTH, knockAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
}
else
{//uppercut
//throw them
G_Throw( NPC->enemy, smackDir, 100 );
//make them backflip
NPC_SetAnim( NPC->enemy, SETANIM_BOTH, BOTH_KNOCKDOWN5, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
}
//done with the damage
NPCInfo->blockedDebounceTime = 1;
}
}
}
else if ( NPC->lockCount ) //already shooting laser
{//sometimes use the laser beam attack, but only after he's taken down our generator
shoot = qfalse;
if ( NPC->lockCount == 1 )
{//charging up
if ( TIMER_Done( NPC, "beamDelay" ) )
示例2: emplaced_gun_use
//.........这里部分代码省略.........
return;
}
}
// don't allow using it again for half a second
if ( self->delay + 500 < level.time )
{
int oldWeapon = activator->s.weapon;
if ( oldWeapon == WP_SABER )
{
self->alt_fire = activator->client->ps.SaberActive();
}
// swap the users weapon with the emplaced gun and add the ammo the gun has to the player
activator->client->ps.weapon = self->s.weapon;
Add_Ammo( activator, WP_EMPLACED_GUN, self->count );
activator->client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_EMPLACED_GUN );
// Allow us to point from one to the other
activator->owner = self; // kind of dumb, but when we are locked to the weapon, we are owned by it.
self->activator = activator;
G_RemoveWeaponModels( activator );
extern void ChangeWeapon( gentity_t *ent, int newWeapon );
if ( activator->NPC )
{
ChangeWeapon( activator, WP_EMPLACED_GUN );
}
else if ( activator->s.number == 0 )
{
// we don't want for it to draw the weapon select stuff
cg.weaponSelect = WP_EMPLACED_GUN;
CG_CenterPrint( "@SP_INGAME_EXIT_VIEW", SCREEN_HEIGHT * 0.95 );
}
// Since we move the activator inside of the gun, we reserve a solid spot where they were standing in order to be able to get back out without being in solid
if ( self->nextTrain )
{//you never know
G_FreeEntity( self->nextTrain );
}
self->nextTrain = G_Spawn();
//self->nextTrain->classname = "emp_placeholder";
self->nextTrain->contents = CONTENTS_MONSTERCLIP|CONTENTS_PLAYERCLIP;//hmm... playerclip too now that we're doing it for NPCs?
G_SetOrigin( self->nextTrain, activator->client->ps.origin );
VectorCopy( activator->mins, self->nextTrain->mins );
VectorCopy( activator->maxs, self->nextTrain->maxs );
gi.linkentity( self->nextTrain );
//need to inflate the activator's mins/maxs since the gunsit anim puts them outside of their bbox
VectorSet( activator->mins, -24, -24, -24 );
VectorSet( activator->maxs, 24, 24, 40 );
// Move the activator into the center of the gun. For NPC's the only way the can get out of the gun is to die.
VectorCopy( self->s.origin, activator->client->ps.origin );
activator->client->ps.origin[2] += 30; // move them up so they aren't standing in the floor
gi.linkentity( activator );
// the gun will track which weapon we used to have
self->s.weapon = oldWeapon;
// Lock the player
activator->client->ps.eFlags |= EF_LOCKED_TO_WEAPON;
activator->owner = self; // kind of dumb, but when we are locked to the weapon, we are owned by it.
self->activator = activator;
self->delay = level.time; // can't disconnect from the thing for half a second
// Let the gun be considered an enemy
//Ugh, so much AI code seems to assume enemies are clients, maybe this shouldn't be on, but it's too late in the game to change it now without knowing what side-effects this will have
self->svFlags |= SVF_NONNPC_ENEMY;
self->noDamageTeam = activator->client->playerTeam;
// FIXME: don't do this, we'll try and actually put the player in this beast
// move the player to the center of the gun
// activator->contents = 0;
// VectorCopy( self->currentOrigin, activator->client->ps.origin );
SetClientViewAngle( activator, self->pos1 );
//FIXME: should really wait a bit after spawn and get this just once?
self->waypoint = NAV::GetNearestNode(self);
#ifdef _DEBUG
if ( self->waypoint == -1 )
{
gi.Printf( S_COLOR_RED"ERROR: no waypoint for emplaced_gun %s at %s\n", self->targetname, vtos(self->currentOrigin) );
}
#endif
G_Sound( self, G_SoundIndex( "sound/weapons/emplaced/emplaced_mount.mp3" ));
#ifdef _IMMERSION
G_Force( self, G_ForceIndex( "fffx/weapons/emplaced/emplaced_mount", FF_CHANNEL_TOUCH ) );
#endif // _IMMERSION
if ( !(self->spawnflags&EMPLACED_PLAYERUSE) || activator->s.number == 0 )
{//player-only usescript or any usescript
// Run use script
G_ActivateBehavior( self, BSET_USE );
}
}
}
示例3: NPC_Touch
void NPC_Touch(gentity_t *self, gentity_t *other, trace_t *trace)
{
if(!self->NPC)
return;
SaveNPCGlobals();
SetNPCGlobals( self );
if ( self->message && self->health <= 0 )
{//I am dead and carrying a key
if ( other && player && player->health > 0 && other == player )
{//player touched me
char *text;
qboolean keyTaken;
//give him my key
if ( Q_stricmp( "goodie", self->message ) == 0 )
{//a goodie key
if ( (keyTaken = INV_GoodieKeyGive( other )) == qtrue )
{
text = "cp @INGAME_TOOK_IMPERIAL_GOODIE_KEY";
G_AddEvent( other, EV_ITEM_PICKUP, (FindItemForInventory( INV_GOODIE_KEY )-bg_itemlist) );
}
else
{
text = "cp @INGAME_CANT_CARRY_GOODIE_KEY";
}
}
else
{//a named security key
if ( (keyTaken = INV_SecurityKeyGive( player, self->message )) == qtrue )
{
text = "cp @INGAME_TOOK_IMPERIAL_SECURITY_KEY";
G_AddEvent( other, EV_ITEM_PICKUP, (FindItemForInventory( INV_SECURITY_KEY )-bg_itemlist) );
}
else
{
text = "cp @INGAME_CANT_CARRY_SECURITY_KEY";
}
}
if ( keyTaken )
{//remove my key
gi.G2API_SetSurfaceOnOff( &self->ghoul2[self->playerModel], "l_arm_key", 0x00000002 );
self->message = NULL;
//FIXME: temp pickup sound
G_Sound( player, G_SoundIndex( "sound/weapons/key_pkup.wav" ) );
//FIXME: need some event to pass to cgame for sound/graphic/message?
}
//FIXME: temp message
gi.SendServerCommand( NULL, text );
}
}
if ( other->client )
{//FIXME: if pushing against another bot, both ucmd.rightmove = 127???
//Except if not facing one another...
if ( other->health > 0 )
{
NPCInfo->touchedByPlayer = other;
}
if ( other == NPCInfo->goalEntity )
{
NPCInfo->aiFlags |= NPCAI_TOUCHED_GOAL;
}
if( !(self->svFlags&SVF_LOCKEDENEMY) && !(self->svFlags&SVF_IGNORE_ENEMIES) && !(other->flags & FL_NOTARGET) )
{
if ( self->client->enemyTeam )
{//See if we bumped into an enemy
if ( other->client->playerTeam == self->client->enemyTeam )
{//bumped into an enemy
if( NPCInfo->behaviorState != BS_HUNT_AND_KILL && !NPCInfo->tempBehavior )
{//MCG - Begin: checking specific BS mode here, this is bad, a HACK
//FIXME: not medics?
if ( NPC->enemy != other )
{//not already mad at them
G_SetEnemy( NPC, other );
}
// NPCInfo->tempBehavior = BS_HUNT_AND_KILL;
}
}
}
}
//FIXME: do this if player is moving toward me and with a certain dist?
/*
if ( other->s.number == 0 && self->client->playerTeam == other->client->playerTeam )
{
VectorAdd( self->client->pushVec, other->client->ps.velocity, self->client->pushVec );
}
*/
}
else
{//FIXME: check for SVF_NONNPC_ENEMY flag here?
if ( other->health > 0 )
{
if ( NPC->enemy == other && (other->svFlags&SVF_NONNPC_ENEMY) )
{
NPCInfo->touchedByPlayer = other;
}
//.........这里部分代码省略.........
示例4: Mark1_FireBlaster
/*
-------------------------
Mark1_FireBlaster
- Shoot the left weapon, the multi-blaster
-------------------------
*/
void Mark1_FireBlaster(void)
{
vec3_t muzzle1,enemy_org1,delta1,angleToEnemy1;
static vec3_t forward, vright, up;
static vec3_t muzzle;
gentity_t *missile;
mdxaBone_t boltMatrix;
int bolt;
// Which muzzle to fire from?
if ((NPCInfo->localState <= LSTATE_FIRED0) || (NPCInfo->localState == LSTATE_FIRED4))
{
NPCInfo->localState = LSTATE_FIRED1;
bolt = NPC->genericBolt1;
}
else if (NPCInfo->localState == LSTATE_FIRED1)
{
NPCInfo->localState = LSTATE_FIRED2;
bolt = NPC->genericBolt2;
}
else if (NPCInfo->localState == LSTATE_FIRED2)
{
NPCInfo->localState = LSTATE_FIRED3;
bolt = NPC->genericBolt3;
}
else
{
NPCInfo->localState = LSTATE_FIRED4;
bolt = NPC->genericBolt4;
}
gi.G2API_GetBoltMatrix( NPC->ghoul2, NPC->playerModel,
bolt,
&boltMatrix, NPC->currentAngles, NPC->currentOrigin, (cg.time?cg.time:level.time),
NULL, NPC->s.modelScale );
gi.G2API_GiveMeVectorFromMatrix( boltMatrix, ORIGIN, muzzle1 );
if (NPC->health)
{
CalcEntitySpot( NPC->enemy, SPOT_HEAD, enemy_org1 );
VectorSubtract (enemy_org1, muzzle1, delta1);
vectoangles ( delta1, angleToEnemy1 );
AngleVectors (angleToEnemy1, forward, vright, up);
}
else
{
AngleVectors (NPC->currentAngles, forward, vright, up);
}
G_PlayEffect( "bryar/muzzle_flash", muzzle1, forward );
G_Sound( NPC, G_SoundIndex("sound/chars/mark1/misc/mark1_fire"));
missile = CreateMissile( muzzle1, forward, 1600, 10000, NPC );
missile->classname = "bryar_proj";
missile->s.weapon = WP_BRYAR_PISTOL;
missile->damage = 1;
missile->dflags = DAMAGE_DEATH_KNOCKBACK;
missile->methodOfDeath = MOD_ENERGY;
missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
}
示例5: RunEmplacedWeapon
void RunEmplacedWeapon( gentity_t *ent, usercmd_t **ucmd )
{
if (( (*ucmd)->buttons & BUTTON_USE || (*ucmd)->forwardmove < 0 || (*ucmd)->upmove > 0 ) && ent->owner && ent->owner->delay + 500 < level.time )
{
ent->owner->s.loopSound = 0;
if ( ent->owner->e_UseFunc == useF_eweb_use )//yeah, crappy way to check this, but...
{
G_Sound( ent, G_SoundIndex( "sound/weapons/eweb/eweb_dismount.mp3" ));
}
else
{
G_Sound( ent, G_SoundIndex( "sound/weapons/emplaced/emplaced_dismount.mp3" ));
}
#ifdef _IMMERSION
G_Force( ent, G_ForceIndex( "fffx/weapons/emplaced/emplaced_dismount", FF_CHANNEL_TOUCH ) );
#endif // _IMMERSION
ExitEmplacedWeapon( ent );
(*ucmd)->buttons &= ~BUTTON_USE;
if ( (*ucmd)->upmove > 0 )
{//don't actually jump
(*ucmd)->upmove = 0;
}
}
else
{
// this is a crappy way to put sounds on a moving eweb....
if ( ent->owner
&& ent->owner->e_UseFunc == useF_eweb_use )//yeah, crappy way to check this, but...
{
if ( !VectorCompare( ent->client->ps.viewangles, ent->owner->movedir ))
{
ent->owner->s.loopSound = G_SoundIndex( "sound/weapons/eweb/eweb_aim.wav" );
ent->owner->fly_sound_debounce_time = level.time;
}
else
{
if ( ent->owner->fly_sound_debounce_time + 100 <= level.time )
{
ent->owner->s.loopSound = 0;
}
}
VectorCopy( ent->client->ps.viewangles, ent->owner->movedir );
}
// don't allow movement, weapon switching, and most kinds of button presses
(*ucmd)->forwardmove = 0;
(*ucmd)->rightmove = 0;
(*ucmd)->upmove = 0;
(*ucmd)->buttons &= (BUTTON_ATTACK|BUTTON_ALT_ATTACK);
(*ucmd)->weapon = ent->client->ps.weapon; //WP_EMPLACED_GUN;
if ( ent->health <= 0 )
{
ExitEmplacedWeapon( ent );
}
}
}
示例6: fx_rain_think
void fx_rain_think( gentity_t *ent )
{
if (player)
{
if (ent->count!=0)
{
ent->count--;
if (ent->count==0 || (ent->count%2)==0)
{
gi.WE_SetTempGlobalFogColor(ent->pos2); // Turn Off
if (ent->count==0)
{
ent->nextthink = level.time + Q_irand(1000, 12000);
}
else if (ent->count==2)
{
ent->nextthink = level.time + Q_irand(150, 450);
}
else
{
ent->nextthink = level.time + Q_irand(50, 150);
}
}
else
{
gi.WE_SetTempGlobalFogColor(ent->pos3); // Turn On
ent->nextthink = level.time + 50;
}
}
else if (gi.WE_IsOutside(player->currentOrigin))
{
vec3_t effectPos;
vec3_t effectDir;
VectorClear(effectDir);
effectDir[0] += Q_flrand(-1.0f, 1.0f);
effectDir[1] += Q_flrand(-1.0f, 1.0f);
bool PlayEffect = Q_irand(1,ent->aimDebounceTime)==1;
bool PlayFlicker = Q_irand(1,ent->attackDebounceTime)==1;
bool PlaySound = (PlayEffect || PlayFlicker || Q_irand(1,ent->pushDebounceTime)==1);
// Play The Sound
//----------------
if (PlaySound && !PlayEffect)
{
VectorMA(player->currentOrigin, 250.0f, effectDir, effectPos);
G_SoundAtSpot(effectPos, G_SoundIndex(va("sound/ambience/thunder%d", Q_irand(1,4))), qtrue);
}
// Play The Effect
//-----------------
if (PlayEffect)
{
VectorMA(player->currentOrigin, 400.0f, effectDir, effectPos);
if (PlaySound)
{
G_Sound(player, G_SoundIndex(va("sound/ambience/thunder_close%d", Q_irand(1,2))));
}
// Raise It Up Into The Sky
//--------------------------
effectPos[2] += Q_flrand(600.0f, 1000.0f);
VectorClear(effectDir);
effectDir[2] = -1.0f;
G_PlayEffect("env/huge_lightning", effectPos, effectDir);
ent->nextthink = level.time + Q_irand(100, 200);
}
// Change The Fog Color
//----------------------
if (PlayFlicker)
{
ent->count = (Q_irand(1,4) * 2);
ent->nextthink = level.time + 50;
gi.WE_SetTempGlobalFogColor(ent->pos3);
}
else
{
ent->nextthink = level.time + Q_irand(1000, ent->delay);
}
}
else
{
ent->nextthink = level.time + Q_irand(1000, ent->delay);
}
}
else
{
ent->nextthink = level.time + Q_irand(1000, ent->delay);
}
}
示例7: Pilot_Steer_Vehicle
//.........这里部分代码省略.........
float AimDistance = AimDirection.SafeNorm();
float AimAccuracy = AimDirection.Dot(ActorDirection);
if (!ActorFlank && TIMER_Done(NPC, "FlankAttackCheck"))
{
TIMER_Set(NPC, "FlankAttackCheck", Q_irand(1000, 3000));
if (MoveDistance<4000 && Q_irand(0, 1)==0)
{
NPCInfo->lastAvoidSteerSideDebouncer = level.time + Q_irand(8000, 14000);
}
}
// Fly By Sounds
//---------------
if ((ActorVeh->m_pVehicleInfo->soundFlyBy || ActorVeh->m_pVehicleInfo->soundFlyBy2) &&
EnemyVeh &&
MoveDistance<800 &&
ActorSpeed>500.0f &&
TIMER_Done(NPC, "FlybySoundDebouncer")
)
{
if (EnemySpeed<100.0f || (ActorDirection.Dot(EnemyDirection)*(MoveDistance/800.0f))<-0.5f)
{
TIMER_Set(NPC, "FlybySoundDebouncer", 2000);
int soundFlyBy = ActorVeh->m_pVehicleInfo->soundFlyBy;
if (ActorVeh->m_pVehicleInfo->soundFlyBy2 && (!soundFlyBy || !Q_irand(0,1)))
{
soundFlyBy = ActorVeh->m_pVehicleInfo->soundFlyBy2;
}
G_Sound(ActorVeh->m_pParentEntity, soundFlyBy);
}
}
// FLY PAST BEHAVIOR
//===================
if (EnemySlideBreak || !TIMER_Done(NPC, "MinHoldDirectionTime"))
{
if (TIMER_Done(NPC, "MinHoldDirectionTime"))
{
TIMER_Set(NPC, "MinHoldDirectionTime", 500); // Hold For At Least 500 ms
}
ActorAccelerate = true; // Go
ActorAimAtTarget = false; // Don't Alter Our Aim Direction
ucmd.buttons &=~BUTTON_VEH_SPEED; // Let Normal Vehicle Controls Go
}
// FLANKING BEHAVIOR
//===================
else if (ActorFlank)
{
ActorAccelerate = true;
ActorDoTurbo = (MoveDistance>2500 || EnemyInTurbo);
ucmd.buttons |= BUTTON_VEH_SPEED; // Tells PMove to use the ps.speed we calculate here, not the one from g_vehicles.c
// For Flanking, We Calculate The Speed By Hand, Rather Than Using Pure Accelerate / No Accelerate Functionality
//---------------------------------------------------------------------------------------------------------------
NPC->client->ps.speed = ActorVeh->m_pVehicleInfo->speedMax * ((ActorInTurbo)?(1.35f):(1.15f));
示例8: turretG2_find_enemies
//-----------------------------------------------------
static qboolean turretG2_find_enemies( gentity_t *self )
//-----------------------------------------------------
{
qboolean found = qfalse;
int i, count;
float bestDist = self->radius * self->radius;
float enemyDist;
vec3_t enemyDir, org, org2;
qboolean foundClient = qfalse;
gentity_t *entity_list[MAX_GENTITIES], *target, *bestTarget = NULL;
if ( self->aimDebounceTime > level.time ) // time since we've been shut off
{
// We were active and alert, i.e. had an enemy in the last 3 secs
if ( self->painDebounceTime < level.time )
{
if ( !(self->spawnflags&SPF_TURRETG2_TURBO) )
{
G_Sound(self, CHAN_BODY, G_SoundIndex( "sound/chars/turret/ping.wav" ));
}
self->painDebounceTime = level.time + 1000;
}
}
VectorCopy( self->r.currentOrigin, org2 );
if ( self->spawnflags & 2 )
{
org2[2] += 20;
}
else
{
org2[2] -= 20;
}
count = G_RadiusList( org2, self->radius, self, qtrue, entity_list );
for ( i = 0; i < count; i++ )
{
trace_t tr;
target = entity_list[i];
if ( !target->client )
{
// only attack clients
if ( !(target->flags&FL_BBRUSH)//not a breakable brush
|| !target->takedamage//is a bbrush, but invincible
|| (target->NPC_targetname&&self->targetname&&Q_stricmp(target->NPC_targetname,self->targetname)!=0) )//not in invicible bbrush, but can only be broken by an NPC that is not me
{
continue;
}
//else: we will shoot at bbrushes!
}
if ( target == self || !target->takedamage || target->health <= 0 || ( target->flags & FL_NOTARGET ))
{
continue;
}
if ( target->client && target->client->sess.sessionTeam == TEAM_SPECTATOR )
{
continue;
}
if ( self->alliedTeam )
{
if ( target->client )
{
if ( target->client->sess.sessionTeam == self->alliedTeam )
{
// A bot/client/NPC we don't want to shoot
continue;
}
}
else if ( target->teamnodmg == self->alliedTeam )
{
// An ent we don't want to shoot
continue;
}
}
if ( !trap_InPVS( org2, target->r.currentOrigin ))
{
continue;
}
if ( target->client )
{
VectorCopy( target->client->renderInfo.eyePoint, org );
}
else
{
VectorCopy( target->r.currentOrigin, org );
}
if ( self->spawnflags & 2 )
{
org[2] -= 15;
}
else
{
org[2] += 5;
}
//.........这里部分代码省略.........
示例9: Rancor_Swing
void Rancor_Swing( qboolean tryGrab )
{
int radiusEntNums[128];
int numEnts;
const float radius = 88;
const float radiusSquared = (radius*radius);
int i;
vec3_t boltOrg;
numEnts = NPC_GetEntsNearBolt( radiusEntNums, radius, NPC->client->renderInfo.handRBolt, boltOrg );
for ( i = 0; i < numEnts; i++ )
{
gentity_t *radiusEnt = &g_entities[radiusEntNums[i]];
if ( !radiusEnt->inuse )
{
continue;
}
if ( radiusEnt == NPC )
{//Skip the rancor ent
continue;
}
if ( radiusEnt->client == NULL )
{//must be a client
continue;
}
if ( (radiusEnt->client->ps.eFlags2&EF2_HELD_BY_MONSTER) )
{//can't be one already being held
continue;
}
if ( DistanceSquared( radiusEnt->r.currentOrigin, boltOrg ) <= radiusSquared )
{
if ( tryGrab
&& NPC->count != 1 //don't have one in hand or in mouth already - FIXME: allow one in hand and any number in mouth!
&& radiusEnt->client->NPC_class != CLASS_RANCOR
&& radiusEnt->client->NPC_class != CLASS_GALAKMECH
&& radiusEnt->client->NPC_class != CLASS_ATST
&& radiusEnt->client->NPC_class != CLASS_GONK
&& radiusEnt->client->NPC_class != CLASS_R2D2
&& radiusEnt->client->NPC_class != CLASS_R5D2
&& radiusEnt->client->NPC_class != CLASS_MARK1
&& radiusEnt->client->NPC_class != CLASS_MARK2
&& radiusEnt->client->NPC_class != CLASS_MOUSE
&& radiusEnt->client->NPC_class != CLASS_PROBE
&& radiusEnt->client->NPC_class != CLASS_SEEKER
&& radiusEnt->client->NPC_class != CLASS_REMOTE
&& radiusEnt->client->NPC_class != CLASS_SENTRY
&& radiusEnt->client->NPC_class != CLASS_INTERROGATOR
&& radiusEnt->client->NPC_class != CLASS_VEHICLE )
{//grab
if ( NPC->count == 2 )
{//have one in my mouth, remove him
TIMER_Remove( NPC, "clearGrabbed" );
Rancor_DropVictim( NPC );
}
NPC->enemy = radiusEnt;//make him my new best friend
radiusEnt->client->ps.eFlags2 |= EF2_HELD_BY_MONSTER;
//FIXME: this makes it so that the victim can't hit us with shots! Just use activator or something
radiusEnt->client->ps.hasLookTarget = qtrue;
radiusEnt->client->ps.lookTarget = NPC->s.number;
NPC->activator = radiusEnt;//remember him
NPC->count = 1;//in my hand
//wait to attack
TIMER_Set( NPC, "attacking", NPC->client->ps.legsTimer + Q_irand(500, 2500) );
if ( radiusEnt->health > 0 && radiusEnt->pain )
{//do pain on enemy
radiusEnt->pain( radiusEnt, NPC, 100 );
//GEntity_PainFunc( radiusEnt, NPC, NPC, radiusEnt->r.currentOrigin, 0, MOD_CRUSH );
}
else if ( radiusEnt->client )
{
radiusEnt->client->ps.forceHandExtend = HANDEXTEND_NONE;
radiusEnt->client->ps.forceHandExtendTime = 0;
NPC_SetAnim( radiusEnt, SETANIM_BOTH, BOTH_SWIM_IDLE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
}
}
else
{//smack
vec3_t pushDir;
vec3_t angs;
G_Sound( radiusEnt, CHAN_AUTO, G_SoundIndex( "sound/chars/rancor/swipehit.wav" ) );
//actually push the enemy
/*
//VectorSubtract( radiusEnt->r.currentOrigin, boltOrg, pushDir );
VectorSubtract( radiusEnt->r.currentOrigin, NPC->r.currentOrigin, pushDir );
pushDir[2] = Q_flrand( 100, 200 );
VectorNormalize( pushDir );
*/
VectorCopy( NPC->client->ps.viewangles, angs );
angs[YAW] += flrand( 25, 50 );
angs[PITCH] = flrand( -25, -15 );
AngleVectors( angs, pushDir, NULL, NULL );
if ( radiusEnt->client->NPC_class != CLASS_RANCOR
&& radiusEnt->client->NPC_class != CLASS_ATST )
{
//.........这里部分代码省略.........
示例10: NPC_BSWampa_Default
/*
-------------------------
NPC_BSWampa_Default
-------------------------
*/
void NPC_BSWampa_Default( void )
{
NPC->client->ps.eFlags2 &= ~EF2_USE_ALT_ANIM;
//NORMAL ANIMS
// stand1 = normal stand
// walk1 = normal, non-angry walk
// walk2 = injured
// run1 = far away run
// run2 = close run
//VICTIM ANIMS
// grabswipe = melee1 - sweep out and grab
// stand2 attack = attack4 - while holding victim, swipe at him
// walk3_drag = walk5 - walk with drag
// stand2 = hold victim
// stand2to1 = drop victim
if ( !TIMER_Done( NPC, "rageTime" ) )
{//do nothing but roar first time we see an enemy
NPC_FaceEnemy( qtrue );
return;
}
if ( NPC->enemy )
{
if ( !TIMER_Done(NPC,"attacking") )
{//in middle of attack
//face enemy
NPC_FaceEnemy( qtrue );
//continue attack logic
enemyDist = Distance( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin );
Wampa_Attack( enemyDist, qfalse );
return;
}
else
{
if ( TIMER_Done(NPC,"angrynoise") )
{
G_Sound( NPC, CHAN_VOICE, G_SoundIndex( va("sound/chars/wampa/misc/anger%d.wav", Q_irand(1, 2)) ) );
TIMER_Set( NPC, "angrynoise", Q_irand( 5000, 10000 ) );
}
//else, if he's in our hand, we eat, else if he's on the ground, we keep attacking his dead body for a while
if( NPC->enemy->client && NPC->enemy->client->NPC_class == CLASS_WAMPA )
{//got mad at another Wampa, look for a valid enemy
if ( TIMER_Done( NPC, "wampaInfight" ) )
{
NPC_CheckEnemyExt( qtrue );
}
}
else
{
if ( ValidEnemy( NPC->enemy ) == qfalse )
{
TIMER_Remove( NPC, "lookForNewEnemy" );//make them look again right now
if ( !NPC->enemy->inuse || level.time - NPC->enemy->s.time > Q_irand( 10000, 15000 ) )
{//it's been a while since the enemy died, or enemy is completely gone, get bored with him
NPC->enemy = NULL;
Wampa_Patrol();
NPC_UpdateAngles( qtrue, qtrue );
//just lost my enemy
if ( (NPC->spawnflags&2) )
{//search around me if I don't have an enemy
NPC_BSSearchStart( NPC->waypoint, BS_SEARCH );
NPCInfo->tempBehavior = BS_DEFAULT;
}
else if ( (NPC->spawnflags&1) )
{//wander if I don't have an enemy
NPC_BSSearchStart( NPC->waypoint, BS_WANDER );
NPCInfo->tempBehavior = BS_DEFAULT;
}
return;
}
}
if ( TIMER_Done( NPC, "lookForNewEnemy" ) )
{
gentity_t *newEnemy, *sav_enemy = NPC->enemy;//FIXME: what about NPC->lastEnemy?
NPC->enemy = NULL;
newEnemy = NPC_CheckEnemy( NPCInfo->confusionTime < level.time, qfalse, qfalse );
NPC->enemy = sav_enemy;
if ( newEnemy && newEnemy != sav_enemy )
{//picked up a new enemy!
NPC->lastEnemy = NPC->enemy;
G_SetEnemy( NPC, newEnemy );
//hold this one for at least 5-15 seconds
TIMER_Set( NPC, "lookForNewEnemy", Q_irand( 5000, 15000 ) );
}
else
{//look again in 2-5 secs
TIMER_Set( NPC, "lookForNewEnemy", Q_irand( 2000, 5000 ) );
}
}
}
Wampa_Combat();
return;
}
}
else
//.........这里部分代码省略.........
示例11: Wampa_Slash
void Wampa_Slash( int boltIndex, qboolean backhand )
{
int radiusEntNums[128];
int numEnts;
const float radius = 88;
const float radiusSquared = (radius*radius);
int i;
vec3_t boltOrg;
int damage = (backhand)?Q_irand(10,15):Q_irand(20,30);
numEnts = NPC_GetEntsNearBolt( radiusEntNums, radius, boltIndex, boltOrg );
for ( i = 0; i < numEnts; i++ )
{
gentity_t *radiusEnt = &g_entities[radiusEntNums[i]];
if ( !radiusEnt->inuse )
{
continue;
}
if ( radiusEnt == NPC )
{//Skip the wampa ent
continue;
}
if ( radiusEnt->client == NULL )
{//must be a client
continue;
}
if ( DistanceSquared( radiusEnt->r.currentOrigin, boltOrg ) <= radiusSquared )
{
//smack
G_Damage( radiusEnt, NPC, NPC, vec3_origin, radiusEnt->r.currentOrigin, damage, ((backhand)?DAMAGE_NO_ARMOR:(DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK)), MOD_MELEE );
if ( backhand )
{
//actually push the enemy
vec3_t pushDir;
vec3_t angs;
VectorCopy( NPC->client->ps.viewangles, angs );
angs[YAW] += flrand( 25, 50 );
angs[PITCH] = flrand( -25, -15 );
AngleVectors( angs, pushDir, NULL, NULL );
if ( radiusEnt->client->NPC_class != CLASS_WAMPA
&& radiusEnt->client->NPC_class != CLASS_RANCOR
&& radiusEnt->client->NPC_class != CLASS_ATST )
{
G_Throw( radiusEnt, pushDir, 65 );
if ( BG_KnockDownable(&radiusEnt->client->ps) &&
radiusEnt->health > 0 && Q_irand( 0, 1 ) )
{//do pain on enemy
radiusEnt->client->ps.forceHandExtend = HANDEXTEND_KNOCKDOWN;
radiusEnt->client->ps.forceDodgeAnim = 0;
radiusEnt->client->ps.forceHandExtendTime = level.time + 1100;
radiusEnt->client->ps.quickerGetup = qfalse;
}
}
}
else if ( radiusEnt->health <= 0 && radiusEnt->client )
{//killed them, chance of dismembering
if ( !Q_irand( 0, 1 ) )
{//bite something off
int hitLoc = Q_irand( G2_MODELPART_HEAD, G2_MODELPART_RLEG );
if ( hitLoc == G2_MODELPART_HEAD )
{
NPC_SetAnim( radiusEnt, SETANIM_BOTH, BOTH_DEATH17, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
}
else if ( hitLoc == G2_MODELPART_WAIST )
{
NPC_SetAnim( radiusEnt, SETANIM_BOTH, BOTH_DEATHBACKWARD2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
}
G_Dismember( radiusEnt, NPC, radiusEnt->r.currentOrigin, hitLoc, 90, 0, radiusEnt->client->ps.torsoAnim, qtrue);
}
}
else if ( !Q_irand( 0, 3 ) && radiusEnt->health > 0 )
{//one out of every 4 normal hits does a knockdown, too
vec3_t pushDir;
vec3_t angs;
VectorCopy( NPC->client->ps.viewangles, angs );
angs[YAW] += flrand( 25, 50 );
angs[PITCH] = flrand( -25, -15 );
AngleVectors( angs, pushDir, NULL, NULL );
//[KnockdownSys]
//ported multi-direction knockdowns from SP.
G_Knockdown( radiusEnt, NPC, pushDir, 35, qtrue );
//G_Knockdown( radiusEnt );
//[/KnockdownSys]
}
G_Sound( radiusEnt, CHAN_WEAPON, G_SoundIndex( "sound/chars/rancor/swipehit.wav" ) );
}
}
}
示例12: P_WorldEffects
/*
=============
P_WorldEffects
Check for lava / slime contents and drowning
=============
*/
void P_WorldEffects(gentity_t *ent) {
int waterlevel;
if (ent->client->noclip) {
ent->client->airOutTime = level.time + HOLDBREATHTIME; // don't need air
return;
}
waterlevel = ent->waterlevel;
//
// check for drowning
//
if (waterlevel == 3) {
// if out of air, start drowning
if (ent->client->airOutTime < level.time) {
if (ent->client->ps.powerups[PW_BREATHER]) { // take air from the breather now that we need it
ent->client->ps.powerups[PW_BREATHER] -= (level.time - ent->client->airOutTime);
ent->client->airOutTime = level.time + (level.time - ent->client->airOutTime);
} else if (!g_disableDrowning.integer) { // Nico, check if drowning is disabled
// drown!
ent->client->airOutTime += 1000;
if (ent->health > 0) {
// take more damage the longer underwater
ent->damage += 2;
if (ent->damage > 15) {
ent->damage = 15;
}
// play a gurp sound instead of a normal pain sound
if (ent->health <= ent->damage) {
G_Sound(ent, G_SoundIndex("*drown.wav"));
} else if (rand() & 1) {
G_Sound(ent, G_SoundIndex("sound/player/gurp1.wav"));
} else {
G_Sound(ent, G_SoundIndex("sound/player/gurp2.wav"));
}
// don't play a normal pain sound
ent->pain_debounce_time = level.time + 200;
G_Damage(ent, NULL, NULL, NULL, NULL, ent->damage, 0, MOD_WATER);
}
}
}
} else {
ent->client->airOutTime = level.time + 12000;
ent->damage = 2;
}
//
// check for sizzle damage (move to pmove?)
//
if (waterlevel && (ent->watertype & CONTENTS_LAVA) &&
ent->health > 0 && ent->pain_debounce_time <= level.time) {
G_Damage(ent, NULL, NULL, NULL, NULL, 30 * waterlevel, 0, MOD_LAVA);
}
//
// check for burning from flamethrower
//
// JPW NERVE MP way
if (ent->s.onFireEnd && ent->client && level.time - ent->client->lastBurnTime >= MIN_BURN_INTERVAL) {
// JPW NERVE server-side incremental damage routine / player damage/health is int (not float)
// so I can't allocate 1.5 points per server tick, and 1 is too weak and 2 is too strong.
// solution: allocate damage far less often (MIN_BURN_INTERVAL often) and do more damage.
// That way minimum resolution (1 point) damage changes become less critical.
ent->client->lastBurnTime = level.time;
if ((ent->s.onFireEnd > level.time) && (ent->health > 0)) {
gentity_t *attacker;
attacker = g_entities + ent->flameBurnEnt;
G_Damage(ent, attacker, attacker, NULL, NULL, 5, DAMAGE_NO_KNOCKBACK, MOD_FLAMETHROWER); // JPW NERVE was 7
}
}
// jpw
}
示例13: Sentry_Fire
/*
-------------------------
Sentry_Fire
-------------------------
*/
void Sentry_Fire (void)
{
vec3_t muzzle;
static vec3_t forward, vright, up;
gentity_t *missile;
mdxaBone_t boltMatrix;
int bolt, which;
NPCS.NPC->flags &= ~FL_SHIELDED;
if ( NPCS.NPCInfo->localState == LSTATE_POWERING_UP )
{
if ( TIMER_Done( NPCS.NPC, "powerup" ))
{
NPCS.NPCInfo->localState = LSTATE_ATTACKING;
NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
}
else
{
// can't do anything right now
return;
}
}
else if ( NPCS.NPCInfo->localState == LSTATE_ACTIVE )
{
NPCS.NPCInfo->localState = LSTATE_POWERING_UP;
G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/sentry/misc/sentry_shield_open") );
NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_POWERUP1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
TIMER_Set( NPCS.NPC, "powerup", 250 );
return;
}
else if ( NPCS.NPCInfo->localState != LSTATE_ATTACKING )
{
// bad because we are uninitialized
NPCS.NPCInfo->localState = LSTATE_ACTIVE;
return;
}
// Which muzzle to fire from?
which = NPCS.NPCInfo->burstCount % 3;
switch( which )
{
case 0:
bolt = trap_G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash1");
break;
case 1:
bolt = trap_G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash2");
break;
case 2:
default:
bolt = trap_G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash03");
}
trap_G2API_GetBoltMatrix( NPCS.NPC->ghoul2, 0,
bolt,
&boltMatrix, NPCS.NPC->r.currentAngles, NPCS.NPC->r.currentOrigin, level.time,
NULL, NPCS.NPC->modelScale );
BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle );
AngleVectors( NPCS.NPC->r.currentAngles, forward, vright, up );
// G_Sound( NPC, G_SoundIndex("sound/chars/sentry/misc/shoot.wav"));
G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle, forward );
missile = CreateMissile( muzzle, forward, 1600, 10000, NPCS.NPC, qfalse );
missile->classname = "bryar_proj";
missile->s.weapon = WP_BRYAR_PISTOL;
missile->dflags = DAMAGE_DEATH_KNOCKBACK;
missile->methodOfDeath = MOD_BRYAR_PISTOL;
missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
NPCS.NPCInfo->burstCount++;
NPCS.NPC->attackDebounceTime = level.time + 50;
missile->damage = 5;
// now scale for difficulty
if ( g_npcspskill.integer == 0 )
{
NPCS.NPC->attackDebounceTime += 200;
missile->damage = 1;
}
else if ( g_npcspskill.integer == 1 )
{
NPCS.NPC->attackDebounceTime += 100;
missile->damage = 3;
}
}
示例14: Remote_MaintainHeight
/*
-------------------------
Remote_MaintainHeight
-------------------------
*/
void Remote_MaintainHeight( void )
{
float dif;
// Update our angles regardless
NPC_UpdateAngles( qtrue, qtrue );
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;
}
}
// If we have an enemy, we should try to hover at or a little below enemy eye level
if ( NPC->enemy )
{
if (TIMER_Done( NPC, "heightChange"))
{
TIMER_Set( NPC,"heightChange",Q_irand( 1000, 3000 ));
// Find the height difference
dif = (NPC->enemy->r.currentOrigin[2] + Q_irand( 0, NPC->enemy->r.maxs[2]+8 )) - 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;
NPC->client->ps.velocity[2] = (NPC->client->ps.velocity[2]+dif)/2;
// NPC->fx_time = level.time;
G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/remote/misc/hiss.wav"));
}
}
}
else
{
gentity_t *goal = NULL;
if ( NPCInfo->goalEntity ) // Is there a goal?
{
goal = NPCInfo->goalEntity;
}
else
{
goal = NPCInfo->lastGoalEntity;
}
if ( goal )
{
dif = goal->r.currentOrigin[2] - NPC->r.currentOrigin[2];
if ( fabs( dif ) > 24 )
{
dif = ( dif < 0 ? -24 : 24 );
NPC->client->ps.velocity[2] = (NPC->client->ps.velocity[2]+dif)/2;
}
}
}
// Apply friction
if ( NPC->client->ps.velocity[0] )
{
NPC->client->ps.velocity[0] *= VELOCITY_DECAY;
if ( fabs( NPC->client->ps.velocity[0] ) < 1 )
{
NPC->client->ps.velocity[0] = 0;
}
}
if ( NPC->client->ps.velocity[1] )
{
NPC->client->ps.velocity[1] *= VELOCITY_DECAY;
if ( fabs( NPC->client->ps.velocity[1] ) < 1 )
{
NPC->client->ps.velocity[1] = 0;
}
}
}
示例15: Rancor_Attack
void Rancor_Attack( float distance, qboolean doCharge )
{
if ( !TIMER_Exists( NPC, "attacking" ) )
{
if ( NPC->count == 2 && NPC->activator )
{
}
else if ( NPC->count == 1 && NPC->activator )
{//holding enemy
if ( NPC->activator->health > 0 && Q_irand( 0, 1 ) )
{//quick bite
NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
TIMER_Set( NPC, "attack_dmg", 450 );
}
else
{//full eat
NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_ATTACK3, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
TIMER_Set( NPC, "attack_dmg", 900 );
//Make victim scream in fright
if ( NPC->activator->health > 0 && NPC->activator->client )
{
G_AddEvent( NPC->activator, Q_irand(EV_DEATH1, EV_DEATH3), 0 );
NPC_SetAnim( NPC->activator, SETANIM_TORSO, BOTH_FALLDEATH1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
if ( NPC->activator->NPC )
{//no more thinking for you
TossClientItems( NPC );
NPC->activator->NPC->nextBStateThink = Q3_INFINITE;
}
}
}
}
else if ( NPC->enemy->health > 0 && doCharge )
{//charge
vec3_t fwd, yawAng;
VectorSet( yawAng, 0, NPC->client->ps.viewangles[YAW], 0 );
AngleVectors( yawAng, fwd, NULL, NULL );
VectorScale( fwd, distance*1.5f, NPC->client->ps.velocity );
NPC->client->ps.velocity[2] = 150;
NPC->client->ps.groundEntityNum = ENTITYNUM_NONE;
NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_MELEE2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
TIMER_Set( NPC, "attack_dmg", 1250 );
}
else if ( !Q_irand(0, 1) )
{//smash
NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_MELEE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
TIMER_Set( NPC, "attack_dmg", 1000 );
}
else
{//try to grab
NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_ATTACK2, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
TIMER_Set( NPC, "attack_dmg", 1000 );
}
TIMER_Set( NPC, "attacking", NPC->client->ps.legsTimer + random() * 200 );
}
// Need to do delayed damage since the attack animations encapsulate multiple mini-attacks
if ( TIMER_Done2( NPC, "attack_dmg", qtrue ) )
{
vec3_t shakePos;
switch ( NPC->client->ps.legsAnim )
{
case BOTH_MELEE1:
Rancor_Smash();
G_GetBoltPosition( NPC, NPC->client->renderInfo.handLBolt, shakePos, 0 );
G_ScreenShake( shakePos, NULL, 4.0f, 1000, qfalse );
//CGCam_Shake( 1.0f*playerDist/128.0f, 1000 );
break;
case BOTH_MELEE2:
Rancor_Bite();
TIMER_Set( NPC, "attack_dmg2", 450 );
break;
case BOTH_ATTACK1:
if ( NPC->count == 1 && NPC->activator )
{
G_Damage( NPC->activator, NPC, NPC, vec3_origin, NPC->activator->r.currentOrigin, Q_irand( 25, 40 ), DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK, MOD_MELEE );
if ( NPC->activator->health <= 0 )
{//killed him
//make it look like we bit his head off
//NPC->activator->client->dismembered = qfalse;
G_Dismember( NPC->activator, NPC, NPC->activator->r.currentOrigin, G2_MODELPART_HEAD, 90, 0, NPC->activator->client->ps.torsoAnim, qtrue);
//G_DoDismemberment( NPC->activator, NPC->activator->r.currentOrigin, MOD_SABER, 1000, HL_HEAD, qtrue );
NPC->activator->client->ps.forceHandExtend = HANDEXTEND_NONE;
NPC->activator->client->ps.forceHandExtendTime = 0;
NPC_SetAnim( NPC->activator, SETANIM_BOTH, BOTH_SWIM_IDLE1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
}
G_Sound( NPC->activator, CHAN_AUTO, G_SoundIndex( "sound/chars/rancor/chomp.wav" ) );
}
break;
case BOTH_ATTACK2:
//try to grab
Rancor_Swing( qtrue );
break;
case BOTH_ATTACK3:
if ( NPC->count == 1 && NPC->activator )
{
//cut in half
if ( NPC->activator->client )
//.........这里部分代码省略.........