Exemplo n.º 1
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;
}
Exemplo n.º 2
0
void G_DropWeapon( gentity_t *ent, weapon_t weapon )
{
	vec3_t		angles, velocity, org, offset, mins, maxs;
	gclient_t	*client = ent->client;
	gentity_t	*ent2;
	gitem_t		*item;
	trace_t		tr;

	item = BG_FindItemForWeapon( weapon );
	VectorCopy( client->ps.viewangles, angles );

	// clamp pitch
	if ( angles[PITCH] < -30 )
		angles[PITCH] = -30;
	else if ( angles[PITCH] > 30 )
		angles[PITCH] = 30;

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 64, offset );
	offset[2] += client->ps.viewheight / 2.f;
	VectorScale( velocity, 75, velocity );
	velocity[2] += 50 + random() * 35;

	VectorAdd( client->ps.origin, offset, org );

	VectorSet( mins, -ITEM_RADIUS, -ITEM_RADIUS, 0 );
	VectorSet( maxs, ITEM_RADIUS, ITEM_RADIUS, 2*ITEM_RADIUS );

	trap_Trace( &tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID );
	VectorCopy( tr.endpos, org );

	ent2 = LaunchItem( item, org, velocity, client->ps.clientNum );
	COM_BitClear( client->ps.weapons, weapon );

	if( weapon == WP_KAR98 ) {
		COM_BitClear( client->ps.weapons, WP_GPG40 );
	} else if ( weapon == WP_CARBINE ) {
		COM_BitClear( client->ps.weapons, WP_M7 );
	} else if ( weapon == WP_FG42 ) {
		COM_BitClear( client->ps.weapons, WP_FG42SCOPE );
	} else if( weapon == WP_K43 ) {
		COM_BitClear( client->ps.weapons, WP_K43_SCOPE );
	} else if( weapon == WP_GARAND ) {
		COM_BitClear( client->ps.weapons, WP_GARAND_SCOPE );
	} else if( weapon == WP_MORTAR ) {
		COM_BitClear( client->ps.weapons, WP_MORTAR_SET );
	} else if( weapon == WP_MOBILE_MG42 ) {
		COM_BitClear( client->ps.weapons, WP_MOBILE_MG42_SET );
	}

	if( weapon == WP_GPG40 ) { // etace
		COM_BitClear( client->ps.weapons, WP_KAR98 );
	} else if ( weapon == WP_M7 ) {
		COM_BitClear( client->ps.weapons, WP_CARBINE );
	} else if ( weapon == WP_FG42SCOPE ) {
		COM_BitClear( client->ps.weapons, WP_FG42 );
	} else if( weapon == WP_K43_SCOPE ) {
		COM_BitClear( client->ps.weapons, WP_K43 );
	} else if( weapon == WP_GARAND_SCOPE ) {
		COM_BitClear( client->ps.weapons, WP_GARAND );
	} else if( weapon == WP_MORTAR_SET ) {
		COM_BitClear( client->ps.weapons, WP_MORTAR );
	} else if( weapon == WP_MOBILE_MG42_SET ) {
		COM_BitClear( client->ps.weapons, WP_MOBILE_MG42 );
	}

	// Clear out empty weapon, change to next best weapon
	G_AddEvent( ent, EV_WEAPONSWITCHED, 1 );

	if( weapon == client->ps.weapon )
		client->ps.weapon = 0;

	if( weapon == WP_MORTAR ) {
		ent2->count = client->ps.ammo[BG_FindAmmoForWeapon(weapon)] + client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
/* quad: maybe make a g_weapons flag for this?!?
	} else if (weapon == WP_MP40 || weapon == WP_THOMPSON) {
		// redeye - NQ style weapon switching with full ammo
		ent2->count = client->ps.ammo[BG_FindAmmoForWeapon(weapon)] + client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
*/
	} else {
		ent2->count = client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	}

	if( weapon == WP_KAR98 || weapon == WP_CARBINE ) {
		ent2->delay = client->ps.ammo[BG_FindAmmoForWeapon(weapAlts[weapon])];
	} else {
		ent2->delay = 0;
	}

