Esempio n. 1
0
void NPCF_Add( gentity_t *self, gentity_t *ent )
{
	if ( !ent || !self )
	{
		return;
	}

	if ( !ent->client || !self->client )
	{
		return;
	}

	if ( self->client->numPlFollowers >= NPCF_MaxFollowers() )
	{
		trap_SendServerCommand( self->client->ps.clientNum, va("print \"No more than %d followers...\n\"", g_NPCmaxFollowers.integer) );
		G_EntitySound( self, CHAN_VOICE, G_SoundIndex("*nomore.wav") );
		TIMER_Set( ent, "followUse", 1750 );
		return;
	}

	if ( ent->client->playerTeam == NPCTEAM_NEUTRAL )
	{
		ent->NPC->keepTeam = 1|(ent->client->enemyTeam<<4);

		ent->client->playerTeam = ent->alliedTeam = ent->s.teamowner = self->client->playerTeam;
		ent->client->enemyTeam = self->client->enemyTeam;
	}
	else
	{
		ent->NPC->keepTeam = 0;
	}

	self->client->plFollower[self->client->numPlFollowers] = ent;
	self->client->numPlFollowers++;

	ent->NPC->defaultBehavior = BS_FOLLOW_LEADER;
	ent->client->leader = self;
	ent->client->playerLeader = self;

	ent->NPC->behaviorState = BS_FOLLOW_LEADER;
	ent->NPC->defendEnt = self;
	ent->NPC->eventualGoal = self;

	NPC_RestoreStats( ent );

	//NPC_Respond( ent, self->s.number );

	TIMER_Set( ent, "dynamicBehavior", 10000 );
}
Esempio n. 2
0
void StopGrip(gentity_t*self)
{
	int wasActive = self->client->ps.fd.forcePowersActive;

	self->client->ps.fd.forceGripUseTime = level.time + 3000;
	if (self->client->ps.fd.forcePowerLevel[FP_GRIP] > FORCE_LEVEL_1 &&
		g_entities[self->client->ps.fd.forceGripEntityNum].client &&
		g_entities[self->client->ps.fd.forceGripEntityNum].health > 0 &&
		g_entities[self->client->ps.fd.forceGripEntityNum].inuse &&
		(level.time - g_entities[self->client->ps.fd.forceGripEntityNum].client->ps.fd.forceGripStarted) > 500)
	{ //if we had our throat crushed in for more than half a second, gasp for air when we're let go
		if (wasActive & (1 << FP_GRIP))
		{
			G_EntitySound( &g_entities[self->client->ps.fd.forceGripEntityNum], CHAN_VOICE, G_SoundIndex("*gasp.wav") );
		}
	}

	if (g_entities[self->client->ps.fd.forceGripEntityNum].client &&
		g_entities[self->client->ps.fd.forceGripEntityNum].inuse)
	{
		g_entities[self->client->ps.fd.forceGripEntityNum].client->ps.forceGripChangeMovetype = PM_NORMAL;
		//[ForceSys]
		g_entities[self->client->ps.fd.forceGripEntityNum].client->ps.fd.forceGripCripple = 0;
		//[/ForceSys]
		g_entities[self->client->ps.fd.forceGripEntityNum].client->forceAttacker = ENTITYNUM_NONE;
	}

	if (self->client->ps.forceHandExtend == HANDEXTEND_FORCE_HOLD)
	{
		self->client->ps.forceHandExtendTime = 0;
	}

	self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE;

	self->client->ps.powerups[PW_DISINT_4] = 0;
}
Esempio n. 3
0
void DoGripAction(gentity_t *self, forcePowers_t forcePower)
{//racc - have someone in our grip, deal with them.
	gentity_t *gripEnt;
	int gripLevel = 0;
	trace_t tr;
	vec3_t a;

	self->client->dangerTime = level.time;
	self->client->ps.eFlags &= ~EF_INVULNERABLE;
	self->client->invulnerableTimer = 0;

	gripEnt = &g_entities[self->client->ps.fd.forceGripEntityNum];

	if (!ValidGripEnt(self,gripEnt))
	{
		WP_ForcePowerStop(self,FP_GRIP);
		self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE;

		if (gripEnt && gripEnt->client && gripEnt->inuse)
		{
			gripEnt->client->ps.forceGripChangeMovetype = PM_NORMAL;
		}
		return;
	}

	if(gripEnt->client)
		VectorSubtract(gripEnt->client->ps.origin, self->client->ps.origin, a);
	else
		VectorSubtract(gripEnt->s.pos.trBase,self->client->ps.origin,a);

	if(gripEnt->client)
		trap_Trace(&tr, self->client->ps.origin, NULL, NULL, gripEnt->client->ps.origin, self->s.number, MASK_PLAYERSOLID);
	else
		trap_Trace(&tr, self->client->ps.origin, NULL, NULL, gripEnt->s.pos.trBase, self->s.number, MASK_PLAYERSOLID);

	//[ForceSys]
	gripLevel = self->client->ps.fd.forcePowerLevel[FP_GRIP];

	if (VectorLength(a) > MAX_GRIP_DISTANCE)
	{
		WP_ForcePowerStop(self, forcePower);
		return;
	}

	if(gripEnt->client)
	{
		if ( !InFront( gripEnt->client->ps.origin, self->client->ps.origin, self->client->ps.viewangles, 0.9f ) &&
			gripLevel < FORCE_LEVEL_3)
		{
			WP_ForcePowerStop(self, forcePower);
			return;
		}
	}
	else
	{
		if ( !InFront( gripEnt->s.pos.trBase, self->client->ps.origin, self->client->ps.viewangles, 0.9f ) &&
			gripLevel < FORCE_LEVEL_3)
		{
			WP_ForcePowerStop(self, forcePower);
			return;
		}
	}

	if (self->client->ps.fd.forcePowerDebounce[FP_GRIP] < level.time)
	{ //2 damage per second while choking, resulting in 10 damage total (not including The Squeeze<tm>)
		self->client->ps.fd.forcePowerDebounce[FP_GRIP] = level.time + 1000;
		G_Damage(gripEnt, self, self, NULL, NULL, 2, DAMAGE_NO_ARMOR, MOD_FORCE_DARK);
	}

	Jetpack_Off(gripEnt); //make sure the guy being gripped has his jetpack off.

	if (gripLevel == FORCE_LEVEL_1)
	{
		if(gripEnt->client)
			gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000;
		
		if(gripEnt->client)
			if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 5000)
			{
				WP_ForcePowerStop(self, forcePower);
				return;
			}
	}

	if (gripLevel == FORCE_LEVEL_2||gripLevel==FORCE_LEVEL_3)
	{
		gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000;

		if (gripEnt->client->ps.forceGripMoveInterval < level.time)
		{
			if(gripLevel == FORCE_LEVEL_2)
				gripEnt->client->ps.velocity[2] = 15;
			else
				gripEnt->client->ps.velocity[2] = 30;

			gripEnt->client->ps.forceGripMoveInterval = level.time + 300; //only update velocity every 300ms, so as to avoid heavy bandwidth usage
		}
		gripEnt->client->ps.otherKiller = self->s.number;
		gripEnt->client->ps.otherKillerTime = level.time + 5000;
		gripEnt->client->ps.otherKillerDebounceTime = level.time + 100;
		//[Asteroids]
		gripEnt->client->otherKillerMOD = MOD_UNKNOWN;
		gripEnt->client->otherKillerVehWeapon = 0;
		gripEnt->client->otherKillerWeaponType = WP_NONE;
		//[/Asteroids]

		gripEnt->client->ps.forceGripChangeMovetype = PM_FLOAT;

		if(gripEnt->client)
		{
			if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 3000 && !self->client->ps.fd.forceGripDamageDebounceTime)
			{ //if we managed to lift him into the air for 2 seconds, give him a crack
				self->client->ps.fd.forceGripDamageDebounceTime = 1;
				if(gripLevel == FORCE_LEVEL_2)
					G_Damage(gripEnt, self, self, NULL, NULL, 20, DAMAGE_NO_ARMOR, MOD_FORCE_DARK);
				else
					G_Damage(gripEnt, self, self, NULL, NULL, 75, DAMAGE_NO_ARMOR, MOD_FORCE_DARK);
				//Must play custom sounds on the actual entity. Don't use G_Sound (it creates a temp entity for the sound)
				G_EntitySound( gripEnt, CHAN_VOICE, G_SoundIndex(va( "*choke%d.wav", Q_irand( 1, 3 ) )) );

				gripEnt->client->ps.forceHandExtend = HANDEXTEND_CHOKE;
				gripEnt->client->ps.forceHandExtendTime = level.time + 2000;

				if (gripEnt->client->ps.fd.forcePowersActive & (1 << FP_GRIP))
				{ //choking, so don't let him keep gripping himself
					WP_ForcePowerStop(gripEnt, FP_GRIP);
					return;
				}
			}
			else if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 4000)
			{
				WP_ForcePowerStop(self, forcePower);
				return;
			}
		}
	}
}
Esempio n. 4
0
void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {
	int		dflags;

	if ( self->flags & FL_INACTIVE )
	{//set by target_deactivate
		return;
	}

	if ( !other->takedamage ) {
		return;
	}

	if ( self->timestamp > level.time ) {
		return;
	}

	if (self->damage == -1 && other && other->client && other->health < 1)
	{
		other->client->ps.fallingToDeath = 0;
		respawn(other);
		return;
	}

	if (self->damage == -1 && other && other->client && other->client->ps.fallingToDeath)
	{
		return;
	}

	if ( self->spawnflags & 16 ) {
		self->timestamp = level.time + 1000;
	} else {
		self->timestamp = level.time + FRAMETIME;
	}

	// play sound
	/*
	if ( !(self->spawnflags & 4) && self->damage != -1 ) {
		G_Sound( other, CHAN_AUTO, self->noise_index );
	}
	*/

	if (self->spawnflags & 8)
		dflags = DAMAGE_NO_PROTECTION;
	else
		dflags = 0;

	if (self->damage == -1 && other && other->client)
	{
		if (other->client->ps.otherKillerTime > level.time)
		{ //we're as good as dead, so if someone pushed us into this then remember them
			other->client->ps.otherKillerTime = level.time + 20000;
			other->client->ps.otherKillerDebounceTime = level.time + 10000;
		}
		other->client->ps.fallingToDeath = level.time;

		//rag on the way down, this flag will automatically be cleared for us on respawn
		other->client->ps.eFlags |= EF_RAG;

		//make sure his jetpack is off
		Jetpack_Off(other);

		if (other->NPC)
		{ //kill it now
			vec3_t vDir;

			VectorSet(vDir, 0, 1, 0);
			G_Damage(other, other, other, vDir, other->client->ps.origin, Q3_INFINITE, 0, MOD_FALLING);
		}
		else
		{
			G_EntitySound(other, CHAN_VOICE, G_SoundIndex("*falling1.wav"));
		}

		self->timestamp = 0; //do not ignore others
	}
	else	
	{
		int dmg = self->damage;

		if (dmg == -1)
		{ //so fall-to-blackness triggers destroy evertyhing
			dmg = 99999;
			self->timestamp = 0;
		}
		if (self->activator && self->activator->inuse && self->activator->client)
		{
			G_Damage (other, self->activator, self->activator, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT);
		}
		else
		{
			G_Damage (other, self, self, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT);
		}
	}
}
Esempio n. 5
0
void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {
	int		dflags;

	if ( !other->takedamage ) {
		return;
	}

	if ( self->timestamp > level.time ) {
		return;
	}

	if (self->damage == -1 && other && other->client && other->health < 1)
	{
		other->client->ps.fallingToDeath = 0;
		respawn(other);
		return;
	}

	if (self->damage == -1 && other && other->client && other->client->ps.fallingToDeath)
	{
		return;
	}

	if ( self->spawnflags & 16 ) {
		self->timestamp = level.time + 1000;
	} else {
		self->timestamp = level.time + FRAMETIME;
	}

	// play sound
	if ( !(self->spawnflags & 4) && self->damage != -1 ) {
		G_Sound( other, CHAN_AUTO, self->noise_index );
	}

	if (self->spawnflags & 8)
		dflags = DAMAGE_NO_PROTECTION;
	else
		dflags = 0;

	if (self->damage == -1 && other && other->client)
	{
		if (other->client->ps.otherKillerTime > level.time)
		{ //we're as good as dead, so if someone pushed us into this then remember them
			other->client->ps.otherKillerTime = level.time + 20000;
			other->client->ps.otherKillerDebounceTime = level.time + 10000;
		}
		other->client->ps.fallingToDeath = level.time;

		self->timestamp = 0; //do not ignore others
		G_EntitySound(other, CHAN_VOICE, G_SoundIndex("*falling1.wav"));
	}
	else	
	{
		int dmg = self->damage;

		if (dmg == -1)
		{ //so fall-to-blackness triggers destroy evertyhing
			dmg = 99999;
			self->timestamp = 0;
		}
		if (self->activator && self->activator->inuse && self->activator->client)
		{
			G_Damage (other, self->activator, self->activator, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT);
		}
		else
		{
			G_Damage (other, self, self, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT);
		}
	}
}
Esempio n. 6
0
void JKG_GrappleUpdate( gentity_t *self )
{
	gentity_t *grappler = &g_entities[self->client->grappleIndex];

	if (!grappler->inuse || !grappler->client || grappler->client->grappleIndex != self->s.number ||
		!BG_InGrappleMove(grappler->client->ps.torsoAnim) || !BG_InGrappleMove(grappler->client->ps.legsAnim) ||
		!BG_InGrappleMove(self->client->ps.torsoAnim) || !BG_InGrappleMove(self->client->ps.legsAnim) ||
		!self->client->grappleState || !grappler->client->grappleState ||
		grappler->health < 1 || self->health < 1 ||
		!G_PrettyCloseIGuess(self->client->ps.origin[2], grappler->client->ps.origin[2], 4.0f))
	{
		self->client->grappleState = 0;
		if ((BG_InGrappleMove(self->client->ps.torsoAnim) && self->client->ps.torsoTimer > 100) ||
			(BG_InGrappleMove(self->client->ps.legsAnim) && self->client->ps.legsTimer > 100))
		{ //if they're pretty far from finishing the anim then shove them into another anim
			G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_KYLE_MISS, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
			if (self->client->ps.torsoAnim == BOTH_KYLE_MISS)
			{ //providing the anim set succeeded..
				self->client->ps.weaponTime = self->client->ps.torsoTimer;
			}
		}
	}
	else
	{
		vec3_t grapAng;

		VectorSubtract(grappler->client->ps.origin, self->client->ps.origin, grapAng);

		if (VectorLength(grapAng) > 64.0f)
		{ //too far away, break it off
			if ((BG_InGrappleMove(self->client->ps.torsoAnim) && self->client->ps.torsoTimer > 100) ||
				(BG_InGrappleMove(self->client->ps.legsAnim) && self->client->ps.legsTimer > 100))
			{
				self->client->grappleState = 0;

				G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_KYLE_MISS, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
				if (self->client->ps.torsoAnim == BOTH_KYLE_MISS)
				{ //providing the anim set succeeded..
					self->client->ps.weaponTime = self->client->ps.torsoTimer;
				}
			}
		}
		else
		{
			vectoangles(grapAng, grapAng);
			SetClientViewAngle(self, grapAng);

			if (self->client->grappleState >= 20)
			{ //grapplee
				//try to position myself at the correct distance from my grappler
				float idealDist;
				vec3_t gFwd, idealSpot;
				trace_t trace;

				if (grappler->client->ps.torsoAnim == BOTH_KYLE_PA_1)
				{ //grab punch
					idealDist = 46.0f;
				}
				else
				{ //knee-throw
					idealDist = 34.0f;
				}

				AngleVectors(grappler->client->ps.viewangles, gFwd, 0, 0);
				VectorMA(grappler->client->ps.origin, idealDist, gFwd, idealSpot);

				trap_Trace(&trace, self->client->ps.origin, self->r.mins, self->r.maxs, idealSpot, self->s.number, self->clipmask);
				if (!trace.startsolid && !trace.allsolid && trace.fraction == 1.0f)
				{ //go there
					G_SetOrigin(self, idealSpot);
					VectorCopy(idealSpot, self->client->ps.origin);
				}
			}
			else if (self->client->grappleState >= 1)
			{ //grappler
				if (grappler->client->ps.weapon == WP_SABER)
				{ //make sure their saber is shut off
					if (!grappler->client->ps.saberHolstered)
					{
						grappler->client->ps.saberHolstered = 2;
						if (grappler->client->saber[0].soundOff)
						{
							G_Sound(grappler, CHAN_AUTO, grappler->client->saber[0].soundOff);
						}
						if (grappler->client->saber[1].soundOff &&
							grappler->client->saber[1].model[0])
						{
							G_Sound(grappler, CHAN_AUTO, grappler->client->saber[1].soundOff);
						}
					}
				}

				//check for smashy events
				if (self->client->ps.torsoAnim == BOTH_KYLE_PA_1)
				{ //grab punch
                    if (self->client->grappleState == 1)
					{ //smack
						if (self->client->ps.torsoTimer < 3400)
						{
							int grapplerAnim = grappler->client->ps.torsoAnim;
							int grapplerTime = grappler->client->ps.torsoTimer;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 10, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoAnim = grapplerAnim;
								grappler->client->ps.torsoTimer = grapplerTime;
								grappler->client->ps.legsAnim = grapplerAnim;
								grappler->client->ps.legsTimer = grapplerTime;
								grappler->client->ps.weaponTime = grapplerTime;
							}
							self->client->grappleState++;
						}
					}
					else if (self->client->grappleState == 2)
					{ //smack!
						if (self->client->ps.torsoTimer < 2550)
						{
							int grapplerAnim = grappler->client->ps.torsoAnim;
							int grapplerTime = grappler->client->ps.torsoTimer;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 10, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoAnim = grapplerAnim;
								grappler->client->ps.torsoTimer = grapplerTime;
								grappler->client->ps.legsAnim = grapplerAnim;
								grappler->client->ps.legsTimer = grapplerTime;
								grappler->client->ps.weaponTime = grapplerTime;
							}
							self->client->grappleState++;
						}
					}
					else
					{ //SMACK!
						if (self->client->ps.torsoTimer < 1300)
						{
							vec3_t tossDir;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 30, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							self->client->grappleState = 0;

							VectorSubtract(grappler->client->ps.origin, self->client->ps.origin, tossDir);
							VectorNormalize(tossDir);
							VectorScale(tossDir, 500.0f, tossDir);
							tossDir[2] = 200.0f;

							VectorAdd(grappler->client->ps.velocity, tossDir, grappler->client->ps.velocity);

							if (grappler->health > 0)
							{ //if still alive knock them down
								grappler->client->ps.forceHandExtend = HANDEXTEND_KNOCKDOWN;
								grappler->client->ps.forceHandExtendTime = level.time + 1300;
							}
						}
					}
				}
				else if (self->client->ps.torsoAnim == BOTH_KYLE_PA_2)
				{ //knee throw
                    if (self->client->grappleState == 1)
					{ //knee to the face
						if (self->client->ps.torsoTimer < 3200)
						{
							int grapplerAnim = grappler->client->ps.torsoAnim;
							int grapplerTime = grappler->client->ps.torsoTimer;

							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 20, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoAnim = grapplerAnim;
								grappler->client->ps.torsoTimer = grapplerTime;
								grappler->client->ps.legsAnim = grapplerAnim;
								grappler->client->ps.legsTimer = grapplerTime;
								grappler->client->ps.weaponTime = grapplerTime;
							}
							self->client->grappleState++;
						}
					}
					else if (self->client->grappleState == 2)
					{ //smashed on the ground
						if (self->client->ps.torsoTimer < 2000)
						{
							//G_Damage(grappler, self, self, NULL, self->client->ps.origin, 10, 0, MOD_MELEE);
							//don't do damage on this one, it would look very freaky if they died
							G_EntitySound( grappler, CHAN_VOICE, G_SoundIndex("*pain100.wav") );
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );
							self->client->grappleState++;
						}
					}
					else
					{ //and another smash
						if (self->client->ps.torsoTimer < 1000)
						{
							G_Damage(grappler, self, self, NULL, self->client->ps.origin, 30, 0, MOD_MELEE);
							//G_Sound( grappler, CHAN_AUTO, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) );

							//it might try to put them into a pain anim or something, so override it back again
							if (grappler->health > 0)
							{
								grappler->client->ps.torsoTimer = 1000;
								//G_SetAnim(grappler, &grappler->client->pers.cmd, SETANIM_BOTH, BOTH_GETUP3, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
								grappler->client->grappleState = 0;
							}
							else
							{ //override death anim
								grappler->client->ps.torsoAnim = BOTH_DEADFLOP1;
								grappler->client->ps.legsAnim = BOTH_DEADFLOP1;
							}

							self->client->grappleState = 0;
						}
					}
				}
				else
				{ //?
				}
			}
		}
	}
}