Ejemplo n.º 1
0
void G_AddKillSkillPointsForDestruction( gentity_t *attacker, meansOfDeath_t mod, g_constructible_stats_t *constructibleStats )
{
	switch( mod ) {
		case MOD_GRENADE_LAUNCHER:
		case MOD_GRENADE_PINEAPPLE:
			G_AddSkillPoints( attacker, SK_LIGHT_WEAPONS, constructibleStats->destructxpbonus );
			G_DebugAddSkillPoints( attacker, SK_LIGHT_WEAPONS, constructibleStats->destructxpbonus, "destroying a constructible/explosive" ); 
			break;
		case MOD_GPG40:
		case MOD_M7:
		case MOD_DYNAMITE:
		case MOD_LANDMINE:
			G_AddSkillPoints( attacker, SK_EXPLOSIVES_AND_CONSTRUCTION, constructibleStats->destructxpbonus );
			G_DebugAddSkillPoints( attacker, SK_EXPLOSIVES_AND_CONSTRUCTION, constructibleStats->destructxpbonus, "destroying a constructible/explosive" ); 
			break;
		case MOD_PANZERFAUST:
		case MOD_MORTAR:
			G_AddSkillPoints( attacker, SK_HEAVY_WEAPONS, constructibleStats->destructxpbonus );
			G_DebugAddSkillPoints( attacker, SK_HEAVY_WEAPONS, constructibleStats->destructxpbonus, "destroying a constructible/explosive" ); 
			break;
		case MOD_ARTY:
		case MOD_AIRSTRIKE:
			G_AddSkillPoints( attacker, SK_SIGNALS, constructibleStats->destructxpbonus );
			G_DebugAddSkillPoints( attacker, SK_SIGNALS, constructibleStats->destructxpbonus, "destroying a constructible/explosive" ); 
			break;
		case MOD_SATCHEL:
			G_AddSkillPoints( attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, constructibleStats->destructxpbonus );
			G_DebugAddSkillPoints( attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, constructibleStats->destructxpbonus, "destroying a constructible/explosive" ); 
			break;
		default:
			break;
	}
}
Ejemplo n.º 2
0
int Pickup_Health (gentity_t *ent, gentity_t *other) {
	int			max;
	int			quantity = 0;

	// if medic isn't giving ammo to self or another medic or the enemy, give him some props
	if( other->client->ps.stats[STAT_PLAYER_CLASS] != PC_MEDIC ) {
		if( ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
			if (!(ent->parent->client->PCSpecialPickedUpCount % MEDIC_SPECIAL_PICKUP_MOD)) {
				AddScore(ent->parent, WOLF_HEALTH_UP);
				G_LogPrintf("Health_Pack: %d %d\n", ent->parent - g_entities, other - g_entities);	// OSP
			}
			G_AddSkillPoints( ent->parent, SK_FIRST_AID, 1.f );
			G_DebugAddSkillPoints( ent->parent, SK_FIRST_AID, 1.f, "health pack picked up" ); 
			ent->parent->client->PCSpecialPickedUpCount++;
		}
	}	
	
	max = other->client->ps.stats[STAT_MAX_HEALTH];
	if( other->client->sess.playerType == PC_MEDIC ) {
		max *= 1.12f;
	}

	other->health += ent->item->quantity;
	if (other->health > max ) {
		other->health = max;
	}
	other->client->ps.stats[STAT_HEALTH] = other->health;

	return -1;
}
Ejemplo n.º 3
0
/**
 * @brief G_AddKillSkillPointsForDestruction
 * @param[in] attacker
 * @param[in] mod
 * @param[in] constructibleStats
 */
void G_AddKillSkillPointsForDestruction(gentity_t *attacker, meansOfDeath_t mod, g_constructible_stats_t *constructibleStats)
{
	if (GetMODTableData(mod)->skillType < SK_NUM_SKILLS)
	{
		G_AddSkillPoints(attacker, GetMODTableData(mod)->skillType, constructibleStats->destructxpbonus);
		G_DebugAddSkillPoints(attacker, GetMODTableData(mod)->skillType, constructibleStats->destructxpbonus, "destroying a constructible/explosive");
	}

	// prepare scoreboard
	CalculateRanks();
}
Ejemplo n.º 4
0
/**
 * @brief G_AddKillSkillPoints
 * @param[in] attacker
 * @param[in] mod
 * @param[in] hr
 * @param[in] splash
 */
void G_AddKillSkillPoints(gentity_t *attacker, meansOfDeath_t mod, hitRegion_t hr, qboolean splash)
{
	float       points;
	skillType_t skillType;
	const char  *reason;

	if (!attacker->client)
	{
		return;
	}

	if (GetMODTableData(mod)->hasHitRegion)
	{
		points = GetMODTableData(mod)->hitRegionKillPoints[hr];

		switch (hr)
		{
		case HR_HEAD: reason = va("%s headshot kill", GetMODTableData(mod)->debugReasonMsg); break;
		case HR_ARMS: reason = va("%s armshot kill", GetMODTableData(mod)->debugReasonMsg); break;
		case HR_BODY: reason = va("%s bodyshot kill", GetMODTableData(mod)->debugReasonMsg); break;
		case HR_LEGS: reason = va("%s legshot kill", GetMODTableData(mod)->debugReasonMsg); break;
		default:      reason = va("%s kill", GetMODTableData(mod)->debugReasonMsg); break; // for weapons that don't have localized damage, should not happen
		}
	}
	else if (splash)
	{
		points = GetMODTableData(mod)->splashKillPoints;

		reason = va("%s splash damage kill", GetMODTableData(mod)->debugReasonMsg);
	}
	else
	{
		points = GetMODTableData(mod)->defaultKillPoints;

		if (GetMODTableData(mod)->isExplosive)
		{
			reason = va("%s direct damage kill", GetMODTableData(mod)->debugReasonMsg);
		}
		else
		{
			reason = va("%s kill", GetMODTableData(mod)->debugReasonMsg);
		}
	}

	skillType = GetMODTableData(mod)->skillType;

	G_AddSkillPoints(attacker, skillType, points);
	G_DebugAddSkillPoints(attacker, skillType, points, reason);

	// prepare scoreboard
	CalculateRanks();
}
Ejemplo n.º 5
0
int Pickup_Health (gentity_t *ent, gentity_t *other) {
	int			max;
//	int			quantity = 0;

	// tjw: addef for g_shortcuts
	if(ent->parent && ent->parent->client)
		other->client->pers.lasthealth_client = ent->parent->s.clientNum;

	// if medic isn't giving ammo to self or another medic or the enemy, give him some props
	if( other->client->ps.stats[STAT_PLAYER_CLASS] != PC_MEDIC ) {
		if( ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
			if (!(ent->parent->client->PCSpecialPickedUpCount % MEDIC_SPECIAL_PICKUP_MOD)) {
				AddScore(ent->parent, WOLF_HEALTH_UP);
				G_LogPrintf("Health_Pack: %d %d\n", ent->parent - g_entities, other - g_entities);	// OSP
			}

			// forty - #474 - don't give xp if we're picking up our own med packs.
			if(other != ent->parent) {
				G_AddSkillPoints( ent->parent, SK_FIRST_AID, 1.f );
				G_DebugAddSkillPoints( ent->parent, SK_FIRST_AID, 1.f, "health pack picked up" );
			}

			ent->parent->client->PCSpecialPickedUpCount++;
		}
	}

	max = other->client->ps.stats[STAT_MAX_HEALTH];
	if( other->client->sess.playerType == PC_MEDIC ) {
		max *= 1.12f;
	}

	other->health += ent->item->quantity;

	// unpoison ourself if we pick up meds
	other->client->pmext.poisoned = qfalse;
	other->client->ps.viewlocked = 0;
	other->client->ps.viewlocked_entNum = 0;

	if (other->health > max ) {
		other->health = max;
	}
	other->client->ps.stats[STAT_HEALTH] = other->health;

	//omni-bot event
	if ( ent->parent )
		Bot_Event_Healed(other-g_entities, ent->parent);

	return -1;
}
Ejemplo n.º 6
0
/**
* @brief Pick health.
*/
int Pickup_Health(gentity_t *ent, gentity_t *other)
{
	int max;

	if (ent->parent && ent->parent->client)
	{
		other->client->pers.lasthealth_client = ent->parent->s.clientNum;
	}

	// if medic isn't giving ammo to self or another medic or the enemy, give him some props
	if (other->client->ps.stats[STAT_PLAYER_CLASS] != PC_MEDIC)
	{
		if (ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam)
		{
			if (!(ent->parent->client->PCSpecialPickedUpCount % MEDIC_SPECIAL_PICKUP_MOD))
			{
				AddScore(ent->parent, WOLF_HEALTH_UP);
				G_LogPrintf("Health_Pack: %d %d\n", (int)(ent->parent - g_entities), (int)(other - g_entities));
			}
			G_AddSkillPoints(ent->parent, SK_FIRST_AID, 1.f);
			G_DebugAddSkillPoints(ent->parent, SK_FIRST_AID, 1.f, "health pack picked up");
			ent->parent->client->PCSpecialPickedUpCount++;
		}
	}

	max = other->client->ps.stats[STAT_MAX_HEALTH];
	if (other->client->sess.playerType == PC_MEDIC)
	{
		max *= 1.12f;
	}

	other->health += ent->item->quantity;
	if (other->health > max)
	{
		other->health = max;
	}
	other->client->ps.stats[STAT_HEALTH] = other->health;

#ifdef FEATURE_OMNIBOT
	// omni-bot event
	if (ent->parent)
	{
		Bot_Event_Healed(other - g_entities, ent->parent);
	}
#endif

	return -1;
}
Ejemplo n.º 7
0
/**
 * @brief Pick health.
 * @param[in,out] ent
 * @param[in,out] other
 * @return
 */