//	ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon(weapon)]; // Gordon: um, modifying an item is not a good idea
	client->ps.ammoclip[BG_FindClipForWeapon(weapon)] = 0;

	Bot_Event_RemoveWeapon(client->ps.clientNum, Bot_WeaponGameToBot(weapon));
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/**
* @brief Drop weapon.
*/
void G_DropWeapon(gentity_t *ent, weapon_t weapon)
{
	vec3_t    angles, velocity, org, offset, mins, maxs;
	gclient_t *client = ent->client;
	gentity_t *ent2;
	gitem_t   *item;
	trace_t   tr;

	if (!IS_VALID_WEAPON(weapon))
	{
		return;
	}

	item = BG_FindItemForWeapon(weapon);
	VectorCopy(client->ps.viewangles, angles);

	// clamp pitch
	if (angles[PITCH] < -30)
	{
		angles[PITCH] = -30;
	}
	else if (angles[PITCH] > 30)
	{
		angles[PITCH] = 30;
	}

	AngleVectors(angles, velocity, NULL, NULL);
	VectorScale(velocity, 64, offset);
	offset[2] += client->ps.viewheight / 2.f;
	VectorScale(velocity, 75, velocity);
	velocity[2] += 50 + random() * 35;

	VectorAdd(client->ps.origin, offset, org);

	VectorSet(mins, -ITEM_RADIUS, -ITEM_RADIUS, 0);
	VectorSet(maxs, ITEM_RADIUS, ITEM_RADIUS, 2 * ITEM_RADIUS);

	trap_Trace(&tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID);
	VectorCopy(tr.endpos, org);

	ent2 = LaunchItem(item, org, velocity, client->ps.clientNum);
	COM_BitClear(client->ps.weapons, weapon);

	switch (weapon)
	{
	case WP_KAR98:
		COM_BitClear(client->ps.weapons, WP_GPG40);
		break;
	case WP_CARBINE:
		COM_BitClear(client->ps.weapons, WP_M7);
		break;
	case WP_FG42:
		COM_BitClear(client->ps.weapons, WP_FG42SCOPE);
		break;
	case WP_K43:
		COM_BitClear(client->ps.weapons, WP_K43_SCOPE);
		break;
	case WP_GARAND:
		COM_BitClear(client->ps.weapons, WP_GARAND_SCOPE);
		break;
	case WP_MORTAR:
		COM_BitClear(client->ps.weapons, WP_MORTAR_SET);
		break;
	case WP_MORTAR2:
		COM_BitClear(client->ps.weapons, WP_MORTAR2_SET);
		break;
	case WP_MOBILE_MG42:
		COM_BitClear(client->ps.weapons, WP_MOBILE_MG42_SET);
		break;
	case WP_MOBILE_BROWNING:
		COM_BitClear(client->ps.weapons, WP_MOBILE_BROWNING_SET);
		break;
	default:
		break;
	}

	// Clear out empty weapon, change to next best weapon
	G_AddEvent(ent, EV_WEAPONSWITCHED, 0);

	if (weapon == client->ps.weapon)
	{
		client->ps.weapon = 0;
	}

	if (IS_MORTAR_WEAPON_SET(weapon))
	{
		ent2->count = client->ps.ammo[BG_FindAmmoForWeapon(weapon)] + client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	}
	else
	{
		ent2->count = client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	}

	if (weapon == WP_KAR98 || weapon == WP_CARBINE)
	{
		ent2->delay = client->ps.ammo[BG_FindAmmoForWeapon(weaponTable[weapon].weapAlts)];
	}
	else
	{
		ent2->delay = 0;
	}

	//  ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon(weapon)]; // um, modifying an item is not a good idea
	client->ps.ammoclip[BG_FindClipForWeapon(weapon)] = 0;

#ifdef FEATURE_OMNIBOT
	Bot_Event_RemoveWeapon(client->ps.clientNum, Bot_WeaponGameToBot(weapon));
#endif
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
/**
 * @brief Drop Weapon
 * @param[in] ent
 * @param[in] weapon
 */
void G_DropWeapon(gentity_t *ent, weapon_t weapon)
{
	vec3_t    angles, velocity, org, offset, mins, maxs;
	gclient_t *client = ent->client;
	gentity_t *ent2;
	gitem_t   *item;
	trace_t   tr;

	if (!IS_VALID_WEAPON(weapon))
	{
		return;
	}

	item = BG_FindItemForWeapon(weapon);
	VectorCopy(client->ps.viewangles, angles);

	// clamp pitch
	if (angles[PITCH] < -30)
	{
		angles[PITCH] = -30;
	}
	else if (angles[PITCH] > 30)
	{
		angles[PITCH] = 30;
	}

	AngleVectors(angles, velocity, NULL, NULL);
	VectorScale(velocity, 64, offset);
	offset[2] += client->ps.viewheight / 2.f;
	VectorScale(velocity, 75, velocity);
	velocity[2] += 50 + random() * 35;

	VectorAdd(client->ps.origin, offset, org);

	VectorSet(mins, -ITEM_RADIUS, -ITEM_RADIUS, 0);
	VectorSet(maxs, ITEM_RADIUS, ITEM_RADIUS, 2 * ITEM_RADIUS);

	trap_Trace(&tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID);
	VectorCopy(tr.endpos, org);

	ent2 = LaunchItem(item, org, velocity, client->ps.clientNum);
	COM_BitClear(client->ps.weapons, weapon);

	if (GetWeaponTableData(weapon)->weapAlts != WP_NONE)
	{
		weapon_t weapAlts = GetWeaponTableData(weapon)->weapAlts;

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

	// Clear out empty weapon, change to next best weapon
	G_AddEvent(ent, EV_WEAPONSWITCHED, 0);

	if (weapon == client->ps.weapon)
	{
		client->ps.weapon = 0;
	}

	if (GetWeaponTableData(weapon)->isMortarSet)
	{
		ent2->count = client->ps.ammo[GetWeaponTableData(weapon)->ammoIndex] + client->ps.ammoclip[GetWeaponTableData(weapon)->clipIndex];
	}
	else
	{
		ent2->count = client->ps.ammoclip[GetWeaponTableData(weapon)->clipIndex];
	}

	if (weapon == WP_KAR98 || weapon == WP_CARBINE)
	{
		ent2->delay = client->ps.ammo[GetWeaponTableData(GetWeaponTableData(weapon)->weapAlts)->ammoIndex];
	}
	else
	{
		ent2->delay = 0;
	}

	//  ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon(weapon)]; // um, modifying an item is not a good idea
	client->ps.ammoclip[GetWeaponTableData(weapon)->clipIndex] = 0;

#ifdef FEATURE_OMNIBOT
	Bot_Event_RemoveWeapon(client->ps.clientNum, Bot_WeaponGameToBot(weapon));
#endif
}