Ejemplo n.º 1
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
}
Ejemplo n.º 2
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.º 3
0
void CG_DrawMortarMarker(int px, int py, int pw, int ph, qboolean draw, mapScissor_t *scissor, int expand)
{
	if (IS_MORTAR_WEAPON_SET(cg.lastFiredWeapon) && cg.mortarImpactTime >= 0)
	{
		if (cg.snap->ps.weapon != WP_MORTAR_SET && cg.snap->ps.weapon != WP_MORTAR2_SET)
		{
			cg.mortarImpactTime = 0;
		}
		else
		{
			vec4_t colour = { 1.f, 1.f, 1.f, 1.f };
			vec3_t point;

			if (scissor)
			{
				point[0] = ((cg.mortarImpactPos[0] - cg.mapcoordsMins[0]) * cg.mapcoordsScale[0]) * pw * scissor->zoomFactor;
				point[1] = ((cg.mortarImpactPos[1] - cg.mapcoordsMins[1]) * cg.mapcoordsScale[1]) * ph * scissor->zoomFactor;
			}
			else
			{
				point[0] = px + (((cg.mortarImpactPos[0] - cg.mapcoordsMins[0]) * cg.mapcoordsScale[0]) * pw);
				point[1] = py + (((cg.mortarImpactPos[1] - cg.mapcoordsMins[1]) * cg.mapcoordsScale[1]) * ph);
			}

			// don't return if the marker is culled, just don't draw it
			if (!(scissor && CG_ScissorPointIsCulled(point, scissor)))
			{
				if (scissor)
				{
					point[0] += px - scissor->tl[0];
					point[1] += py - scissor->tl[1];
				}

				if (cg.mortarImpactOutOfMap)
				{
					if (!scissor)
					{
						// near the edge of the map, fit into it
						if (point[0] + 8.f > (px + pw))
						{
							point[0] -= 8.f;
						}
						else if (point[0] - 8.f < px)
						{
							point[0] += 8.f;
						}

						if (point[1] + 8.f > (py + ph))
						{
							point[1] -= 8.f;
						}
						else if (point[1] - 8.f < py)
						{
							point[1] += 8.f;
						}
					}
					colour[3] = .5f;
				}

				trap_R_SetColor(colour);
				CG_DrawRotatedPic(point[0] - 8.f, point[1] - 8.f, 16, 16, cgs.media.ccMortarHit, .5f - (cg.mortarFireAngles[YAW] /*- 180.f */ + 45.f) / 360.f);
				trap_R_SetColor(NULL);
			}
		}
	}

	if (COM_BitCheck(cg.snap->ps.weapons, WP_MORTAR_SET) || COM_BitCheck(cg.snap->ps.weapons, WP_MORTAR2_SET))
	{
		vec4_t colour = { 1.f, 1.f, 1.f, 1.f };
		vec3_t point;
		int    i, fadeTime;

		for (i = 0; i < cgs.maxclients; i++)
		{
			fadeTime = cg.time - (cg.artilleryRequestTime[i] + 25000);

			if (fadeTime < 5000)
			{
				if (fadeTime > 0)
				{
					colour[3] = 1.f - (fadeTime / 5000.f);
				}

				if (scissor)
				{
					point[0] = ((cg.artilleryRequestPos[i][0] - cg.mapcoordsMins[0]) * cg.mapcoordsScale[0]) * pw * scissor->zoomFactor;
					point[1] = ((cg.artilleryRequestPos[i][1] - cg.mapcoordsMins[1]) * cg.mapcoordsScale[1]) * ph * scissor->zoomFactor;
				}
				else
				{
					point[0] = px + (((cg.artilleryRequestPos[i][0] - cg.mapcoordsMins[0]) * cg.mapcoordsScale[0]) * pw);
					point[1] = py + (((cg.artilleryRequestPos[i][1] - cg.mapcoordsMins[1]) * cg.mapcoordsScale[1]) * ph);
				}

				// don't return if the marker is culled, just skip it (so we draw the rest, if any)
				if (scissor && CG_ScissorPointIsCulled(point, scissor))
				{
					continue;
				}

				if (scissor)
				{
					point[0] += px - scissor->tl[0];
					point[1] += py - scissor->tl[1];
				}

				trap_R_SetColor(colour);
				CG_DrawPic(point[0] - 8.f, point[1] - 8.f, 16, 16, cgs.media.ccMortarTarget);
				trap_R_SetColor(NULL);
			}
		}
	}
}