int Pickup_Health(gentity_t *ent, gentity_t *other)
{
	int max;

	if (ent->parent && ent->parent->client)
	{
		other->client->pers.lasthealth_client = ent->parent->s.clientNum;
	}

	// if medic isn't giving ammo to self or the enemy, give him some props
	if (ent->parent && ent->parent->client && ent->parent->client != other->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam)
	{
		G_AddSkillPoints(ent->parent, SK_FIRST_AID, 1.f);
		G_DebugAddSkillPoints(ent->parent, SK_FIRST_AID, 1.f, "health pack picked up");
	}

	max = other->client->ps.stats[STAT_MAX_HEALTH];
	if (other->client->sess.playerType == PC_MEDIC)
	{
		max *= 1.12f;
	}

	other->health += ent->item->quantity;
	if (other->health > max)
	{
		other->health = max;
	}
	other->client->ps.stats[STAT_HEALTH] = other->health;

#ifdef FEATURE_OMNIBOT
	// omni-bot event
	if (ent->parent)
	{
		Bot_Event_Healed(other - g_entities, ent->parent);
	}
#endif

	return -1;
}
Ejemplo n.º 8
0
void G_AddKillSkillPoints(gentity_t *attacker, meansOfDeath_t mod, hitRegion_t hr, qboolean splash)
{

	if (!attacker->client)
	{
		return;
	}

	switch (mod)
	{
			// light weapons
		case MOD_KNIFE:
			G_AddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f);
			G_DebugAddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f, "knife kill");
			break;

		case MOD_LUGER:
		case MOD_COLT:
		case MOD_MP40:
		case MOD_THOMPSON:
		case MOD_STEN:
		case MOD_GARAND:
		case MOD_SILENCER:
		case MOD_FG42:

//      case MOD_FG42SCOPE:
		case MOD_CARBINE:
		case MOD_KAR98:
		case MOD_SILENCED_COLT:
		case MOD_K43:
		case MOD_AKIMBO_COLT:
		case MOD_AKIMBO_LUGER:
		case MOD_AKIMBO_SILENCEDCOLT:
		case MOD_AKIMBO_SILENCEDLUGER:
			switch (hr)
			{
				case HR_HEAD:
					G_AddSkillPoints(attacker, SK_LIGHT_WEAPONS, 5.f);
					G_DebugAddSkillPoints(attacker, SK_LIGHT_WEAPONS, 5.f, "headshot kill");
					break;

				case HR_ARMS:
					G_AddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f, "armshot kill");
					break;

				case HR_BODY:
					G_AddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f, "bodyshot kill");
					break;

				case HR_LEGS:
					G_AddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f, "legshot kill");
					break;

				default:
					G_AddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f, "kill");
					break;		// for weapons that don't have localized damage
			}

			break;

			// heavy weapons
		case MOD_MOBILE_MG42:
			G_AddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f);
			G_DebugAddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f, "mobile mg42 kill");
			break;

			// scoped weapons
		case MOD_GARAND_SCOPE:
		case MOD_K43_SCOPE:
		case MOD_FG42SCOPE:
			switch (hr)
			{
				case HR_HEAD:
					G_AddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 5.f);
					G_DebugAddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 5.f, "headshot kill");
					break;

				case HR_ARMS:
					G_AddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 2.f, "armshot kill");
					break;

				case HR_BODY:
					G_AddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f, "bodyshot kill");
					break;

				case HR_LEGS:
					G_AddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 2.f, "legshot kill");
					break;

				default:
					G_AddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f);
					G_DebugAddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f, "kill");
					break;		// for weapons that don't have localized damage
			}

			break;

			// misc weapons (individual handling)
		case MOD_SATCHEL:
			G_AddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 5.f);
			G_DebugAddSkillPoints(attacker, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 5.f, "satchel charge kill");
			break;

		case MOD_MACHINEGUN:
		case MOD_BROWNING:
		case MOD_MG42:
			G_AddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f);
			G_DebugAddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f, "emplaced machinegun kill");
			break;

		case MOD_PANZERFAUST:
			if (splash)
			{
				G_AddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f);
				G_DebugAddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f, "panzerfaust splash damage kill");
			}
			else
			{
				G_AddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f);
				G_DebugAddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f, "panzerfaust direct hit kill");
			}

			break;

		case MOD_FLAMETHROWER:
			G_AddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f);
			G_DebugAddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f, "flamethrower kill");
			break;

		case MOD_MORTAR:
			if (splash)
			{
				G_AddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f);
				G_DebugAddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f, "mortar splash damage kill");
			}
			else
			{
				G_AddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f);
				G_DebugAddSkillPoints(attacker, SK_HEAVY_WEAPONS, 3.f, "mortar direct hit kill");
			}

			break;

		case MOD_GRENADE_LAUNCHER:
		case MOD_GRENADE_PINEAPPLE:

