Jump to content

Home

Friendly Saber on NPCs


AlphaleX

Recommended Posts

the g_friendlySaber cvar is just for clients, it don't work for npcs

i tried looking for both friendlysaber and friendlyfire and i found other things

 

the closest thing i found is this: (on NPC_reactions.c)

 

===============
NPC_Pain
===============
*/
void NPC_Pain(gentity_t *self, gentity_t *attacker, int damage)
{
team_t otherTeam = TEAM_FREE;
int		voiceEvent = -1;
gentity_t *other = attacker;
int mod = gPainMOD;
int hitLoc = gPainHitLoc;
vec3_t point;

VectorCopy(gPainPoint, point);

if ( self->NPC == NULL ) 
	return;

if ( other == NULL ) 
	return;

//or just remove ->pain in player_die?
if ( self->client->ps.pm_type == PM_DEAD )
	return;

if ( other == self ) 
	return;

//MCG: Ignore damage from your own team for now
if ( other->client )
{
	otherTeam = other->client->playerTeam;
//	if ( otherTeam == TEAM_DISGUISE )
//	{
//		otherTeam = TEAM_PLAYER;
//	}
}

if ( self->client->playerTeam 
	&& other->client 
	&& otherTeam == self->client->playerTeam 
/*	&& (!player->client->ps.viewEntity || other->s.number != player->client->ps.viewEntity)*/) 
//rwwFIXMEFIXME: Will need modification when player controllable npcs are done
{//hit by a teammate
	if ( other != self->enemy && self != other->enemy )
	{//we weren't already enemies
		if ( self->enemy || other->enemy 

			//|| (other->s.number&&other->s.number!=player->client->ps.viewEntity) 
			//rwwFIXMEFIXME: same

			/*|| (!other->s.number&&Q_irand( 0, 3 ))*/ )
		{//if one of us actually has an enemy already, it's okay, just an accident OR wasn't hit by player or someone controlled by player OR player hit ally and didn't get 25% chance of getting mad (FIXME:accumulate anger+base on diff?)
			//FIXME: player should have to do a certain amount of damage to ally or hit them several times to make them mad
			//Still run pain and flee scripts
			if ( self->client && self->NPC )
			{//Run any pain instructions
				if ( self->health <= (self->client->ps.stats[sTAT_MAX_HEALTH]/3) && G_ActivateBehavior(self, BSET_FLEE) )
				{

				}
				else// if( VALIDSTRING( self->behaviorSet[bSET_PAIN] ) )
				{
					G_ActivateBehavior(self, BSET_PAIN);
				}
			}
			if ( damage != -1 )
			{//-1 == don't play pain anim
				//Set our proper pain animation
				if ( Q_irand( 0, 1 ) )
				{
					NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, EV_FFWARN );
				}
				else
				{
					NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, -1 );
				}
			}
			return;
		}
		else if ( self->NPC && !other->s.number )//should be assumed, but...
		{//dammit, stop that!
			if ( self->NPC->charmedTime )
			{//mindtricked
				return;
			}
			else if ( self->NPC->ffireCount < 3+((2-g_spskill.integer)*2) )
			{//not mad enough yet
				//Com_Printf( "chck: %d < %d\n", self->NPC->ffireCount, 3+((2-g_spskill.integer)*2) );
				if ( damage != -1 )
				{//-1 == don't play pain anim
					//Set our proper pain animation
					if ( Q_irand( 0, 1 ) )
					{
						NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, EV_FFWARN );
					}
					else
					{
						NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, -1 );
					}
				}
				return;
			}
			else if ( G_ActivateBehavior( self, BSET_FFIRE ) )
			{//we have a specific script to run, so do that instead
				return;
			}
			else
			{//okay, we're going to turn on our ally, we need to set and lock our enemy and put ourselves in a bstate that lets us attack him (and clear any flags that would stop us)
				self->NPC->blockedSpeechDebounceTime = 0;
				voiceEvent = EV_FFTURN;
				self->NPC->behaviorState = self->NPC->tempBehavior = self->NPC->defaultBehavior = BS_DEFAULT;
				other->flags &= ~FL_NOTARGET;
				//self->svFlags &= ~(SVF_IGNORE_ENEMIES|SVF_ICARUS_FREEZE|SVF_NO_COMBAT_SOUNDS);
				self->r.svFlags &= ~SVF_ICARUS_FREEZE;
				G_SetEnemy( self, other );
				//self->svFlags |= SVF_LOCKEDENEMY; //rwwFIXMEFIXME: proper support for these flags.
				self->NPC->scriptFlags &= ~(SCF_DONT_FIRE|SCF_CROUCHED|SCF_WALKING|SCF_NO_COMBAT_TALK|SCF_FORCED_MARCH);
				self->NPC->scriptFlags |= (SCF_CHASE_ENEMIES|SCF_NO_MIND_TRICK);
				//NOTE: we also stop ICARUS altogether
				//stop_icarus = qtrue;
				//rwwFIXMEFIXME: stop icarus?
				if ( !killPlayerTimer )
				{
					killPlayerTimer = level.time + 10000;
				}
			}
		}
	}
}

SaveNPCGlobals();
SetNPCGlobals( self );

//Do extra bits
if ( NPCInfo->ignorePain == qfalse )
{
	NPCInfo->confusionTime = 0;//clear any charm or confusion, regardless
	if ( damage != -1 )
	{//-1 == don't play pain anim
		//Set our proper pain animation
		NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, voiceEvent );
	}
	//Check to take a new enemy
	if ( NPC->enemy != other && NPC != other )
	{//not already mad at them
		NPC_CheckAttacker( other, mod );
	}
}

//Attempt to run any pain instructions
if ( self->client && self->NPC )
{
	//FIXME: This needs better heuristics perhaps
	if(self->health <= (self->client->ps.stats[sTAT_MAX_HEALTH]/3) && G_ActivateBehavior(self, BSET_FLEE) )
	{
	}
	else //if( VALIDSTRING( self->behaviorSet[bSET_PAIN] ) )
	{
		G_ActivateBehavior(self, BSET_PAIN);
	}
}

//Attempt to fire any paintargets we might have
if( self->paintarget && self->paintarget[0] )
{
	G_UseTargets2(self, other, self->paintarget);
}

RestoreNPCGlobals();
}

/*

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...