void GM_StartGloat( void ) { NPCS.NPC->wait = 0; NPC_SetSurfaceOnOff( NPCS.NPC, "torso_galakface", TURN_ON ); NPC_SetSurfaceOnOff( NPCS.NPC, "torso_galakhead", TURN_ON ); NPC_SetSurfaceOnOff( NPCS.NPC, "torso_eyes_mouth", TURN_ON ); NPC_SetSurfaceOnOff( NPCS.NPC, "torso_collar", TURN_ON ); NPC_SetSurfaceOnOff( NPCS.NPC, "torso_galaktorso", TURN_ON ); NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_STAND2TO1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); NPCS.NPC->client->ps.legsTimer += 500; NPCS.NPC->client->ps.torsoTimer += 500; }
/* ------------------------- NPC_Mark2_Pain - look at what was hit and see if it should be removed from the model. ------------------------- */ void NPC_Mark2_Pain(gentity_t *self, gentity_t *attacker, int damage) { int newBolt,i; int hitLoc = gPainHitLoc; NPC_Pain( self, attacker, damage ); for (i=0;i<3;i++) { if ((hitLoc==HL_GENERIC1+i) && (self->locationDamage[HL_GENERIC1+i] > AMMO_POD_HEALTH)) // Blow it up? { if (self->locationDamage[hitLoc] >= AMMO_POD_HEALTH) { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("torso_canister%d",(i+1)) ); if ( newBolt != -1 ) { NPC_Mark2_Part_Explode(self,newBolt); } NPC_SetSurfaceOnOff( self, va("torso_canister%d",(i+1)), TURN_OFF ); break; } } } G_Sound( self, CHAN_AUTO, G_SoundIndex( "sound/chars/mark2/misc/mark2_pain" )); // If any pods were blown off, kill him if (self->count > 0) { G_Damage( self, NULL, NULL, NULL, NULL, self->health, DAMAGE_NO_PROTECTION, MOD_UNKNOWN ); } }
/* ------------------------- 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 ) ); } // 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(); } } } }
/* ------------------------- NPC_Mark1_Pain - look at what was hit and see if it should be removed from the model. ------------------------- */ void NPC_Mark1_Pain(gentity_t *self, gentity_t *attacker, int damage) { int newBolt,i,chance; int hitLoc = gPainHitLoc; NPC_Pain( self, attacker, damage ); G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_pain")); // Hit in the CHEST??? if (hitLoc==HL_CHEST) { chance = Q_irand( 1, 4); if ((chance == 1) && (damage > 5)) { NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); } } // Hit in the left arm? else if ((hitLoc==HL_ARM_LT) && (self->locationDamage[HL_ARM_LT] > LEFT_ARM_HEALTH)) { if (self->locationDamage[hitLoc] >= LEFT_ARM_HEALTH) // Blow it up? { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*flash3" ); if ( newBolt != -1 ) { NPC_Mark1_Part_Explode(self,newBolt); } NPC_SetSurfaceOnOff( self, "l_arm", TURN_OFF ); } } // Hit in the right arm? else if ((hitLoc==HL_ARM_RT) && (self->locationDamage[HL_ARM_RT] > RIGHT_ARM_HEALTH)) // Blow it up? { if (self->locationDamage[hitLoc] >= RIGHT_ARM_HEALTH) { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*flash4" ); if ( newBolt != -1 ) { NPC_Mark1_Part_Explode( self, newBolt ); } NPC_SetSurfaceOnOff( self, "r_arm", TURN_OFF ); } } // Check ammo pods else { for (i=0;i<6;i++) { if ((hitLoc==HL_GENERIC1+i) && (self->locationDamage[HL_GENERIC1+i] > AMMO_POD_HEALTH)) // Blow it up? { if (self->locationDamage[hitLoc] >= AMMO_POD_HEALTH) { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",(i+1)) ); if ( newBolt != -1 ) { NPC_Mark1_Part_Explode(self,newBolt); } NPC_SetSurfaceOnOff( self, va("torso_tube%d",(i+1)), TURN_OFF ); NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); break; } } } } // Are both guns shot off? if ((trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" )>0) && (trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" )>0)) { G_Damage(self,NULL,NULL,NULL,NULL,self->health,0,MOD_UNKNOWN); } }
/* ------------------------- NPC_BSDroid_Pain ------------------------- */ void NPC_Droid_Pain(gentity_t *self, gentity_t *attacker, int damage) { gentity_t *other = attacker; int anim; int mod = gPainMOD; float pain_chance; VectorCopy( self->NPC->lastPathAngles, self->s.angles ); if ( self->client->NPC_class == CLASS_R5D2 ) { pain_chance = NPC_GetPainChance( self, damage ); // Put it in pain if ( mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT || random() < pain_chance ) // Spin around in pain? Demp2 always does this { // Health is between 0-30 or was hit by a DEMP2 so pop his head if ( !self->s.m_iVehicleNum && ( self->health < 30 || mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT ) ) { if (!(self->spawnflags & 2)) // Doesn't have to ALWAYSDIE { if ((self->NPC->localState != LSTATE_SPINNING) && (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "head" ))) { NPC_SetSurfaceOnOff( self, "head", TURN_OFF ); if ( self->client->ps.m_iVehicleNum ) { vec3_t up; AngleVectors( self->r.currentAngles, NULL, NULL, up ); G_PlayEffectID( G_EffectIndex("chunks/r5d2head_veh"), self->r.currentOrigin, up ); } else { G_PlayEffectID( G_EffectIndex("small_chunks") , self->r.currentOrigin, vec3_origin ); G_PlayEffectID( G_EffectIndex("chunks/r5d2head"), self->r.currentOrigin, vec3_origin ); } //self->s.powerups |= ( 1 << PW_SHOCKED ); //self->client->ps.powerups[PW_SHOCKED] = level.time + 3000; self->client->ps.electrifyTime = level.time + 3000; TIMER_Set( self, "droidsmoketotal", 5000); TIMER_Set( self, "droidspark", 100); self->NPC->localState = LSTATE_SPINNING; } } } // Just give him normal pain for a little while else { anim = self->client->ps.legsAnim; if ( anim == BOTH_STAND2 ) // On two legs? { anim = BOTH_PAIN1; } else // On three legs { anim = BOTH_PAIN2; } NPC_SetAnim( self, SETANIM_BOTH, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); // Spin around in pain self->NPC->localState = LSTATE_SPINNING; TIMER_Set( self, "roam", Q_irand(1000,2000)); } } } else if (self->client->NPC_class == CLASS_MOUSE) { if ( mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT ) { self->NPC->localState = LSTATE_SPINNING; //self->s.powerups |= ( 1 << PW_SHOCKED ); //self->client->ps.powerups[PW_SHOCKED] = level.time + 3000; self->client->ps.electrifyTime = level.time + 3000; } else { self->NPC->localState = LSTATE_BACKINGUP; } self->NPC->scriptFlags &= ~SCF_LOOK_FOR_ENEMIES; } else if (self->client->NPC_class == CLASS_R2D2) { pain_chance = NPC_GetPainChance( self, damage ); if ( mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT || random() < pain_chance ) // Spin around in pain? Demp2 always does this { // Health is between 0-30 or was hit by a DEMP2 so pop his head if ( !self->s.m_iVehicleNum && ( self->health < 30 || mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT ) ) { if (!(self->spawnflags & 2)) // Doesn't have to ALWAYSDIE { if ((self->NPC->localState != LSTATE_SPINNING) && (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "head" ))) { NPC_SetSurfaceOnOff( self, "head", TURN_OFF ); if ( self->client->ps.m_iVehicleNum ) { vec3_t up; AngleVectors( self->r.currentAngles, NULL, NULL, up ); G_PlayEffectID( G_EffectIndex("chunks/r2d2head_veh"), self->r.currentOrigin, up ); } else { G_PlayEffectID( G_EffectIndex("small_chunks") , self->r.currentOrigin, vec3_origin ); G_PlayEffectID( G_EffectIndex("chunks/r2d2head"), self->r.currentOrigin, vec3_origin ); } //self->s.powerups |= ( 1 << PW_SHOCKED ); //self->client->ps.powerups[PW_SHOCKED] = level.time + 3000; self->client->ps.electrifyTime = level.time + 3000; TIMER_Set( self, "droidsmoketotal", 5000); TIMER_Set( self, "droidspark", 100); self->NPC->localState = LSTATE_SPINNING; } } } // Just give him normal pain for a little while else { anim = self->client->ps.legsAnim; if ( anim == BOTH_STAND2 ) // On two legs? { anim = BOTH_PAIN1; } else // On three legs { anim = BOTH_PAIN2; } NPC_SetAnim( self, SETANIM_BOTH, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); // Spin around in pain self->NPC->localState = LSTATE_SPINNING; TIMER_Set( self, "roam", Q_irand(1000,2000)); } } } else if ( self->client->NPC_class == CLASS_INTERROGATOR && ( mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT ) && other ) { vec3_t dir; VectorSubtract( self->r.currentOrigin, other->r.currentOrigin, dir ); VectorNormalize( dir ); VectorMA( self->client->ps.velocity, 550, dir, self->client->ps.velocity ); self->client->ps.velocity[2] -= 127; } NPC_Pain( self, attacker, damage); }
void NPC_GalakMech_Init( gentity_t *ent ) { if (ent->NPC->behaviorState != BS_CINEMATIC) { ent->client->ps.stats[STAT_ARMOR] = GALAK_SHIELD_HEALTH; ent->NPC->investigateCount = ent->NPC->investigateDebounceTime = 0; ent->flags |= FL_SHIELDED;//reflect normal shots //rwwFIXMEFIXME: Support PW_GALAK_SHIELD //ent->client->ps.powerups[PW_GALAK_SHIELD] = Q3_INFINITE;//temp, for effect //ent->fx_time = level.time; VectorSet( ent->r.mins, -60, -60, -24 ); VectorSet( ent->r.maxs, 60, 60, 80 ); ent->flags |= FL_NO_KNOCKBACK;//don't get pushed TIMER_Set( ent, "attackDelay", 0 ); //FIXME: Slant for difficulty levels TIMER_Set( ent, "flee", 0 ); TIMER_Set( ent, "smackTime", 0 ); TIMER_Set( ent, "beamDelay", 0 ); TIMER_Set( ent, "noLob", 0 ); TIMER_Set( ent, "noRapid", 0 ); TIMER_Set( ent, "talkDebounce", 0 ); NPC_SetSurfaceOnOff( ent, "torso_shield", TURN_ON ); NPC_SetSurfaceOnOff( ent, "torso_galakface", TURN_OFF ); NPC_SetSurfaceOnOff( ent, "torso_galakhead", TURN_OFF ); NPC_SetSurfaceOnOff( ent, "torso_eyes_mouth", TURN_OFF ); NPC_SetSurfaceOnOff( ent, "torso_collar", TURN_OFF ); NPC_SetSurfaceOnOff( ent, "torso_galaktorso", TURN_OFF ); } else { // NPC_SetSurfaceOnOff( ent, "helmet", TURN_OFF ); NPC_SetSurfaceOnOff( ent, "torso_shield", TURN_OFF ); NPC_SetSurfaceOnOff( ent, "torso_galakface", TURN_ON ); NPC_SetSurfaceOnOff( ent, "torso_galakhead", TURN_ON ); NPC_SetSurfaceOnOff( ent, "torso_eyes_mouth", TURN_ON ); NPC_SetSurfaceOnOff( ent, "torso_collar", TURN_ON ); NPC_SetSurfaceOnOff( ent, "torso_galaktorso", TURN_ON ); } }
void GM_Dying( gentity_t *self ) { if ( level.time - self->s.time < 4000 ) {//FIXME: need a real effect //self->s.powerups |= ( 1 << PW_SHOCKED ); //self->client->ps.powerups[PW_SHOCKED] = level.time + 1000; self->client->ps.electrifyTime = level.time + 1000; if ( TIMER_Done( self, "dyingExplosion" ) ) { int newBolt; switch ( Q_irand( 1, 14 ) ) { // Find place to generate explosion case 1: if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_hand" )) {//r_hand still there GM_CreateExplosion( self, trap->G2API_AddBolt(self->ghoul2, 0, "*flasha"), qtrue ); NPC_SetSurfaceOnOff( self, "r_hand", TURN_OFF ); } else if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm_middle" )) {//r_arm_middle still there newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*r_arm_elbow" ); NPC_SetSurfaceOnOff( self, "r_arm_middle", TURN_OFF ); } break; case 2: //FIXME: do only once? if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_hand" )) {//l_hand still there GM_CreateExplosion( self, trap->G2API_AddBolt(self->ghoul2, 0, "*flashc"), qfalse ); NPC_SetSurfaceOnOff( self, "l_hand", TURN_OFF ); } else if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_wrist" )) {//l_arm_wrist still there newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*l_arm_cap_l_hand" ); NPC_SetSurfaceOnOff( self, "l_arm_wrist", TURN_OFF ); } else if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_middle" )) {//l_arm_middle still there newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*l_arm_cap_l_hand" ); NPC_SetSurfaceOnOff( self, "l_arm_middle", TURN_OFF ); } else if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_augment" )) {//l_arm_augment still there newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*l_arm_elbow" ); NPC_SetSurfaceOnOff( self, "l_arm_augment", TURN_OFF ); } break; case 3: case 4: newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*hip_fr" ); GM_CreateExplosion( self, newBolt, qfalse ); break; case 5: case 6: newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*shldr_l" ); GM_CreateExplosion( self, newBolt, qfalse ); break; case 7: case 8: newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*uchest_r" ); GM_CreateExplosion( self, newBolt, qfalse ); break; case 9: case 10: GM_CreateExplosion( self, self->client->renderInfo.headBolt, qfalse ); break; case 11: newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*l_leg_knee" ); GM_CreateExplosion( self, newBolt, qtrue ); break; case 12: newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*r_leg_knee" ); GM_CreateExplosion( self, newBolt, qtrue ); break; case 13: newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*l_leg_foot" ); GM_CreateExplosion( self, newBolt, qtrue ); break; case 14: newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*r_leg_foot" ); GM_CreateExplosion( self, newBolt, qtrue ); break; } TIMER_Set( self, "dyingExplosion", Q_irand( 300, 1100 ) ); } } else {//one final, huge explosion G_PlayEffectID( G_EffectIndex("galak/explode"), self->r.currentOrigin, vec3_origin ); // G_PlayEffect( "small_chunks", self->r.currentOrigin ); // G_PlayEffect( "env/exp_trail_comp", self->r.currentOrigin, self->currentAngles ); self->nextthink = level.time + FRAMETIME; self->think = G_FreeEntity; } }
void NPC_BSGM_Default( void ) { if( NPCS.NPCInfo->scriptFlags & SCF_FIRE_WEAPON ) { WeaponThink( qtrue ); } if ( NPCS.NPC->client->ps.stats[STAT_ARMOR] <= 0 ) {//armor gone // if ( !NPCInfo->investigateDebounceTime ) if (0) {//start regenerating the armor NPC_SetSurfaceOnOff( NPCS.NPC, "torso_shield", TURN_OFF ); NPCS.NPC->flags &= ~FL_SHIELDED;//no more reflections VectorSet( NPCS.NPC->r.mins, -20, -20, -24 ); VectorSet( NPCS.NPC->r.maxs, 20, 20, 64 ); NPCS.NPC->client->ps.crouchheight = NPCS.NPC->client->ps.standheight = 64; if ( NPCS.NPC->locationDamage[HL_GENERIC1] < GENERATOR_HEALTH ) {//still have the generator bolt-on if ( NPCS.NPCInfo->investigateCount < 12 ) { NPCS.NPCInfo->investigateCount++; } NPCS.NPCInfo->investigateDebounceTime = level.time + (NPCS.NPCInfo->investigateCount * 5000); } } else if ( NPCS.NPCInfo->investigateDebounceTime < level.time ) {//armor regenerated, turn shield back on //do a trace and make sure we can turn this back on? trace_t tr; trap->Trace( &tr, NPCS.NPC->r.currentOrigin, shieldMins, shieldMaxs, NPCS.NPC->r.currentOrigin, NPCS.NPC->s.number, NPCS.NPC->clipmask, qfalse, 0, 0 ); if ( !tr.startsolid ) { VectorCopy( shieldMins, NPCS.NPC->r.mins ); VectorCopy( shieldMaxs, NPCS.NPC->r.maxs ); NPCS.NPC->client->ps.crouchheight = NPCS.NPC->client->ps.standheight = shieldMaxs[2]; NPCS.NPC->client->ps.stats[STAT_ARMOR] = GALAK_SHIELD_HEALTH; NPCS.NPCInfo->investigateDebounceTime = 0; NPCS.NPC->flags |= FL_SHIELDED;//reflect normal shots // NPC->fx_time = level.time; NPC_SetSurfaceOnOff( NPCS.NPC, "torso_shield", TURN_ON ); } } } /* if ( NPC->client->ps.stats[STAT_ARMOR] > 0 ) {//armor present NPC->client->ps.powerups[PW_GALAK_SHIELD] = Q3_INFINITE;//temp, for effect NPC_SetSurfaceOnOff( NPC, "torso_shield", TURN_ON ); } else { NPC_SetSurfaceOnOff( NPC, "torso_shield", TURN_OFF ); } */ //rwwFIXMEFIXME: Allow this stuff, and again, going to have to let the client know about it. //Maybe a surface-off bitflag of some sort in the entity state? if( !NPCS.NPC->enemy ) {//don't have an enemy, look for one NPC_BSGM_Patrol(); } else //if ( NPC->enemy ) {//have an enemy NPC_BSGM_Attack(); } }
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 ) if (other && other->client && other->s.number < MAX_CLIENTS) {//player touched me //[CoOp] char *text; qboolean keyTaken; int sendnum = -1; // ensiform - added this //give him my key if ( Q_stricmp( "goodie", self->message ) == 0 ) {//a goodie key if ( (keyTaken = INV_GoodieKeyGive( other )) == qtrue ) { // ensiform TODO - Add name of 'other' (who picked up key) text = va("cp \"%s^7 %s\n\"", other->client->pers.netname, G_GetStringEdString("SP_INGAME", "TOOK_IMPERIAL_GOODIE_KEY2")); text = va("cp \"%s\n\"", G_GetStringEdString("SP_INGAME", "TOOK_IMPERIAL_GOODIE_KEY")); //text = "cp @SP_INGAME_TOOK_IMPERIAL_GOODIE_KEY"; //G_AddEvent( other, EV_ITEM_PICKUP, (FindItemForInventory( INV_GOODIE_KEY )-bg_itemlist) ); } else { sendnum = other->s.number; text = va("cp \"%s\n\"", G_GetStringEdString("SP_INGAME", "CANT_CARRY_GOODIE_KEY")); //text = "cp @SP_INGAME_CANT_CARRY_GOODIE_KEY"; } } else {//a named security key if ( (keyTaken = INV_SecurityKeyGive( other, self->message )) == qtrue ) { // ensiform TODO - Add name of 'other' (who picked up key) text = va("cp \"%s^7 %s\n\"", other->client->pers.netname, G_GetStringEdString("SP_INGAME", "TOOK_IMPERIAL_SECURITY_KEY2")); text = va("cp \"%s\n\"", G_GetStringEdString("SP_INGAME", "TOOK_IMPERIAL_SECURITY_KEY")); //text = "cp @SP_INGAME_TOOK_IMPERIAL_SECURITY_KEY"; //G_AddEvent( other, EV_ITEM_PICKUP, (FindItemForInventory( INV_SECURITY_KEY )-bg_itemlist) ); } else { sendnum = other->s.number; text = va("cp \"%s\n\"", G_GetStringEdString("SP_INGAME", "CANT_CARRY_SECURITY_KEY")); //text = "cp @SP_INGAME_CANT_CARRY_SECURITY_KEY"; } } if ( keyTaken ) {//remove my key NPC_SetSurfaceOnOff( self, "l_arm_key", TURN_OFF ); //NPC_SetSurfaceOnOff( self, "l_arm_key", 0x00000002 ); self->message = NULL; //FIXME: temp pickup sound G_Sound( other, CHAN_AUTO, G_SoundIndex( "sound/weapons/key_pkup.wav" ) ); //FIXME: need some event to pass to cgame for sound/graphic/message? } //FIXME: temp message trap_SendServerCommand( sendnum, text ); //trap_SendServerCommand( -1, text ); //[/CoOp] } } 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; } //[CoOp] //reenabling the IGNORE_ENEMIES flag if( /*!(self->svFlags&SVF_LOCKEDENEMY) && */!(self->NPC->scriptFlags&SCF_IGNORE_ENEMIES) && !(other->flags & FL_NOTARGET) ) //if( /*!(self->svFlags&SVF_LOCKEDENEMY) && !(self->svFlags&SVF_IGNORE_ENEMIES) &&*/ !(other->flags & FL_NOTARGET) ) //[/CoOp] { 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) ) if (0) //rwwFIXMEFIXME: Can probably just check if num < MAX_CLIENTS for non-npc enemy stuff { NPCInfo->touchedByPlayer = other; } } if ( other == NPCInfo->goalEntity ) { NPCInfo->aiFlags |= NPCAI_TOUCHED_GOAL; } } RestoreNPCGlobals(); npc_push(self,other,trace); }