//bani - airstrike marker kills
		case MOD_SMOKEGRENADE:
			G_AddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f);
			G_DebugAddSkillPoints(attacker, SK_LIGHT_WEAPONS, 3.f, "hand grenade kill");
			break;

		case MOD_DYNAMITE:
		case MOD_LANDMINE:
			G_AddSkillPoints(attacker, SK_EXPLOSIVES_AND_CONSTRUCTION, 4.f);
			G_DebugAddSkillPoints(attacker, SK_EXPLOSIVES_AND_CONSTRUCTION, 4.f, "dynamite or landmine kill");
			break;

		case MOD_ARTY:
			G_AddSkillPoints(attacker, SK_SIGNALS, 4.f);
			G_DebugAddSkillPoints(attacker, SK_SIGNALS, 4.f, "artillery kill");
			break;

		case MOD_AIRSTRIKE:
			G_AddSkillPoints(attacker, SK_SIGNALS, 3.f);
			G_DebugAddSkillPoints(attacker, SK_SIGNALS, 3.f, "airstrike kill");
			break;

		case MOD_GPG40:
		case MOD_M7:
			G_AddSkillPoints(attacker, SK_EXPLOSIVES_AND_CONSTRUCTION, 3.f);
			G_DebugAddSkillPoints(attacker, SK_EXPLOSIVES_AND_CONSTRUCTION, 3.f, "rifle grenade kill");
			break;

			// no skills for anything else
		default:
			break;
	}
}
Ejemplo n.º 9
0
void G_UpdateTeamMapData( void ) {
	int i, j/*, k*/;
	gentity_t *ent, *ent2;
	mapEntityData_t	*mEnt;

	if(level.time - level.lastMapEntityUpdate < 500) {
		return;
	}
	level.lastMapEntityUpdate = level.time;

	for(i = 0, ent = g_entities; i < level.num_entities; i++, ent++) {
		if(!ent->inuse) {
//			mapEntityData[0][i].valid = qfalse;
//			mapEntityData[1][i].valid = qfalse;
			continue;
		}

		switch(ent->s.eType) {
			case ET_PLAYER:
				G_UpdateTeamMapData_Player( ent, qfalse, qfalse );
				for( j = 0; j < 2; j++ ) {
					mapEntityData_Team_t *teamList = &mapEntityData[j];

					mEnt = G_FindMapEntityDataSingleClient( teamList, NULL, ent->s.number, -1 );
					
					while( mEnt ) {
						VectorCopy( ent->client->ps.origin, mEnt->org );
						mEnt->yaw = ent->client->ps.viewangles[YAW];
						mEnt = G_FindMapEntityDataSingleClient( teamList, mEnt, ent->s.number, -1 );
					}
				}
				break;
			case ET_CONSTRUCTIBLE_INDICATOR:
				if( ent->parent && ent->parent->entstate == STATE_DEFAULT ) {
					G_UpdateTeamMapData_Construct(ent);
				}
				break;
			case ET_EXPLOSIVE_INDICATOR:
				if( ent->parent && ent->parent->entstate == STATE_DEFAULT ) {
					G_UpdateTeamMapData_Destruct(ent);
				}
				break;
			case ET_TANK_INDICATOR:
			case ET_TANK_INDICATOR_DEAD:
				G_UpdateTeamMapData_Tank(ent);
				break;
			case ET_MISSILE:
				if( ent->methodOfDeath == MOD_LANDMINE) {
					G_UpdateTeamMapData_LandMine(ent, qfalse, qfalse);
				}
				break;
			case ET_COMMANDMAP_MARKER:
				G_UpdateTeamMapData_CommandmapMarker( ent );
				break;
			default:
				break;
		}
	}

	//for(i = 0, ent = g_entities; i < MAX_CLIENTS; i++, ent++) {
	for( i = 0, ent = g_entities; i < level.num_entities; i++, ent++ ) {
		qboolean f1, f2;
		if( !ent->inuse || !ent->client ) {
			continue;
		}

		if( ent->client->sess.playerType == PC_RECON ) {
			if( ent->health > 0 ) {
				f1 = ent->client->sess.sessionTeam == TEAM_ALLIES ? qtrue : qfalse;
				f2 = ent->client->sess.sessionTeam == TEAM_AXIS ?	qtrue : qfalse;

				G_SetupFrustum( ent );

				for( j = 0, ent2 = g_entities; j < level.num_entities; j++, ent2++ ) {
					if( !ent2->inuse || ent2 == ent ) {
						continue;
					}

					switch(ent2->s.eType) {
					case ET_PLAYER:
						{
						vec3_t pos[3];
						VectorCopy( ent2->client->ps.origin, pos[0] );
						pos[0][2] += ent2->client->ps.mins[2];
						VectorCopy( ent2->client->ps.origin, pos[1] );
						VectorCopy( ent2->client->ps.origin, pos[2] );
						pos[2][2] += ent2->client->ps.maxs[2];
						if(ent2->health > 0 && (G_VisibleFromBinoculars( ent, ent2, pos[0] ) ||
												G_VisibleFromBinoculars( ent, ent2, pos[1] ) ||
												G_VisibleFromBinoculars( ent, ent2, pos[2] ) ) ) {
							if(ent2->client->sess.sessionTeam != ent->client->sess.sessionTeam) {
								int k;

								switch(ent2->client->sess.sessionTeam) {
								case TEAM_AXIS:
									mEnt = G_FindMapEntityData( &mapEntityData[0], ent2-g_entities );
									if( mEnt && level.time - mEnt->startTime > 5000) {
										for( k = 0; k < MAX_CLIENTS; k++ ) {
											if(g_entities[k].inuse && g_entities[k].client && g_entities[k].client->sess.sessionTeam == ent->client->sess.sessionTeam) {
												trap_SendServerCommand( k, va( "tt \"ENEMY SPOTTED <STOP> CHECK COMMAND MAP FOR DETAILS <STOP>\"\n" ));
											}
										}
									}
									break;

								case TEAM_ALLIES:
									mEnt = G_FindMapEntityData( &mapEntityData[1], ent2-g_entities );
									if( mEnt && level.time - mEnt->startTime > 5000) {
										for( k = 0; k < MAX_CLIENTS; k++ ) {
											if(g_entities[k].inuse && g_entities[k].client && g_entities[k].client->sess.sessionTeam == ent->client->sess.sessionTeam) {
												trap_SendServerCommand( k, va( "tt \"ENEMY SPOTTED <STOP> CHECK COMMAND MAP FOR DETAILS <STOP>\"\n" ));
											}
										}
									}
									break;
								}
							}

							G_UpdateTeamMapData_Player(ent2, f1, f2);
						}
						break;
						}
					default:
						break;
					}
				}

				if(ent->client->ps.eFlags & EF_ZOOMING) {
					G_SetupFrustum_ForBinoculars( ent );

					for(j = 0, ent2 = g_entities; j < level.num_entities; j++, ent2++) {
						if(!ent2->inuse || ent2 == ent) {
							continue;
						}

						switch(ent2->s.eType) {
						case ET_MISSILE:
							if( ent2->methodOfDeath == MOD_LANDMINE) {
								if( (ent2->s.teamNum < 4 || ent2->s.teamNum >= 8) && (ent2->s.teamNum%4 != ent->client->sess.sessionTeam) ) 
								{
									// TAT - as before, we can only detect a mine if we can see it from our binoculars
									if (G_VisibleFromBinoculars( ent, ent2, ent2->r.currentOrigin ))
									{
										G_UpdateTeamMapData_LandMine(ent2, f1, f2);

										switch(ent2->s.teamNum%4) {
										case TEAM_AXIS:
											if( !ent2->s.modelindex2 ) {
												ent->client->landmineSpottedTime = level.time;
												ent->client->landmineSpotted = ent2;
												ent2->s.density = ent-g_entities+1;
												ent2->missionLevel = level.time;

												ent->client->landmineSpotted->count2 += 50;
												if(ent->client->landmineSpotted->count2 >= 250) {
//													int k;
													ent->client->landmineSpotted->count2 = 250;

													ent->client->landmineSpotted->s.modelindex2 = 1;

													// for marker
													ent->client->landmineSpotted->s.frame = rand() % 20;
													ent->client->landmineSpotted->r.contents = CONTENTS_CORPSE;
													trap_LinkEntity( ent->client->landmineSpotted );

													{
														gentity_t* pm = G_PopupMessage( PM_MINES );
														VectorCopy( ent->client->landmineSpotted->r.currentOrigin, pm->s.origin );
														pm->s.effect2Time = TEAM_AXIS;
														pm->s.effect3Time = ent-g_entities;
													}

/*													for( k = 0; k < MAX_CLIENTS; k++ ) {
														if(g_entities[k].inuse && g_entities[k].client && g_entities[k].client->sess.sessionTeam == ent->client->sess.sessionTeam) {
															trap_SendServerCommand( k, va( "tt \"LANDMINES SPOTTED BY %s^0<STOP> CHECK COMMAND MAP FOR DETAILS <STOP>\"\n", ent->client->pers.netname));
														}
													}*/

													trap_SendServerCommand( ent-g_entities, "cp \"Landmine Revealed\n\"" );

													AddScore( ent, 1 );
													//G_AddExperience( ent, 1.f );

													G_AddSkillPoints( ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f );
													G_DebugAddSkillPoints( ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f, "spotting a landmine" );
												}
											}
											break;

										case TEAM_ALLIES:
											if( !ent2->s.modelindex2 ) {
												ent->client->landmineSpottedTime = level.time;
												ent->client->landmineSpotted = ent2;
												ent2->s.density = ent-g_entities+1;
												ent2->missionLevel = level.time;

												ent->client->landmineSpotted->count2 += 50;
												if(ent->client->landmineSpotted->count2 >= 250) {
//													int k;
													ent->client->landmineSpotted->count2 = 250;

													ent->client->landmineSpotted->s.modelindex2 = 1;

													// for marker
													ent->client->landmineSpotted->s.frame = rand() % 20;
													ent->client->landmineSpotted->r.contents = CONTENTS_CORPSE;
													trap_LinkEntity( ent->client->landmineSpotted );

													{
														gentity_t* pm = G_PopupMessage( PM_MINES );
														VectorCopy( ent->client->landmineSpotted->r.currentOrigin, pm->s.origin );

														pm->s.effect2Time = TEAM_ALLIES;
														pm->s.effect3Time = ent-g_entities;
													}

/*													for( k = 0; k < MAX_CLIENTS; k++ ) {
														if(g_entities[k].inuse && g_entities[k].client && g_entities[k].client->sess.sessionTeam == ent->client->sess.sessionTeam) {
															trap_SendServerCommand( k, va( "tt \"LANDMINES SPOTTED BY %s^0<STOP> CHECK COMMAND MAP FOR DETAILS <STOP>\"\n", ent->client->pers.netname));
														}
													}*/

													trap_SendServerCommand( ent-g_entities, "cp \"Landmine Revealed\n\"" );

													AddScore( ent, 1 );
													//G_AddExperience( ent, 1.f );

													G_AddSkillPoints( ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f );
													G_DebugAddSkillPoints( ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f, "spotting a landmine" );
												}
											}
											break;
										} // end switch
									} // end (G_VisibleFromBinoculars( ent, ent2, ent2->r.currentOrigin ))
									else
									{
										// TAT - if we can't see the mine from our binoculars, make sure we clear out the landmineSpotted ptr,
										//		because bots looking for mines are getting confused
										ent->client->landmineSpotted = NULL;
									}
								}
							}
							break;
						default:
							break;
						}
					}

/*					if(ent->client->landmineSpotted && !ent->client->landmineSpotted->s.modelindex2) {
						ent->client->landmineSpotted->count2 += 10;
						if(ent->client->landmineSpotted->count2 >= 250) {
							int k;
							ent->client->landmineSpotted->count2 = 250;

							ent->client->landmineSpotted->s.modelindex2 = 1;

							// for marker
							ent->client->landmineSpotted->s.frame = rand() % 20;

							for( k = 0; k < MAX_CLIENTS; k++ ) {
								if(g_entities[k].inuse && g_entities[k].client && g_entities[k].client->sess.sessionTeam == ent->client->sess.sessionTeam) {
									trap_SendServerCommand( k, va( "tt \"LANDMINES SPOTTED <STOP> CHECK COMMAND MAP FOR DETAILS <STOP>\"\n" ));
								}
							}
							trap_SendServerCommand( ent-g_entities, "cp \"Landmine Revealed\n\"" );

							AddScore( ent, 1 );
							//G_AddExperience( ent, 1.f );

							G_AddSkillPoints( ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f );
							G_DebugAddSkillPoints( ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f, "spotting a landmine" );
						}
					}*/

/*					{
						// find any landmines that don't actually exist anymore, see if the covert ops can see the spot and if so - wipe them
						mapEntityData_Team_t *teamList = ent->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[0] : &mapEntityData[1];

						mEnt = teamList->activeMapEntityData.next;
						while( mEnt && mEnt != &teamList->activeMapEntityData ) {
							if( mEnt->type == ME_LANDMINE && mEnt->entNum == -1 ) {
								if( G_VisibleFromBinoculars( ent, NULL, mEnt->org ) ) {
									mEnt = G_FreeMapEntityData( teamList, mEnt );

									trap_SendServerCommand( ent-g_entities, "print \"Old Landmine Cleared\n\"" );
									AddScore( ent, 1 );
									continue;
								}
							}

							mEnt = mEnt->next;
						}
					}*/
				}
			}
		}
	}

//	G_SendAllMapEntityInfo();
}
Ejemplo n.º 10
0
int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
	int			quantity;
	qboolean	alreadyHave = qfalse;

	// JPW NERVE -- magic ammo for any two-handed weapon
	if( ent->item->giTag == WP_AMMO ) {
		AddMagicAmmo( other, ent->count );

		// if LT isn't giving ammo to self or another LT or the enemy, give him some props
		if( other->client->ps.stats[STAT_PLAYER_CLASS] != PC_FIELDOPS ) {
			if ( ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
				if (!(ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD)) {
					AddScore(ent->parent, WOLF_AMMO_UP);
					if(ent->parent && ent->parent->client) {
						G_LogPrintf("Ammo_Pack: %d %d\n", ent->parent - g_entities, other - g_entities);	// OSP
					}
				}
				ent->parent->client->PCSpecialPickedUpCount++;
				G_AddSkillPoints( ent->parent, SK_SIGNALS, 1.f );
				G_DebugAddSkillPoints( ent->parent, SK_SIGNALS, 1.f, "ammo pack picked up" ); 

				// extracted code originally here into AddMagicAmmo -xkan, 9/18/2002
				// add 1 clip of magic ammo for any two-handed weapon
			}
			return RESPAWN_SP;
		}
	}

	quantity = ent->count;

	// check if player already had the weapon
	alreadyHave = COM_BitCheck( other->client->ps.weapons, ent->item->giTag );

	// JPW NERVE  prevents drop/pickup weapon "quick reload" exploit
	if( alreadyHave ) {
		Add_Ammo( other, ent->item->giTag, quantity, qfalse );

		// Gordon: secondary weapon ammo
		if( ent->delay ) {
			Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
		}
	} else {
		if( level.time - other->client->dropWeaponTime < 1000 ) {
			return 0;
		}

		if( other->client->ps.weapon == WP_MORTAR_SET || other->client->ps.weapon == WP_MOBILE_MG42_SET ) {
			return 0;
		}

		// See if we can pick it up
		if( G_CanPickupWeapon( ent->item->giTag, other ) ) {
			weapon_t primaryWeapon = G_GetPrimaryWeaponForClient( other->client );

			if( primaryWeapon || 
				other->client->sess.playerType == PC_SOLDIER && other->client->sess.skill[SK_HEAVY_WEAPONS] >= 4 ) {

				if( primaryWeapon ) {
					// drop our primary weapon
					G_DropWeapon( other, primaryWeapon );
				}

				// now pickup the other one
				other->client->dropWeaponTime = level.time;

				// add the weapon
				COM_BitSet( other->client->ps.weapons, ent->item->giTag );

				// DHM - Fixup mauser/sniper issues
				if( ent->item->giTag == WP_FG42 ) {
					COM_BitSet( other->client->ps.weapons, WP_FG42SCOPE);
				} else if(ent->item->giTag == WP_GARAND) {
					COM_BitSet( other->client->ps.weapons, WP_GARAND_SCOPE);
				} else if( ent->item->giTag == WP_K43 ) {
					COM_BitSet( other->client->ps.weapons, WP_K43_SCOPE );
				} else if( ent->item->giTag == WP_MORTAR ) {
					COM_BitSet( other->client->ps.weapons, WP_MORTAR_SET );
				} else if( ent->item->giTag == WP_MOBILE_MG42 ) {
					COM_BitSet( other->client->ps.weapons, WP_MOBILE_MG42_SET );
				} else if( ent->item->giTag == WP_CARBINE ) {
					COM_BitSet( other->client->ps.weapons, WP_M7 );
				} else if( ent->item->giTag == WP_KAR98 ) {
					COM_BitSet( other->client->ps.weapons, WP_GPG40 );
				}

				other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = 0;
				other->client->ps.ammo[BG_FindAmmoForWeapon(ent->item->giTag)] = 0;

				if( ent->item->giTag == WP_MORTAR ) {
					other->client->ps.ammo[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
					}
				} else {
					other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						other->client->ps.ammo[ weapAlts[ ent->item->giTag ] ] = ent->delay;
					}
				}
			}
		} else {
			return 0;
		}
	}

	return -1;
}
Ejemplo n.º 11
0
int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
	int			quantity;
	qboolean	alreadyHave = qfalse;

	// JPW NERVE -- magic ammo for any two-handed weapon
	if( ent->item->giTag == WP_AMMO ) {
		AddMagicAmmo( other, ent->count );
		// tjw: added for g_shortcuts
		if(ent->parent && ent->parent->client)
			other->client->pers.lastammo_client = ent->parent->s.clientNum;
		// if LT isn't giving ammo to self or another LT or the enemy, give him some props
		if( other->client->ps.stats[STAT_PLAYER_CLASS] != PC_FIELDOPS ) {
			if ( ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
				if (!(ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD)) {
					AddScore(ent->parent, WOLF_AMMO_UP);
					if(ent->parent && ent->parent->client) {
						G_LogPrintf("Ammo_Pack: %d %d\n", ent->parent - g_entities, other - g_entities);	// OSP
					}
				}
				ent->parent->client->PCSpecialPickedUpCount++;

				// forty - #474 - don't give xp if we're picking up our own ammo packs.
				if(other != ent->parent) {
					G_AddSkillPoints( ent->parent, SK_SIGNALS, 1.f );
					G_DebugAddSkillPoints( ent->parent, SK_SIGNALS, 1.f, "ammo pack picked up" );
				}

				//omni-bot event
				if ( ent->parent )
					Bot_Event_RecievedAmmo(other-g_entities, ent->parent);

				// extracted code originally here into AddMagicAmmo -xkan, 9/18/2002
				// add 1 clip of magic ammo for any two-handed weapon
			}
			return RESPAWN_SP;
		}
	}

	if( ent->item->giTag == WP_BINOCULARS &&
			(g_weapons.integer & WPF_DROP_BINOCS) ) {
		COM_BitSet( other->client->ps.weapons, WP_BINOCULARS );
		other->client->ps.ammo[BG_FindAmmoForWeapon(WP_BINOCULARS)] = 1;
		other->client->ps.stats[STAT_KEYS] |= ( 1 << INV_BINOCS );
		other->client->sess.numBinocs++;
	}

	quantity = ent->count;

	// check if player already had the weapon
	alreadyHave = COM_BitCheck( other->client->ps.weapons, ent->item->giTag );

	// JPW NERVE  prevents drop/pickup weapon "quick reload" exploit
	if( alreadyHave ) {
		Add_Ammo( other, ent->item->giTag, quantity, qfalse );

		// Gordon: secondary weapon ammo
		if( ent->delay ) {
			Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
		}
	} else {
		if( level.time - other->client->dropWeaponTime < 1000 ) {
			return 0;
		}

		if( other->client->ps.weapon == WP_MORTAR_SET || other->client->ps.weapon == WP_MOBILE_MG42_SET ) {
			return 0;
		}

		// See if we can pick it up
		if( G_CanPickupWeapon( ent->item->giTag, other ) ) {
			weapon_t primaryWeapon = G_GetPrimaryWeaponForClient( other->client );

			// rain - added parens around ambiguous &&
			if( 1 || // Terifire, for dropweapon
				(other->client->sess.playerType == PC_SOLDIER && other->client->sess.skill[SK_HEAVY_WEAPONS] >= 4) ) {

				// gabriel: If a lvl 4 soldier is picking un a mp40/thompson,
				// don't allow the soldier to have both an mp40 and a thompson
				if ((ent->item->giTag == WP_MP40) &&
					COM_BitCheck( other->client->ps.weapons, WP_THOMPSON)) {

					G_DropWeapon( other, WP_THOMPSON);
				} else if ((ent->item->giTag == WP_THOMPSON) &&
					COM_BitCheck( other->client->ps.weapons, WP_MP40)) {

					G_DropWeapon( other, WP_MP40);
				} else if( primaryWeapon ) { // Otherwise, function normally
					// drop our primary weapon
					G_DropWeapon( other, primaryWeapon );
				}

				// now pickup the other one
				other->client->dropWeaponTime = level.time;

				// add the weapon
				COM_BitSet( other->client->ps.weapons, ent->item->giTag );

				// DHM - Fixup mauser/sniper issues
				if( ent->item->giTag == WP_FG42 ) {
					COM_BitSet( other->client->ps.weapons, WP_FG42SCOPE);
				} else if(ent->item->giTag == WP_GARAND) {
					COM_BitSet( other->client->ps.weapons, WP_GARAND_SCOPE);
				} else if( ent->item->giTag == WP_K43 ) {
					COM_BitSet( other->client->ps.weapons, WP_K43_SCOPE );
				} else if( ent->item->giTag == WP_MORTAR ) {
					COM_BitSet( other->client->ps.weapons, WP_MORTAR_SET );
				} else if( ent->item->giTag == WP_MOBILE_MG42 ) {
					COM_BitSet( other->client->ps.weapons, WP_MOBILE_MG42_SET );
				} else if( ent->item->giTag == WP_CARBINE ) {
					COM_BitSet( other->client->ps.weapons, WP_M7 );
				} else if( ent->item->giTag == WP_KAR98 ) {
					COM_BitSet( other->client->ps.weapons, WP_GPG40 );
				}

				other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = 0;
				other->client->ps.ammo[BG_FindAmmoForWeapon(ent->item->giTag)] = 0;

				if( ent->item->giTag == WP_MORTAR ) {
					other->client->ps.ammo[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
					}
/*	quad: maybe make a g_weapons flag for this?
				} else if ((ent->item->giTag == WP_THOMPSON || ent->item->giTag == WP_MP40)) { // TODO: ???? (quad)
					// redeye - NQ style weapon switching with full ammo
					// note: I wrote this code before source of NQ was available, so this is less
					// good than NQ's implementation but still better than original ETPub
					int weap = BG_FindClipForWeapon(ent->item->giTag);
					int ammoweap = BG_FindAmmoForWeapon(ent->item->giTag);
					int max_ammo_per_clip = GetAmmoTableData(ammoweap)->maxclip;
					int ammo_in_clips = quantity - max_ammo_per_clip;

					if (quantity <= max_ammo_per_clip)
					{
						other->client->ps.ammoclip[weap] = quantity;
						other->client->ps.ammo[weap] = 0;
					}
					else
					{
						other->client->ps.ammoclip[weap] = max_ammo_per_clip;
						other->client->ps.ammo[weap] = ammo_in_clips;
					}
*/
				} else {
					other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						other->client->ps.ammo[ weapAlts[ ent->item->giTag ] ] = ent->delay;
					}
				}
			}
		} else {
			return 0;
		}
	}

	// TAT 1/6/2003 - If we are a bot, call the pickup function
