示例#1
0
void
TourneyTimeEvent (TOURNEYTIME ttime, int attime)
{
  int i;

  for (i = 0; i < t_eventcount; i++)
    {
      if (t_eventlist[i].ttime == ttime && t_eventlist[i].attime == attime)
	{
	  if (t_eventlist[i].taction == A_PLAY)
	    {
	      gi.sound (&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD,
			gi.soundindex (t_eventlist[i].info), 1.0, ATTN_NONE,
			0.0);
	    }
	  else if (t_eventlist[i].taction == A_PRINT)
	    {
	      CenterPrintAll (t_eventlist[i].info);
	    }
/*     
   else
   {
   if (t_eventlist[i].taction == A_SET)
   }
 */
	}
    }
}
示例#2
0
文件: a_match.c 项目: Maniac-/aq2-tng
//extern int started; // AQ2:M - Matchmode - Used for ready command
void Cmd_Ready_f(edict_t * ent)
{
	char temp[128];
	int		teamNum;
	team_t	*team;

	if (!matchmode->value) {
		gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n");
		return;
	}

	teamNum = ent->client->resp.team;
	if (teamNum == NOTEAM) {
		gi.cprintf( ent, PRINT_HIGH, "You need to be on a team for that...\n" );
		return;
	}

	team = &teams[teamNum];
	if (team->captain != ent) {
		gi.cprintf( ent, PRINT_HIGH, "You need to be a captain for that\n" );
		return;
	}

	if (!(gameSettings & GS_ROUNDBASED) && team_round_going) {
		if(teamdm->value)
			gi.cprintf(ent, PRINT_HIGH, "You can't unready in teamdm, use 'pausegame' instead\n");
		else
			gi.cprintf(ent, PRINT_HIGH, "You can't unready in ctf, use 'pausegame' instead\n");
		return;
	}

	team->ready = !team->ready;
	Com_sprintf( temp, sizeof( temp ), "%s %s ready to play!", team->name, (team->ready) ? "is" : "is no longer" );
	CenterPrintAll( temp );
}
示例#3
0
void _CheckScrambleVote (void)
{
	int i, numvotes, playernum, team;
	float votes;
	edict_t *ent, *other;
	char buf[128];

	_CalcScrambleVotes(&playernum, &numvotes, &votes);

	if (numvotes > 0)
	{
		sprintf (buf, "Scramble: %d votes (%.1f%%), need %.1f%%\n", numvotes, votes, scramblevote_pass->value);
		gi.bprintf (PRINT_HIGH, strtostr2 (buf));
	}

	if (playernum < scramblevote_min->value)
		return;
	if (numvotes < scramblevote_need->value)
		return;
	if (votes < scramblevote_pass->value)
		return;

	MakeAllLivePlayersObservers ();

	for (i = 1; i <= game.maxclients; i++)
	{
		ent = &g_edicts[i];
		if (ent->client && ent->inuse && ent->client->resp.team != NOTEAM)
		{
			other = _RandomTeamPlayer();
			if(other != NULL && rand() % 2) {
				team = other->client->resp.team;
				other->client->resp.team = ent->client->resp.team;
				ent->client->resp.team = team;
				ent->client->resp.scramblevote = false;
			}
		}
	}

	CenterPrintAll("The teams have been scrambled!");
}
示例#4
0
//sets new round, returns wether enough players are available
//or not
qboolean TourneyNewRound (void)
{
  char buf[4096];
  edict_t *dummy;

//  gi.bprintf(PRINT_HIGH,"LastOpponent: %i\n", LastOpponent);        
  if (LastOpponent < 2)
    return (false);
  strcpy (buf, "Next game: ");
  dummy = TourneyFindPlayer (1);
  if (dummy)
    {
      dummy->client->resp.team = TEAM1;
      strcat (buf, dummy->client->pers.netname);
    }
  else
    {
      gi.dprintf ("Tourney Error: cannot find player #1!\n");
      strcat (buf, "(unknown)");
    }

  strcat (buf, " vs ");

  dummy = TourneyFindPlayer (NextOpponent);
  if (dummy)
    {
      dummy->client->resp.team = TEAM2;
      strcat (buf, dummy->client->pers.netname);
    }
  else
    {
      gi.dprintf ("Tourney Error: cannot find NextOpponent (%i)!\n",
		  NextOpponent);
      strcat (buf, "(unknown)");
    }

  strcat (buf, "\n");
  CenterPrintAll (buf);
  return (true);
}
示例#5
0
文件: a_match.c 项目: Maniac-/aq2-tng
/*
==============
MM_SetCaptain
==============
Set ent to be a captain of team, ent can be NULL to remove captain
*/
void MM_SetCaptain( int teamNum, edict_t *ent )
{
	int i;
	edict_t *oldCaptain = teams[teamNum].captain;

	if (teamNum == NOTEAM)
		ent = NULL;

	teams[teamNum].captain = ent;
	if (!ent) {
		if (!team_round_going || (gameSettings & GS_ROUNDBASED)) {
			if (teams[teamNum].ready) {
				char temp[128];
				Com_sprintf( temp, sizeof( temp ), "%s is no longer ready to play!", teams[teamNum].name );
				CenterPrintAll( temp );
			}
			teams[teamNum].ready = 0;
		}
		if (oldCaptain) {
			gi.bprintf( PRINT_HIGH, "%s is no longer %s's captain\n", oldCaptain->client->pers.netname, teams[teamNum].name );
		}
		teams[teamNum].locked = 0;
		return;
	}

	if (ent != oldCaptain) {
		gi.bprintf( PRINT_HIGH, "%s is now %s's captain\n", ent->client->pers.netname, teams[teamNum].name );
		gi.cprintf( ent, PRINT_CHAT, "You are the captain of '%s'\n", teams[teamNum].name );
		gi.sound( &g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex( "misc/comp_up.wav" ), 1.0, ATTN_NONE, 0.0 );

		for (i = TEAM1; i <= teamCount; i++) {
			if (i != teamNum && teams[i].wantReset)
				gi.cprintf( ent, PRINT_HIGH, "Team %i wants to reset scores, type 'resetscores' to accept\n", i );
		}
	}
}
示例#6
0
文件: a_match.c 项目: Maniac-/aq2-tng
void Cmd_TogglePause_f(edict_t * ent, qboolean pause)
{
	static int lastPaused = 0;
	int		teamNum;

	if (!matchmode->value) {
		gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n");
		return;
	}

	if ((int)mm_pausecount->value < 1) {
		gi.cprintf(ent, PRINT_HIGH, "Pause is disabled, mm_pausecount is 0\n");
		return;
	}

	if (mm_pausetime->value < FRAMETIME) {
		gi.cprintf( ent, PRINT_HIGH, "Pause is disabled, mm_pausetime is 0\n" );
		return;
	}

	teamNum = ent->client->resp.team;
	if (teamNum == NOTEAM) {
		gi.cprintf(ent, PRINT_HIGH, "You need to be on a team for that...\n");
		return;
	}

	if (!team_round_going) {
		gi.cprintf(ent, PRINT_HIGH, "No match running, so why pause?\n");
		//return;
	}

	if (ent->client->resp.subteam) {
		gi.cprintf(ent, PRINT_HIGH, "You can't pause when substitute\n");
		return;
	}

	if(pause)
	{
		if(level.pauseFrames > 0)
		{
			gi.cprintf(ent, PRINT_HIGH, "Game is already paused you silly\n", time);
			return;
		}
		if (level.intermission_framenum) {
			gi.cprintf(ent, PRINT_HIGH, "Can't pause in an intermission.\n");
			return;
		}
		if(teams[teamNum].pauses_used >= (int)mm_pausecount->value)
		{
			gi.cprintf(ent, PRINT_HIGH, "Your team doesn't have any pauses left.\n");
			return;
		}
		teams[teamNum].pauses_used++;

		CenterPrintAll (va("Game paused by %s\nTeam %i has %i pauses left", ent->client->pers.netname, ent->client->resp.team, (int)mm_pausecount->value - teams[ent->client->resp.team].pauses_used));
		level.pauseFrames = (int)(mm_pausetime->value * 60.0f * HZ);
		lastPaused = teamNum;
	}
	else
	{
		if (!level.pauseFrames)
		{
			gi.cprintf(ent, PRINT_HIGH, "Game is not paused\n", time);
			return;
		}
		if(!lastPaused)
		{
			gi.cprintf(ent, PRINT_HIGH, "Already unpausing\n");
			return;
		}
		if(lastPaused != teamNum)
		{
			gi.cprintf(ent, PRINT_HIGH, "You can't unpause when paused by the other team\n");
			return;
		}
		level.pauseFrames = 10 * HZ;
		lastPaused = 0;
	}
}
示例#7
0
文件: a_match.c 项目: Maniac-/aq2-tng
void Cmd_TeamLock_f(edict_t *ent, int a_switch)
{
	char msg[128], *s;
	int teamNum, i;
	team_t *team;

	if (!matchmode->value) {
		gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n");
		return;
	}

	if (!mm_allowlock->value) {
		gi.cprintf(ent, PRINT_HIGH, "Team locking is disabled on this server\n");
		return;
	}

	//Admin can lock teams
	if (ent->client->pers.admin && gi.argc() > 1)
	{
		s = gi.argv(1);
		teamNum = TP_GetTeamFromArg(s);
		if (teamNum < 1) {
			gi.cprintf(ent, PRINT_HIGH, "Unknown team '%s'.\n", s);
			return;
		}
		team = &teams[teamNum];
		if (a_switch == team->locked) {
			gi.cprintf(ent, PRINT_HIGH, "Team %s locked\n", (a_switch) ? "is already" : "isn't");
			return;
		}
		if (a_switch) {
			gclient_t *client;

			for (i = 0, client = game.clients; i < game.maxclients; i++, client++) {
				if (client->pers.connected && client->resp.team == teamNum)
					break;
			}
			if (i == game.maxclients) {
				gi.cprintf(ent, PRINT_HIGH, "You can't lock teams without players\n");
				return;
			}
		}
	}
	else
	{
		teamNum = ent->client->resp.team;
		if (teamNum == NOTEAM) {
			gi.cprintf(ent, PRINT_HIGH, "You are not on a team\n");
			return;
		}

		team = &teams[teamNum];
		if (team->captain != ent) {
			gi.cprintf(ent, PRINT_HIGH, "You are not the captain of your team\n");
			return;
		}

		if (a_switch == team->locked) {
			gi.cprintf(ent, PRINT_HIGH, "Your team %s locked\n", (a_switch) ? "is already" : "isn't");
			return;
		}
	}

	team->locked = a_switch;
	Com_sprintf( msg, sizeof( msg ), "%s is now %s", team->name, (a_switch) ? "locked" : "unlocked" );
	CenterPrintAll(msg);
}
示例#8
0
qboolean ScrambleTeams(void)
{
	int i, j, numplayers, newteam;
	edict_t *ent, *players[MAX_CLIENTS], *oldCaptains[TEAM_TOP] = {NULL};

	numplayers = 0;
	for (i = 0, ent = &g_edicts[1]; i < game.maxclients; i++, ent++)
	{
		if (!ent->inuse || !ent->client || !ent->client->resp.team || ent->client->resp.subteam)
			continue;

		players[numplayers++] = ent;
	}

	if (numplayers <= teamCount)
		return false;

	for (i = numplayers - 1; i > 0; i--) {
		j = rand() % (i + 1);
		ent = players[j];
		players[j] = players[i];
		players[i] = ent;
	}

	MakeAllLivePlayersObservers();
	team_round_going = 0;

	if (matchmode->value) {
		for (i = TEAM1; i <= teamCount; i++) {
			oldCaptains[i] = teams[i].captain;
			teams[i].captain = NULL;
		}
	}

	for (i = 0; i < numplayers; i++) {
		ent = players[i];
		newteam = (i % teamCount) + 1;

		if (oldCaptains[ent->client->resp.team] == ent && !teams[newteam].captain)
			teams[newteam].captain = ent;

		ent->client->resp.team = newteam;

		const char *s = Info_ValueForKey( ent->client->pers.userinfo, "skin" );
		AssignSkin( ent, s, false );
	}

	teams_changed = true;

	CenterPrintAll("The teams have been scrambled!");

	//Clear voting
	for (i = 0, ent = &g_edicts[1]; i < game.maxclients; i++, ent++)
	{
		if (!ent->inuse || !ent->client)
			continue;

		ent->client->resp.scramblevote = 0;
	}
	return true;
}
示例#9
0
文件: g_combat.c 项目: andrijan/ajaq
void
T_Damage (edict_t * targ, edict_t * inflictor, edict_t * attacker, vec3_t dir,
	  vec3_t point, vec3_t normal, int damage, int knockback, int dflags,
	  int mod)
{
	gclient_t *client;
	char buf[256];
	int take, save;
	int asave, psave;
	int te_sparks, do_sparks = 0;
	int damage_type = 0;		// used for MOD later
	int bleeding = 0;		// damage causes bleeding
	int head_success = 0;
	int instant_dam = 1;
	float z_rel;
	int height;
	float from_top;
	vec_t dist;
	float targ_maxs2;		//FB 6/1/99

	// do this before teamplay check
	if (!targ->takedamage)
		return;

	//FIREBLADE
	if (teamplay->value && mod != MOD_TELEFRAG)
	{
		if (lights_camera_action)
			return;

		// AQ2:TNG - JBravo adding UVtime
		if (ctf->value && targ->client)
		{
			if(targ->client->ctf_uvtime > 0)
				return;
			if (attacker->client && attacker->client->ctf_uvtime > 0)
				return;
		}

		// AQ2:TNG - JBravo adding FF after rounds
		if (targ != attacker && targ->client && attacker->client &&
			targ->client->resp.team == attacker->client->resp.team &&
			((int)(dmflags->value) & (DF_NO_FRIENDLY_FIRE))) {
				if (team_round_going)
					return;
				else if (!ff_afterround->value)
					return;
		}
		// AQ:TNG
	}
	//FIREBLADE

	if (dm_shield->value && targ->client)
	{
		if (targ->client->ctf_uvtime > 0)
			return;
		if (attacker->client && attacker->client->ctf_uvtime > 0)
			return;
	}

	// damage reduction for shotgun
	// if far away, reduce it to original action levels
	if (mod == MOD_M3)
	{
		dist = Distance(targ->s.origin, inflictor->s.origin);
		if (dist > 450.0)
			damage = damage - 2;
	}

	targ_maxs2 = targ->maxs[2];
	if (targ_maxs2 == 4)
		targ_maxs2 = CROUCHING_MAXS2;	//FB 6/1/99

	height = abs (targ->mins[2]) + targ_maxs2;

	// locational damage code
	// base damage is head shot damage, so all the scaling is downwards
	if (targ->client)
	{
		if (!((targ != attacker) &&
		((deathmatch->value && ((int)dmflags->value
		& (DF_MODELTEAMS | DF_SKINTEAMS)))
		|| coop->value) && (attacker && attacker->client
		&& OnSameTeam (targ, attacker) &&	 
		((int)dmflags->value & DF_NO_FRIENDLY_FIRE)
		&& (team_round_going && ff_afterround->value))))

		{

			// TNG Stats - Add +1 to hit, make sure that hc and m3 are handles differently

			if ((attacker->client) && (mod != MOD_M3) && (mod != MOD_HC)) {
				strcpy(attacker->client->resp.last_damaged_players, targ->client->pers.netname);

				if (!teamplay->value || team_round_going || stats_afterround->value) {
					attacker->client->resp.stats_hits[mod]++;
					attacker->client->resp.stats_shots_h++;
				}
			}
 
			// TNG Stats END


			if (mod == MOD_MK23 || mod == MOD_MP5 || mod == MOD_M4 ||
				mod == MOD_SNIPER || mod == MOD_DUAL || mod == MOD_KNIFE ||
				mod == MOD_KNIFE_THROWN)
			{
				z_rel = point[2] - targ->s.origin[2];
				from_top = targ_maxs2 - z_rel;
				if (from_top < 0.0)	//FB 6/1/99
				from_top = 0.0;	//Slightly negative values were being handled wrong
				bleeding = 1;
				instant_dam = 0;

				// damage reduction for longer range pistol shots
				if (mod == MOD_MK23 || mod == MOD_DUAL)
				{
					dist = Distance(targ->s.origin, inflictor->s.origin);
					if (dist > 600.0 && dist < 1400.0)
						damage = (int) (damage * 2 / 3);
					else if (dist > 1400.0)
						damage = (int) (damage * 1 / 2);
				}


	      //gi.cprintf(targ, PRINT_HIGH, "z_rel is %f\n leg: %f stomach: %f chest: %f\n", z_rel, LEG_DAMAGE, STOMACH_DAMAGE, CHEST_DAMAGE );
	      //gi.cprintf(targ, PRINT_HIGH, "point[2]: %f targ->s.origin[2]: %f height: %d\n", point[2], targ->s.origin[2], height );
	      //gi.cprintf(targ, PRINT_HIGH, "abs(trag->min[2]): %d targ_max[2] %d\n", (int)abs(targ->mins[2]), (int)targ_maxs2);
	      //gi.cprintf(attacker, PRINT_HIGH, "abs(trag->min[2]): %d targ_max[2] %d\n", (int)abs(targ->mins[2]), (int)targ_maxs2); 
	      //gi.cprintf(attacker, PRINT_HIGH, "abs(trag->min[0]): %d targ_max[0] %d\n", (int)abs(targ->mins[0]), (int)targ->maxs[0]); 
	      //gi.cprintf(attacker, PRINT_HIGH, "abs(trag->min[1]): %d targ_max[1] %d\n", (int)abs(targ->mins[1]), (int)targ->maxs[1]); 


				if (from_top < 2 * HEAD_HEIGHT)
				{
					vec3_t new_point;
					VerifyHeadShot (point, dir, HEAD_HEIGHT, new_point);
					VectorSubtract (new_point, targ->s.origin, new_point);
					//gi.cprintf(attacker, PRINT_HIGH, "z: %d y: %d x: %d\n", (int)(targ_maxs2 - new_point[2]),(int)(new_point[1]) , (int)(new_point[0]) );

					if ((targ_maxs2 - new_point[2]) < HEAD_HEIGHT
						&& (abs (new_point[1])) < HEAD_HEIGHT * .8
						&& (abs (new_point[0])) < HEAD_HEIGHT * .8)
					{
						head_success = 1;
					}
				}

				if (head_success)
				{
					if (attacker->client)
					{
						if (!teamplay->value || team_round_going || stats_afterround->value) {
							attacker->client->resp.stats_headshot[mod]++;
						}
						//AQ2:TNG Slicer Last Damage Location
						if (INV_AMMO(targ, HELM_NUM)) {
							attacker->client->resp.last_damaged_part = LOC_KVLR_HELMET;
							if ((!teamplay->value || team_round_going || stats_afterround->value))
								attacker->client->resp.stats_locations[LOC_KVLR_HELMET]++;
						} else {
							attacker->client->resp.last_damaged_part = LOC_HDAM;
							if ((!teamplay->value || team_round_going || stats_afterround->value))
								attacker->client->resp.stats_locations[LOC_HDAM]++;
						}

						//AQ2:TNG END
						if (!OnSameTeam (targ, attacker))
							attacker->client->resp.hs_streak++;

						// AQ:TNG Igor[Rock] changing sound dir
						if (attacker->client->resp.hs_streak == 3)
						{
							if (use_rewards->value)
							{
								sprintf (buf, "ACCURACY %s!", attacker->client->pers.netname);
								CenterPrintAll (buf);
								gi.sound (&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD,
									gi.soundindex ("tng/accuracy.wav"), 1.0, ATTN_NONE, 0.0);
							}
							attacker->client->resp.hs_streak = 0;
						}
						// end of changing sound dir
					}

					if (INV_AMMO(targ, HELM_NUM) && mod != MOD_KNIFE
						&& mod != MOD_KNIFE_THROWN && mod != MOD_SNIPER)
					{
						if (attacker->client)
						{
							gi.cprintf (attacker, PRINT_HIGH, "%s has a Kevlar Helmet - AIM FOR THE BODY!\n",
								targ->client->pers.netname);
							gi.cprintf (targ, PRINT_HIGH, "Kevlar Helmet absorbed a part of %s's shot\n",
								attacker->client->pers.netname);
						}
						gi.sound (targ, CHAN_ITEM, gi.soundindex("misc/vest.wav"), 1,
							ATTN_NORM, 0);
						damage = (int) (damage / 2);
						damage_type = LOC_HDAM;
						bleeding = 0;
						instant_dam = 1;
						stopAP = 1;
						do_sparks = 1;
					}
					else if (INV_AMMO(targ, HELM_NUM) && mod == MOD_SNIPER)
					{
						if (attacker->client)
						{
							gi.cprintf (attacker, PRINT_HIGH,
							"%s has a Kevlar Helmet, too bad you have AP rounds...\n",
							targ->client->pers.netname);
							gi.cprintf (targ, PRINT_HIGH,
							"Kevlar Helmet absorbed some of %s's AP sniper round\n",
							attacker->client->pers.netname);
						}
						damage = (int) (damage * 0.325);
						gi.sound (targ, CHAN_VOICE, gi.soundindex("misc/headshot.wav"), 1,
							ATTN_NORM, 0);
						damage_type = LOC_HDAM;
					}
					else
					{
						damage = damage * 1.8 + 1;
						gi.cprintf (targ, PRINT_HIGH, "Head damage\n");
						if (attacker->client)
							gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the head\n",
								targ->client->pers.netname);
						damage_type = LOC_HDAM;
						if (mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN)
							gi.sound (targ, CHAN_VOICE, gi.soundindex ("misc/headshot.wav"), 1,
								ATTN_NORM, 0);
					//else
					//      gi.sound(targ, CHAN_VOICE, gi.soundindex("misc/glurp.wav"), 1, ATTN_NORM, 0);                
					}
				}
				else if (z_rel < LEG_DAMAGE)
				{
					damage = damage * .25;
					gi.cprintf (targ, PRINT_HIGH, "Leg damage\n");
					if (attacker->client)
					{
						attacker->client->resp.hs_streak = 0;
						gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the legs\n",
							targ->client->pers.netname);
					}
					damage_type = LOC_LDAM;
                    if (!heroes->value || targ->client->resp.team == 2) { // ESJ Heroes don't run out
                        targ->client->leg_damage = 1;
                        targ->client->leghits++;
                    }
					//AQ2:TNG Slicer Last Damage Location
					attacker->client->resp.last_damaged_part = LOC_LDAM;
					//AQ2:TNG END
					if (!teamplay->value || team_round_going || stats_afterround->value)
						attacker->client->resp.stats_locations[LOC_LDAM]++; // TNG Stats
				}
				else if (z_rel < STOMACH_DAMAGE)
				{
					damage = damage * .4;
					gi.cprintf (targ, PRINT_HIGH, "Stomach damage\n");
					if (attacker->client)
					{
						attacker->client->resp.hs_streak = 0;
						gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the stomach\n",
							targ->client->pers.netname);
					}
					damage_type = LOC_SDAM;
					//TempFile bloody gibbing
					if (mod == MOD_SNIPER && sv_gib->value)
						ThrowGib (targ, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
					//AQ2:TNG Slicer Last Damage Location
					attacker->client->resp.last_damaged_part = LOC_SDAM;
					//AQ2:TNG END
					if (!teamplay->value || team_round_going || stats_afterround->value)
						attacker->client->resp.stats_locations[LOC_SDAM]++; // TNG Stats
				}
				else		//(z_rel < CHEST_DAMAGE)
				{
					if (attacker->client)
					{
						attacker->client->resp.hs_streak = 0;
					}

					if (INV_AMMO(targ, KEV_NUM) && mod != MOD_KNIFE
						&& mod != MOD_KNIFE_THROWN && mod != MOD_SNIPER)
					{
						if (attacker->client)
						{
							gi.cprintf (attacker, PRINT_HIGH, "%s has a Kevlar Vest - AIM FOR THE HEAD!\n",
								targ->client->pers.netname);
							gi.cprintf (targ, PRINT_HIGH, "Kevlar Vest absorbed most of %s's shot\n",
								attacker->client->pers.netname);
							/*
							if (IsFemale(targ))
							gi.cprintf(attacker, PRINT_HIGH, "You bruised %s through her Kevlar Vest\n", targ->client->pers.netname);
							else
							gi.cprintf(attacker, PRINT_HIGH, "You bruised %s through his Kevlar Vest\n", targ->client->pers.netname);
							*/
						}
						gi.sound (targ, CHAN_ITEM, gi.soundindex ("misc/vest.wav"), 1,
							ATTN_NORM, 0);
						damage = (int) (damage / 10);
						damage_type = LOC_CDAM;
						bleeding = 0;
						instant_dam = 1;
						stopAP = 1;
						do_sparks = 1;
					}
					else if (INV_AMMO(targ, KEV_NUM) && mod == MOD_SNIPER)
					{
						if (attacker->client)
						{
							gi.cprintf (attacker, PRINT_HIGH, "%s has a Kevlar Vest, too bad you have AP rounds...\n",
								targ->client->pers.netname);
							gi.cprintf (targ, PRINT_HIGH, "Kevlar Vest absorbed some of %s's AP sniper round\n",
								attacker->client->pers.netname);
						}
						damage = damage * .325;
						damage_type = LOC_CDAM;
					}
					else
					{
						damage = damage * .65;
						gi.cprintf (targ, PRINT_HIGH, "Chest damage\n");
						if (attacker->client)
							gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the chest\n",
								targ->client->pers.netname);
						damage_type = LOC_CDAM;
						//TempFile bloody gibbing
						if (mod == MOD_SNIPER && sv_gib->value)
							ThrowGib (targ, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
					}
					//AQ2:TNG Slicer Last Damage Location
					if (INV_AMMO(targ, KEV_NUM) && mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) {
						attacker->client->resp.last_damaged_part = LOC_KVLR_VEST;
						if (!teamplay->value || team_round_going || stats_afterround->value)
							attacker->client->resp.stats_locations[LOC_KVLR_VEST]++; // TNG Stats
					} else {
						attacker->client->resp.last_damaged_part = LOC_CDAM;
						if (!teamplay->value || team_round_going || stats_afterround->value)
							attacker->client->resp.stats_locations[LOC_CDAM]++; // TNG Stats
					}
					//AQ2:TNG END

				}
	      /*else
	         {   

	         // no mod to damage 
	         gi.cprintf(targ, PRINT_HIGH, "Head damage\n"); 
	         if (attacker->client) 
	         gi.cprintf(attacker, PRINT_HIGH, "You hit %s in the head\n", targ->client->pers.netname); 
	         damage_type = LOC_HDAM;
	         gi.sound(targ, CHAN_VOICE, gi.soundindex("misc/headshot.wav"), 1, ATTN_NORM, 0);
	         } */
			}
			if (team_round_going && attacker->client && targ != attacker
				&& OnSameTeam (targ, attacker))
			{
				Add_TeamWound (attacker, targ, mod);
			}
		}
    }


	if (damage_type && !instant_dam)	// bullets but not vest hits
	{
		vec3_t temp;
		vec3_t temporig;
		//vec3_t forward;
		VectorMA (targ->s.origin, 50, dir, temp);
		//AngleVectors (attacker->client->v_angle, forward, NULL, NULL);
		VectorScale (dir, 20, temp);
		VectorAdd (point, temp, temporig);
		if (mod != MOD_SNIPER)
			spray_blood (targ, temporig, dir, damage, mod);
		else
			spray_sniper_blood (targ, temporig, dir);
	}

	if (mod == MOD_FALLING && !(targ->flags & FL_GODMODE) )
	{
        if (!heroes->value || targ->client->resp.team == 2) { // ESJ no limp for heroes
            if (targ->client && targ->health > 0)
            {
                gi.cprintf (targ, PRINT_HIGH, "Leg damage\n");
                targ->client->leg_damage = 1;
                targ->client->leghits++;
            //      bleeding = 1; for testing
            }
        }
    }

    if (heroes->value && targ->client && targ->client->resp.team == 1)  //ESJ take damage or give points, depending
    {
        if (attacker->client) //not fall damage or the like
        {
            attacker->client->points += damage;
            while (attacker->client->points >= 100)
            {
                attacker->client->resp.score++;
                attacker->client->points -= 100;
            }
        }
        damage = 0;
    }

	// friendly fire avoidance
	// if enabled you can't hurt teammates (but you can hurt yourself)
	// knockback still occurs
	if (targ != attacker &&
		((deathmatch->value && ((int)dmflags->value & (DF_MODELTEAMS | DF_SKINTEAMS)))
		|| coop->value))
	{
		if (OnSameTeam (targ, attacker))
		{
			if ((int)dmflags->value & DF_NO_FRIENDLY_FIRE &&
				(team_round_going || !ff_afterround->value))
				damage = 0;
			else
				mod |= MOD_FRIENDLY_FIRE;
		}
	}

	meansOfDeath = mod;
	locOfDeath = damage_type;	// location

	client = targ->client;

	if (dflags & DAMAGE_BULLET)
		te_sparks = TE_BULLET_SPARKS;
	else
		te_sparks = TE_SPARKS;

	VectorNormalize (dir);

  // bonus damage for suprising a monster
  //      if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0))
  //              damage *= 2;

	if (targ->flags & FL_NO_KNOCKBACK)
		knockback = 0;

	// figure momentum add
	if (!(dflags & DAMAGE_NO_KNOCKBACK))
	{
		if ((knockback) && (targ->movetype != MOVETYPE_NONE)
			&& (targ->movetype != MOVETYPE_BOUNCE)
			&& (targ->movetype != MOVETYPE_PUSH)
			&& (targ->movetype != MOVETYPE_STOP))
		{
			vec3_t kvel, flydir;
			float mass;

			if (mod != MOD_FALLING)
			{
				VectorCopy (dir, flydir);
				flydir[2] += 0.4f;
			}

			if (targ->mass < 50)
				mass = 50;
			else
				mass = targ->mass;

			if (targ->client && attacker == targ)
				VectorScale (flydir, 1600.0 * (float) knockback / mass, kvel);	// the rocket jump hack...
			else
				VectorScale (flydir, 500.0 * (float) knockback / mass, kvel);

			// FB
			//if (mod == MOD_KICK )
			//{
			//        kvel[2] = 0;
			//}

			VectorAdd (targ->velocity, kvel, targ->velocity);
		}
	}

	take = damage;
	save = 0;

	// check for godmode
	if ((targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION))
	{
		take = 0;
		save = damage;
		SpawnDamage (te_sparks, point, normal, save);
	}

	// zucc don't need this stuff, but to remove it need to change how damagefeedback works with colors

	// check for invincibility
	if ((client && client->invincible_framenum > level.framenum)
		&& !(dflags & DAMAGE_NO_PROTECTION))
	{
		if (targ->pain_debounce_time < level.time)
		{
			gi.sound (targ, CHAN_ITEM, gi.soundindex ("items/protect4.wav"), 1,
				ATTN_NORM, 0);
			targ->pain_debounce_time = level.time + 2;
		}
		take = 0;
		save = damage;
	}

	psave = CheckPowerArmor (targ, point, normal, take, dflags);
	take -= psave;

	asave = CheckArmor (targ, point, normal, take, te_sparks, dflags);
	take -= asave;

	//treat cheat/powerup savings the same as armor
	asave += save;

	// team damage avoidance
	if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage (targ, attacker))
		return;
	if ((mod == MOD_M3) || (mod == MOD_HC)
	|| (mod == MOD_HELD_GRENADE) || (mod == MOD_HG_SPLASH)
	|| (mod == MOD_G_SPLASH) || (mod == MOD_BREAKINGGLASS))
	{
		//FB 6/3/99 - shotgun damage report stuff
		int playernum = targ - g_edicts;
		playernum--;
		if (playernum >= 0 && playernum <= game.maxclients - 1)
			*(took_damage + playernum) = 1;
		//FB 6/3/99

		bleeding = 1;
		instant_dam = 0;
	}

  /*        if ( (mod == MOD_M3) || (mod == MOD_HC) )
     {
     instant_dam = 1;            
     remain = take % 2;
     take = (int)(take/2); // balances out difference in how action and axshun handle damage/bleeding

     }
   */

	if (ctf->value)
		CTFCheckHurtCarrier (targ, attacker);

	// do the damage
	if (take)
	{
		// zucc added check for stopAP, if it hit a vest we want sparks
		if (((targ->svflags & SVF_MONSTER) || (client)) && !do_sparks)
			SpawnDamage (TE_BLOOD, point, normal, take);
		else
			SpawnDamage (te_sparks, point, normal, take);

		// all things that have at least some instantaneous damage, i.e. bruising/falling
		if (instant_dam)
			targ->health = targ->health - take;

		if (targ->health <= 0)
		{
			if (client && attacker->client)
			{
				//Added these here also, if this is the last shot and before shots is from
				//different attacker, msg's would go to wrong client -M
				if (!OnSameTeam (attacker, targ))
					attacker->client->resp.damage_dealt += damage;
			
				client->attacker = attacker;
				client->attacker_mod = mod;
				client->attacker_loc = damage_type;
			}

			if ((targ->svflags & SVF_MONSTER) || (client))
				targ->flags |= FL_NO_KNOCKBACK;
			Killed (targ, inflictor, attacker, take, point);
			return;
		}
	}

	if (targ->svflags & SVF_MONSTER)
	{
		M_ReactToDamage (targ, attacker);
		if (!(targ->monsterinfo.aiflags & AI_DUCKED) && (take))
		{
			targ->pain (targ, attacker, knockback, take);
			// nightmare mode monsters don't go into pain frames often
			if (skill->value == 3)
				targ->pain_debounce_time = level.time + 5;
		}
	}
	else if (client)
	{
		if (!(targ->flags & FL_GODMODE) && (take))
			targ->pain (targ, attacker, knockback, take);
	}
	else if (take)
	{
		if (targ->pain)
			targ->pain (targ, attacker, knockback, take);
	}

	// add to the damage inflicted on a player this frame
	// the total will be turned into screen blends and view angle kicks
	// at the end of the frame
	if (client)
	{
		client->damage_parmor += psave;
		client->damage_armor += asave;
		client->damage_blood += take;
		client->damage_knockback += knockback;
		//zucc handle adding bleeding here
		if (damage_type && bleeding)	// one of the hit location weapons
		{
			/* zucc add in partial bleeding, changed
			if ( client->bleeding < 4*damage*BLEED_TIME )
			{
			client->bleeding = 4*damage*BLEED_TIME + client->bleeding/2;

			}
			else
			{
			client->bleeding += damage*BLEED_TIME*2;

			} */
			client->bleeding += damage * BLEED_TIME;
			VectorSubtract (point, targ->absmax, targ->client->bleedloc_offset);
			//VectorSubtract(point, targ->s.origin,  client->bleedloc_offset);

		}
		else if (bleeding)
		{
			/*
			if ( client->bleeding < damage*BLEED_TIME )
			{
			client->bleeding = damage*BLEED_TIME;
			//client->bleedcount = 0;
			} */
			client->bleeding += damage * BLEED_TIME;
			VectorSubtract (point, targ->absmax, targ->client->bleedloc_offset);
			//VectorSubtract(point, targ->s.origin,  client->bleedloc_offset);

		}
		if (attacker->client)
		{
			if (!OnSameTeam (attacker, targ))
				attacker->client->resp.damage_dealt += damage;

			client->attacker = attacker;
			client->attacker_mod = mod;
			client->attacker_loc = damage_type;
			client->push_timeout = 50;
			//VectorCopy(dir, client->bleeddir );
			//VectorCopy(point, client->bleedpoint );
			//VectorCopy(normal, client->bleednormal);

		}
		VectorCopy (point, client->damage_from);
	}
}