#ifndef NO_BOT_SUPPORT
	if( other->r.svFlags & SVF_BOT )
		BotPickupWeapon( other->s.number, ent->item->giTag, alreadyHave );
#endif

	Bot_Event_AddWeapon(other->client->ps.clientNum, Bot_WeaponGameToBot(ent->item->giTag));
	return -1;
}
Ejemplo n.º 12
0
/**
* @brief Pick a weapon up.
*/
int Pickup_Weapon(gentity_t *ent, gentity_t *other)
{
	int      quantity;
	qboolean alreadyHave = qfalse;

	// magic ammo for any two-handed weapon
	if (ent->item->giTag == WP_AMMO)
	{
		AddMagicAmmo(other, ent->count);
		if (ent->parent && ent->parent->client)
		{
			other->client->pers.lastammo_client = ent->parent->s.clientNum;
		}

		// if LT isn't giving ammo to self or another LT or the enemy, give him some props
		if (other->client->ps.stats[STAT_PLAYER_CLASS] != PC_FIELDOPS)
		{
			if (ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam)
			{
				if (!(ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD))
				{
					AddScore(ent->parent, WOLF_AMMO_UP);
					if (ent->parent && ent->parent->client)
					{
						G_LogPrintf("Ammo_Pack: %d %d\n", (int)(ent->parent - g_entities), (int)(other - g_entities));
					}
				}
				ent->parent->client->PCSpecialPickedUpCount++;
				G_AddSkillPoints(ent->parent, SK_SIGNALS, 1.f);
				G_DebugAddSkillPoints(ent->parent, SK_SIGNALS, 1.f, "ammo pack picked up");

#ifdef FEATURE_OMNIBOT
				//omni-bot event
				if (ent->parent)
				{
					Bot_Event_RecievedAmmo(other - g_entities, ent->parent);
				}
#endif

				// extracted code originally here into AddMagicAmmo
				// add 1 clip of magic ammo for any two-handed weapon
			}
			return RESPAWN_NEVER;
		}
	}

	quantity = ent->count;

	// check if player already had the weapon
	alreadyHave = COM_BitCheck(other->client->ps.weapons, ent->item->giTag);

	// prevents drop/pickup weapon "quick reload" exploit
	if (alreadyHave)
	{
		Add_Ammo(other, ent->item->giTag, quantity, qfalse);

		// secondary weapon ammo
		if (ent->delay)
		{
			Add_Ammo(other, weaponTable[ent->item->giTag].weapAlts, ent->delay, qfalse);
		}
	}
	else
	{
		if (level.time - other->client->dropWeaponTime < 1000)
		{
			return 0;
		}

		// don't pick up when MG or mortar is set
		if (IS_MORTAR_WEAPON_SET(other->client->ps.weapon) || IS_MG_WEAPON_SET(other->client->ps.weapon))
		{
			return 0;
		}

		// see if we can pick it up
		if (G_CanPickupWeapon(ent->item->giTag, other))
		{
			weapon_t primaryWeapon;

			if (other->client->sess.playerType == PC_SOLDIER && other->client->sess.skill[SK_HEAVY_WEAPONS] >= 4)
			{
				primaryWeapon = G_GetPrimaryWeaponForClientSoldier(ent->item->giTag, other->client);
			}
			else
			{
				primaryWeapon = G_GetPrimaryWeaponForClient(other->client);
			}

			// added parens around ambiguous &&
			if (primaryWeapon)
			{
				// drop our primary weapon
				G_DropWeapon(other, primaryWeapon);

				// now pickup the other one
				other->client->dropWeaponTime = level.time;

				// add the weapon
				COM_BitSet(other->client->ps.weapons, ent->item->giTag);

				// fixup mauser/sniper issues
				switch (ent->item->giTag)
				{
				case WP_FG42:
					COM_BitSet(other->client->ps.weapons, WP_FG42SCOPE);
					break;
				case  WP_GARAND:
					COM_BitSet(other->client->ps.weapons, WP_GARAND_SCOPE);
					break;
				case  WP_K43:
					COM_BitSet(other->client->ps.weapons, WP_K43_SCOPE);
					break;
				case  WP_MORTAR:
					COM_BitSet(other->client->ps.weapons, WP_MORTAR_SET);
					break;
				case  WP_MORTAR2:
					COM_BitSet(other->client->ps.weapons, WP_MORTAR2_SET);
					break;
				case  WP_MOBILE_MG42:
					COM_BitSet(other->client->ps.weapons, WP_MOBILE_MG42_SET);
					break;
				case WP_MOBILE_BROWNING:
					COM_BitSet(other->client->ps.weapons, WP_MOBILE_BROWNING_SET);
					break;
				case  WP_CARBINE:
					COM_BitSet(other->client->ps.weapons, WP_M7);
					break;
				case WP_KAR98:
					COM_BitSet(other->client->ps.weapons, WP_GPG40);
					break;
				default:
					break;
				}

				other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = 0;
				other->client->ps.ammo[BG_FindAmmoForWeapon(ent->item->giTag)]     = 0;

				if (ent->item->giTag == WP_MORTAR || ent->item->giTag == WP_MORTAR2)
				{
					other->client->ps.ammo[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// secondary weapon ammo
					if (ent->delay)
					{
						Add_Ammo(other, weaponTable[ent->item->giTag].weapAlts, ent->delay, qfalse);
					}
				}
				else
				{
					other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// secondary weapon ammo
					if (ent->delay)
					{
						other->client->ps.ammo[weaponTable[ent->item->giTag].weapAlts] = ent->delay;
					}
				}
			}
		}
		else
		{
			return 0;
		}
	}

#ifdef FEATURE_OMNIBOT
	Bot_Event_AddWeapon(other->client->ps.clientNum, Bot_WeaponGameToBot(ent->item->giTag));
#endif

	return RESPAWN_NEVER;
}
Ejemplo n.º 13
0
void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, const vec3_t in_dir, vec3_t point, int damage, int dflags, int mod ) {
	gclient_t	*client;
	int			take;
	int			save;
	int			knockback;
	qboolean	wasAlive;
	hitRegion_t	hr = HR_NUM_HITREGIONS;
	int			limbo_health;

	limbo_health = FORCE_LIMBO_HEALTH;

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

	// the intermission has already been qualified for, so don't
	// allow any extra scoring
	// CHRUKER: b024 - Don't do damage if at warmup and warmupdamage is set to 'None' and the target is a client.
	if ( level.intermissionQueued || (cvars::gameState.ivalue != GS_PLAYING && match_warmupDamage.integer == 0 && targ->client)) {
		return;
	}

	if ( !inflictor ) {
		inflictor = &g_entities[ENTITYNUM_WORLD];
	}
	if ( !attacker ) {
		attacker = &g_entities[ENTITYNUM_WORLD];
	}

	// Arnout: invisible entities can't be damaged
	if( targ->entstate == STATE_INVISIBLE ||
		targ->entstate == STATE_UNDERCONSTRUCTION ) {
		return;
	}

	// xkan, 12/23/2002 - was the bot alive before applying any damage?
	wasAlive = (targ->health > 0) ? qtrue : qfalse;

	// Arnout: combatstate
	if( targ->client && attacker && attacker->client && attacker != targ ) {
		if( cvars::gameState.ivalue == GS_PLAYING ) {
			if( !OnSameTeam( attacker, targ ) ) {
				targ->client->combatState = (combatstate_t)( targ->client->combatState | (1<<COMBATSTATE_DAMAGERECEIVED) );
				attacker->client->combatState = (combatstate_t)( attacker->client->combatState | (1<<COMBATSTATE_DAMAGEDEALT) );
			}
		}
	}

    // JPW NERVE
    if ((targ->waterlevel >= 3) && (mod == MOD_FLAMETHROWER))
        return;
    // jpw

	// shootable doors / buttons don't actually have any health
	if ( targ->s.eType == ET_MOVER && !(targ->isProp) && !targ->scriptName) {
		if ( targ->use && targ->moverState == MOVER_POS1 ) {
			G_UseEntity( targ, inflictor, attacker );
		}
		return;
	}

	// TAT 11/22/2002
	//		In the old code, this check wasn't done for props, so I put that check back in to make props_statue properly work	
	// 4 means destructible
	if ( targ->s.eType == ET_MOVER && (targ->spawnflags & 4) && !targ->isProp ) 
	{
		if( !G_WeaponIsExplosive( (meansOfDeath_t)mod ) ) {
			return;
		}

		// check for team
		if( G_GetTeamFromEntity( inflictor ) == G_GetTeamFromEntity( targ ) ) {
			return;
		}
	} else if ( targ->s.eType == ET_EXPLOSIVE ) {
		if( targ->parent && G_GetWeaponClassForMOD( (meansOfDeath_t)mod ) == 2 ) {
			return;
		}

		if( G_GetTeamFromEntity( inflictor ) == G_GetTeamFromEntity( targ ) ) {
			return;
		}

		if( G_GetWeaponClassForMOD( (meansOfDeath_t)mod ) < targ->constructibleStats.weaponclass ) {
			return;
		}
	}
	else if ( targ->s.eType == ET_MISSILE && targ->methodOfDeath == MOD_LANDMINE ) {
		if( targ->s.modelindex2 ) {
			if( G_WeaponIsExplosive( (meansOfDeath_t)mod ) ) {
				mapEntityData_t	*mEnt;

				if((mEnt = G_FindMapEntityData(&mapEntityData[0], targ-g_entities)) != NULL) {
					G_FreeMapEntityData( &mapEntityData[0], mEnt );
				}

				if((mEnt = G_FindMapEntityData(&mapEntityData[1], targ-g_entities)) != NULL) {
					G_FreeMapEntityData( &mapEntityData[1], mEnt );
				}

				if( attacker && attacker->client ) {
					AddScore( attacker, 1 );
				}

				G_ExplodeMissile(targ);
			}
		}
		return;
	} else if ( targ->s.eType == ET_CONSTRUCTIBLE ) {

		if( G_GetTeamFromEntity( inflictor ) == G_GetTeamFromEntity( targ ) ) {
			return;
		}

		if( G_GetWeaponClassForMOD( (meansOfDeath_t)mod ) < targ->constructibleStats.weaponclass ) {
			return;
		}
		//bani - fix #238
		if ( mod == MOD_DYNAMITE ) {
			if( !( inflictor->etpro_misc_1 & 1 ) )
				return;
		}
	}

	client = targ->client;

	if ( client ) {
		if ( client->noclip || ( client->ps.powerups[PW_INVULNERABLE] && !( dflags & DAMAGE_JAY_NO_PROTECTION ))) {
			return;
		}
	}

	// check for godmode
	if ( targ->flags & FL_GODMODE ) {
		return;
	}

    // ugly-ass code but we do this to make in_dir read-only
    vec3_t dir;

	if ( !in_dir ) {
		dflags |= DAMAGE_NO_KNOCKBACK;
	} else {
        VectorCopy( in_dir, dir );
		VectorNormalize( dir );
	}

	knockback = damage;
	if ( knockback > 200 ) {
		knockback = 200;
	}
	if ( targ->flags & FL_NO_KNOCKBACK ) {
		knockback = 0;
	}
	if ( dflags & DAMAGE_NO_KNOCKBACK ) {
		knockback = 0;
	} else if( dflags & DAMAGE_HALF_KNOCKBACK ) {
		knockback = int( knockback * 0.5f );
	}
	
	// ydnar: set weapons means less knockback
	if( client && (client->ps.weapon == WP_MORTAR_SET || client->ps.weapon == WP_MOBILE_MG42_SET) )
		knockback = int( knockback * 0.5f );

	if( targ->client && g_friendlyFire.integer && OnSameTeam(targ, attacker) ) {
		knockback = 0;
	}
	
	// figure momentum add, even if the damage won't be taken
	if ( knockback && targ->client ) {
		vec3_t	kvel;
		float	mass;

		mass = 200;

		VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
		VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);

        // From NoQuarter, I'm not sure I need this
		if ( attacker && attacker->client && ( targ->client->ps.groundEntityNum != ENTITYNUM_NONE || G_WeaponIsExplosive((meansOfDeath_t)mod) )){
			targ->client->pmext.wasShoved = qtrue;
			targ->client->pmext.shover = attacker - g_entities;
		}

		if (targ == attacker && !(	mod != MOD_ROCKET &&
									mod != MOD_GRENADE &&
									mod != MOD_GRENADE_LAUNCHER &&
									mod != MOD_DYNAMITE
									&& mod != MOD_GPG40
									&& mod != MOD_M7
									&& mod != MOD_LANDMINE
									))
		{
			targ->client->ps.velocity[2] *= 0.25;
		}

		// set the timer so that the other client can't cancel
		// out the movement immediately
		if ( !targ->client->ps.pm_time ) {
			int		t;

			t = knockback * 2;
			if ( t < 50 ) {
				t = 50;
			}
			if ( t > 200 ) {
				t = 200;
			}
			targ->client->ps.pm_time = t;
			targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
		}
	}

    // skip damage if friendly fire is disabled
    if (!(dflags & DAMAGE_NO_PROTECTION)
        && targ != attacker
        && OnSameTeam( targ, attacker )
        && !g_friendlyFire.integer)
    {
        return;
    }

	if (damage < 1)
		damage = 1;

	take = damage;
	save = 0;

	if ( attacker->client && targ->client && targ != attacker && targ->health > 0 ) {
		// Jaybird - Hitsounds
		// vsay "hold your fire" on the first hit of a teammate
		// only applies if the player has been hurt before
		// and the match is not in warmup.
		if( OnSameTeam( targ, attacker )) {
			if(( !client->lasthurt_mod || client->lasthurt_client != attacker->s.number ) && cvars::gameState.ivalue == GS_PLAYING && ( targ->health - take ) > limbo_health ) {
				if( client->sess.sessionTeam == TEAM_AXIS )
					G_ClientSound( attacker, "sound/chat/axis/26a.wav" );
				else	
					G_ClientSound( attacker, "sound/chat/allies/26a.wav" );
			}

			if (mod != MOD_GOOMBA && mod != MOD_POISON_SYRINGE) {
				g_clientObjects[attacker->s.number].recordHit( AbstractHitVolume::ZONE_BODY, true );
			}
		} else {
			if (mod != MOD_GOOMBA && mod != MOD_POISON_SYRINGE) {
				g_clientObjects[attacker->s.number].recordHit( AbstractHitVolume::ZONE_BODY, false );
			}
		}
	}

	// adrenaline junkie!
	if( targ->client && targ->client->ps.powerups[PW_ADRENALINE] ) {
		take = int( take * 0.5f );
	}

	// save some from flak jacket
	// Jaybird - engineer class carryover
	if( targ->client && targ->client->sess.skill[SK_EXPLOSIVES_AND_CONSTRUCTION] >= 4 && ( targ->client->sess.playerType == PC_ENGINEER || ( cvars::bg_skills.ivalue & SBS_ENGI ))) {
		if( mod == MOD_GRENADE ||
			mod == MOD_GRENADE_LAUNCHER ||
			mod == MOD_ROCKET ||
			mod == MOD_GRENADE_PINEAPPLE ||
			mod == MOD_MAPMORTAR ||
			mod == MOD_MAPMORTAR_SPLASH || 
			mod == MOD_EXPLOSIVE ||
			mod == MOD_LANDMINE ||
			mod == MOD_GPG40 ||
			mod == MOD_M7 ||
			mod == MOD_SATCHEL ||
			mod == MOD_ARTY ||
			mod == MOD_AIRSTRIKE ||
			mod == MOD_DYNAMITE ||
			mod == MOD_MORTAR ||
			mod == MOD_PANZERFAUST ||
			mod == MOD_MAPMORTAR ) {
			take -= int( take * 0.5f );
		}
	}

#ifndef DEBUG_STATS
	if ( g_debugDamage.integer )
#endif
	{
		G_Printf( "client:%i health:%i damage:%i mod:%s\n", targ->s.number, targ->health, take, modNames[mod] );
	}

	if( targ && targ->client && attacker && attacker->client && targ != attacker && targ->health > 0 && OnSameTeam( targ, attacker ) && g_friendlyFire.integer == 2 && IsReflectable( mod )) {
		int ffDamage;

		// Percentage based reflect
		ffDamage = int( take * g_reflectFriendlyFire.value / 100.f );
		if( ffDamage <= 0 ) {
			ffDamage = 0;
		}
		attacker->health -= ffDamage;

		// Give them pain!
		attacker->client->damage_blood += take;
		attacker->client->damage_knockback += knockback;

		// Set the lasthurt stuff so hitsounds do not replay
		targ->client->lasthurt_mod = mod;
		targ->client->lasthurt_client = attacker - g_entities;

		// Kill the player if necessary
		if( attacker->health <= 0 ) {
			attacker->deathType = MOD_REFLECTED_FF;
			attacker->enemy = attacker;
			if( attacker->die ) {
				attacker->die( attacker, attacker, attacker, ffDamage, MOD_REFLECTED_FF );
			}
		}
	}

	// 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 ) {
		if ( attacker ) {
			client->ps.persistant[PERS_ATTACKER] = attacker->s.number;
		} else {
			client->ps.persistant[PERS_ATTACKER] = ENTITYNUM_WORLD;
		}
		client->damage_blood += take;
		client->damage_knockback += knockback;

		if ( dir ) {
			VectorCopy ( dir, client->damage_from );
			client->damage_fromWorld = qfalse;
		} else {
			VectorCopy ( targ->r.currentOrigin, client->damage_from );
			client->damage_fromWorld = qtrue;
		}
	}

	// See if it's the player hurting the emeny flag carrier
//	Team_CheckHurtCarrier(targ, attacker);

	if (targ->client) {
		// set the last client who damaged the target
		targ->client->lasthurt_client = attacker->s.number;
		targ->client->lasthurt_mod = mod;
		targ->client->lasthurt_time = level.time;
	}

	// do the damage
	if( take ) {
		targ->health -= take;

		// Gordon: don't ever gib POWS
		if( ( targ->health <= 0 ) && ( targ->r.svFlags & SVF_POW ) ) {
			targ->health = -1;
		}

		// Ridah, can't gib with bullet weapons (except VENOM)
		// Arnout: attacker == inflictor can happen in other cases as well! (movers trying to gib things)
		//if ( attacker == inflictor && targ->health <= GIB_HEALTH) {
		if( targ->health <= GIB_HEALTH ) {
			if( !G_WeaponIsExplosive( (meansOfDeath_t)mod ) ) {
				targ->health = GIB_HEALTH + 1;
			}
		}

		if( g_damagexp.integer && client && G_GetTeamFromEntity( inflictor ) != G_GetTeamFromEntity( targ )) {
			// Jaybird - give them some per hit
			// They get 1 XP per 50 damage, so multiple .02 * take
			int skill = G_SkillForMOD( mod );
			if( skill >= 0 )
				G_AddSkillPoints( attacker, (skillType_t)skill, take * .02 );
		}

// JPW NERVE overcome previous chunk of code for making grenades work again
//		if ((take > 190)) // 190 is greater than 2x mauser headshot, so headshots don't gib
		// Arnout: only player entities! messes up ents like func_constructibles and func_explosives otherwise
		if( ( (targ->s.number < MAX_CLIENTS) && (take > 190) ) && !(targ->r.svFlags & SVF_POW) ) {
			targ->health = GIB_HEALTH - 1;
		}

		if( targ->s.eType == ET_MOVER && !Q_stricmp( targ->classname, "script_mover" ) ) {
			targ->s.dl_intensity = int( 255.f * (targ->health / (float)targ->count) );	// send it to the client
		}

		//G_Printf("health at: %d\n", targ->health);
		if( targ->health <= 0 ) {
			if( client && !wasAlive ) {
				targ->flags |= FL_NO_KNOCKBACK;
				// OSP - special hack to not count attempts for body gibbage
				if( targ->client->ps.pm_type == PM_DEAD ) {
					G_addStats(targ, attacker, take, mod);
				}

				if( (targ->health < FORCE_LIMBO_HEALTH) && (targ->health > GIB_HEALTH) ) {
					limbo(targ, qtrue);
				}
				// xkan, 1/13/2003 - record the time we died.
				if (!client->deathTime)
					client->deathTime = level.time;

				//bani - #389
				if( targ->health <= GIB_HEALTH ) {
					GibEntity( targ, 0 );
				}
			} else {
				targ->sound1to2 = hr;
				targ->sound2to1 = mod;
				targ->sound2to3 = (dflags & DAMAGE_RADIUS) ? 1 : 0;

				if( client ) {
					if( G_GetTeamFromEntity( inflictor ) != G_GetTeamFromEntity( targ ) ) {
						G_AddKillSkillPoints( attacker, (meansOfDeath_t)mod, hr, (qboolean)(dflags & DAMAGE_RADIUS)  );
					}
				}

				if( targ->health < -999 ) {
					targ->health = -999;
				}


				targ->enemy = attacker;
				targ->deathType = (meansOfDeath_t)mod;

				// Ridah, mg42 doesn't have die func (FIXME)
				if( targ->die ) {	
					// Kill the entity.  Note that this funtion can set ->die to another
					// function pointer, so that next time die is applied to the dead body.
					targ->die( targ, inflictor, attacker, take, mod );
					// OSP - kill stats in player_die function
				}

				if( targ->s.eType == ET_MOVER && !Q_stricmp( targ->classname, "script_mover" ) && (targ->spawnflags & 8) ) {
					return;	// reseructable script mover doesn't unlink itself but we don't want a second death script to be called
				}

				// if we freed ourselves in death function
				if (!targ->inuse)
					return;

				// RF, entity scripting
				if ( targ->health <= 0) {	// might have revived itself in death function
					if( targ->r.svFlags & SVF_BOT ) {
                        // Removed
					} else if(	( targ->s.eType != ET_CONSTRUCTIBLE && targ->s.eType != ET_EXPLOSIVE ) ||
								( targ->s.eType == ET_CONSTRUCTIBLE && !targ->desstages ) )	{ // call manually if using desstages
						G_Script_ScriptEvent( targ, "death", "" );
					}
				}
			}

		} else if ( targ->pain ) {
			if (dir) {	// Ridah, had to add this to fix NULL dir crash
				VectorCopy (dir, targ->rotate);
				VectorCopy (point, targ->pos3); // this will pass loc of hit
			} else {
				VectorClear( targ->rotate );
				VectorClear( targ->pos3 );
			}

			targ->pain (targ, attacker, take, point);
		} else {
			// OSP - update weapon/dmg stats
			G_addStats(targ, attacker, take, mod);
			// OSP
		}

		// RF, entity scripting
		G_Script_ScriptEvent( targ, "pain", va("%d %d", targ->health, targ->health+take) );

		// RF, record bot pain
		if (targ->s.number < level.maxclients)
		{
			// notify omni-bot framework
			Bot_Event_TakeDamage(targ-g_entities, attacker);
		}

		// Ridah, this needs to be done last, incase the health is altered in one of the event calls
		// Jaybird - playdead check
		if ( targ->client ) {
			targ->client->ps.stats[STAT_HEALTH] = targ->health;
		}

        // Cheap way to ID inflictor entity as poison smoke.
		if (inflictor->poisonGasAlarm && mod == MOD_POISON_GAS && targ->health >= 0)
			G_AddEvent(targ, EV_COUGH, 0);
	}
}
Ejemplo n.º 14
0
/**
 * @brief Pick a weapon up.
 * @param[in,out] ent
 * @param[in,out] other
 * @return
 */
int Pickup_Weapon(gentity_t *ent, gentity_t *other)
{
	int      quantity;
	qboolean alreadyHave = qfalse;

	// magic ammo for any two-handed weapon
	if (ent->item->giWeapon == WP_AMMO)
	{
		AddMagicAmmo(other, ent->count);
		if (ent->parent && ent->parent->client)
		{
			other->client->pers.lastammo_client = ent->parent->s.clientNum;
		}

		// if field ops isn't giving ammo to self or the enemy, give him some props
		if (ent->parent && (ent->parent->client != other->client))
		{
			if (ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam)
			{
				G_AddSkillPoints(ent->parent, SK_SIGNALS, 1.f);
				G_DebugAddSkillPoints(ent->parent, SK_SIGNALS, 1.f, "ammo pack picked up");

#ifdef FEATURE_OMNIBOT
				//omni-bot event
				if (ent->parent)
				{
					Bot_Event_RecievedAmmo(other - g_entities, ent->parent);
				}
#endif
				// extracted code originally here into AddMagicAmmo
				// add 1 clip of magic ammo for any two-handed weapon
			}
			return RESPAWN_NEVER;
		}
	}

	quantity = ent->count;

	// check if player already had the weapon
	alreadyHave = COM_BitCheck(other->client->ps.weapons, ent->item->giWeapon);

	// prevents drop/pickup weapon "quick reload" exploit
	if (alreadyHave)
	{
		Add_Ammo(other, ent->item->giWeapon, quantity, qfalse);

		// secondary weapon ammo
		if (ent->delay != 0.f)
		{
			Add_Ammo(other, GetWeaponTableData(ent->item->giWeapon)->weapAlts, ent->delay, qfalse);
		}
	}
	else
	{
		if (level.time - other->client->dropWeaponTime < 1000)
		{
			return 0;
		}

		// don't pick up when MG or mortar is set
		if (GetWeaponTableData(other->client->ps.weapon)->isSetWeapon)
		{
			return 0;
		}

		// see if we can pick it up
		if (G_CanPickupWeapon(ent->item->giWeapon, other))
		{
			weapon_t primaryWeapon;

			if (other->client->sess.playerType == PC_SOLDIER && other->client->sess.skill[SK_HEAVY_WEAPONS] >= 4)
			{
				primaryWeapon = G_GetPrimaryWeaponForClientSoldier(ent->item->giWeapon, other->client);
			}
			else
			{
				primaryWeapon = G_GetPrimaryWeaponForClient(other->client);
			}

			// added parens around ambiguous &&
			if (primaryWeapon)
			{
				// drop our primary weapon
				G_DropWeapon(other, primaryWeapon);

				// now pickup the other one
				other->client->dropWeaponTime = level.time;

				// add the weapon
				COM_BitSet(other->client->ps.weapons, ent->item->giWeapon);

				// fixup mauser/sniper issues
				if (GetWeaponTableData(ent->item->giWeapon)->weapAlts != WP_NONE)
				{
					weapon_t weapAlts = GetWeaponTableData(ent->item->giWeapon)->weapAlts;

					if (GetWeaponTableData(weapAlts)->isRiflenade || GetWeaponTableData(weapAlts)->isScoped || GetWeaponTableData(weapAlts)->isSetWeapon)
					{
						COM_BitSet(other->client->ps.weapons, weapAlts);
					}
				}

				other->client->ps.ammoclip[GetWeaponTableData(ent->item->giWeapon)->clipIndex] = 0;
				other->client->ps.ammo[GetWeaponTableData(ent->item->giWeapon)->ammoIndex]     = 0;

				if (GetWeaponTableData(ent->item->giWeapon)->isMortar)
				{
					other->client->ps.ammo[GetWeaponTableData(ent->item->giWeapon)->clipIndex] = quantity;

					// secondary weapon ammo
					if (ent->delay != 0.f)
					{
						Add_Ammo(other, GetWeaponTableData(ent->item->giWeapon)->weapAlts, ent->delay, qfalse);
					}
				}
				else
				{
					other->client->ps.ammoclip[GetWeaponTableData(ent->item->giWeapon)->clipIndex] = quantity;

					// secondary weapon ammo
					if (ent->delay != 0.f)
					{
						other->client->ps.ammo[GetWeaponTableData(ent->item->giWeapon)->weapAlts] = ent->delay;
					}
				}
			}
		}
		else
		{
			return 0;
		}
	}

#ifdef FEATURE_OMNIBOT
	Bot_Event_AddWeapon(other->client->ps.clientNum, Bot_WeaponGameToBot(ent->item->giWeapon));
#endif

	return RESPAWN_NEVER;
}
Ejemplo n.º 15
0
void G_CheckSpottedLandMines(void)
{
	int       i, j;
	gentity_t *ent, *ent2;

	if (level.time - level.lastMapSpottedMinesUpdate < 500)
	{
		return;
	}
	level.lastMapSpottedMinesUpdate = level.time;

	for (i = 0; i < level.numConnectedClients; i++)
	{
		ent = &g_entities[level.sortedClients[i]];

		if (!ent->inuse || !ent->client)
		{
			continue;
		}

		if (ent->health <= 0)
		{
			continue;
		}

		// must be in a valid team
		if (ent->client->sess.sessionTeam == TEAM_SPECTATOR || ent->client->sess.sessionTeam == TEAM_FREE)
		{
			continue;
		}

		if (ent->client->ps.pm_flags & PMF_LIMBO)
		{
			continue;
		}

		if (ent->client->sess.playerType == PC_COVERTOPS && (ent->client->ps.eFlags & EF_ZOOMING))
		{
			G_SetupFrustum_ForBinoculars(ent);

			for (j = 0, ent2 = g_entities; j < level.num_entities; j++, ent2++)
			{
				if (!ent2->inuse || ent2 == ent)
				{
					continue;
				}

				if (ent2->s.eType != ET_MISSILE)
				{
					continue;
				}

				if (ent2->methodOfDeath == MOD_LANDMINE)
				{
					if ((ent2->s.teamNum < 4 || ent2->s.teamNum >= 8) && (ent2->s.teamNum % 4 != ent->client->sess.sessionTeam))
					{
						// as before, we can only detect a mine if we can see it from our binoculars
						if (G_VisibleFromBinoculars(ent, ent2, ent2->r.currentOrigin))
						{
							G_UpdateTeamMapData_LandMine(ent2);

							switch (ent2->s.teamNum % 4)
							{
							case TEAM_AXIS:
							case TEAM_ALLIES:
								if (!ent2->s.modelindex2)
								{
									ent->client->landmineSpottedTime = level.time;
									ent->client->landmineSpotted     = ent2;
									ent2->s.density                  = ent - g_entities + 1;
									ent2->missionLevel               = level.time;

									ent->client->landmineSpotted->count2 += 50; // @sv_fps
									if (ent->client->landmineSpotted->count2 >= 250)
									{
										ent->client->landmineSpotted->count2 = 250;

										ent->client->landmineSpotted->s.modelindex2 = 1;

										// for marker
										// Landmine flags shouldn't block our view
										// don't do this if the mine has been triggered.
										if (!G_LandmineTriggered(ent->client->landmineSpotted))
										{
											ent->client->landmineSpotted->s.frame    = rand() % 20;
											ent->client->landmineSpotted->r.contents = CONTENTS_TRANSLUCENT;
											trap_LinkEntity(ent->client->landmineSpotted);
										}

										G_PopupMessageForMines(ent);

										trap_SendServerCommand(ent - g_entities, "cp \"Landmine Revealed\n\"");

										AddScore(ent, 1);

										G_AddSkillPoints(ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f);
										G_DebugAddSkillPoints(ent, SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS, 3.f, "spotting a landmine");
									}
								}
								break;
							default:
								break;
							}
						}
						else
						{
							// if we can't see the mine from our binoculars, make sure we clear out the landmineSpotted ptr,
							// because bots looking for mines are getting confused
							ent->client->landmineSpotted = NULL;
						}
					}
				}
			}
		}
	}
}