Ejemplo n.º 1
0
// xkan, 10/26/2002
// extracted from Fill_Clip: add the specified ammount of ammo into the clip
// returns whether ammo was added to the clip
int AddToClip(
			  playerState_t *ps,// which player
			  int weapon,		// weapon to add ammo for
			  int ammomove,		// ammount to add. 0 means fill the clip if possible
			  int outOfReserve)	// is the amount to be added out of reserve
{
	int inclip, maxclip;
	int ammoweap = BG_FindAmmoForWeapon(weapon);

	if(weapon < WP_LUGER || weapon >= WP_NUM_WEAPONS)
		return qfalse;

	inclip	= ps->ammoclip[BG_FindClipForWeapon(weapon)];
	maxclip = GetAmmoTableData(weapon)->maxclip;

	if (!ammomove)	// amount to add to the clip not specified
		ammomove = maxclip - inclip;	// max amount that can be moved into the clip
	else if (ammomove > maxclip - inclip)
		ammomove = maxclip - inclip;

	if (outOfReserve)
	{
		// cap move amount if it's more than you've got in reserve
		if(ammomove > ps->ammo[ammoweap])
			ammomove = ps->ammo[ammoweap];
	}

	if(ammomove) {
		if (outOfReserve)
			ps->ammo[ammoweap] -= ammomove;
		ps->ammoclip[BG_FindClipForWeapon(weapon)] += ammomove;
		return qtrue;
	}
	return qfalse;
}
Ejemplo n.º 2
0
/*
==============
Fill_Clip
	push reserve ammo into available space in the clip
==============
*/
void Fill_Clip( playerState_t *ps, int weapon ) {
	int inclip, maxclip, ammomove;
	int ammoweap = BG_FindAmmoForWeapon( weapon );

	if ( weapon < WP_LUGER || weapon >= WP_NUM_WEAPONS ) {
		return;
	}

	if ( g_dmflags.integer & DF_NO_WEAPRELOAD ) {
		return;
	}

	inclip  = ps->ammoclip[BG_FindClipForWeapon( weapon )];
	maxclip = ammoTable[weapon].maxclip;

	ammomove = maxclip - inclip;    // max amount that can be moved into the clip

	// cap move amount if it's more than you've got in reserve
	if ( ammomove > ps->ammo[ammoweap] ) {
		ammomove = ps->ammo[ammoweap];
	}

	if ( ammomove ) {
		ps->ammo[ammoweap] -= ammomove;
		ps->ammoclip[BG_FindClipForWeapon( weapon )] += ammomove;
	}
}
Ejemplo n.º 3
0
/**
* @brief Add ammo.
* @return whether any ammo was added
*/
int Add_Ammo(gentity_t *ent, int weapon, int count, qboolean fillClip)
{
	int ammoweap      = BG_FindAmmoForWeapon(weapon);
	int maxammo       = BG_MaxAmmoForWeapon(ammoweap, ent->client->sess.skill);
	int originalCount = ent->client->ps.ammo[ammoweap];

	// FIXME: do a switch
	if (ammoweap == WP_GRENADE_LAUNCHER)             // make sure if he picks up a grenade that he get's the "launcher" too
	{
		COM_BitSet(ent->client->ps.weapons, WP_GRENADE_LAUNCHER);
		fillClip = qtrue;   // grenades always filter into the "clip"
	}
	else if (ammoweap == WP_GRENADE_PINEAPPLE)
	{
		COM_BitSet(ent->client->ps.weapons, WP_GRENADE_PINEAPPLE);
		fillClip = qtrue;   // grenades always filter into the "clip"
	}
	else if (ammoweap == WP_DYNAMITE)
	{
		COM_BitSet(ent->client->ps.weapons, WP_DYNAMITE);
		fillClip = qtrue;
	}
	else if (ammoweap == WP_SATCHEL_DET)
	{
		COM_BitSet(ent->client->ps.weapons, WP_SATCHEL_DET);
		fillClip = qtrue;
	}

	if (fillClip)
	{
		Fill_Clip(&ent->client->ps, weapon);
	}

	if (ammoweap == WP_PANZERFAUST || ammoweap == WP_BAZOOKA || ammoweap == WP_FLAMETHROWER)
	{
		ent->client->ps.ammoclip[ammoweap] += count;

		if (ent->client->ps.ammoclip[ammoweap] > maxammo)
		{
			ent->client->ps.ammoclip[ammoweap] = maxammo;   // - ent->client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
		}
	}
	else
	{
		ent->client->ps.ammo[ammoweap] += count;

		if (ent->client->ps.ammo[ammoweap] > maxammo)
		{
			ent->client->ps.ammo[ammoweap] = maxammo;   // - ent->client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
		}
	}

	if (count >= 999)     // 'really, give /all/'
	{
		ent->client->ps.ammo[ammoweap] = count;
	}

	return (ent->client->ps.ammo[ammoweap] > originalCount);
}
Ejemplo n.º 4
0
qboolean AddWeaponToPlayer(gclient_t *client, weapon_t weapon, int ammo, int ammoclip, qboolean setcurrent) {
	COM_BitSet(client->ps.weapons, weapon);
	client->ps.ammoclip[BG_FindClipForWeapon(weapon)] = ammoclip;
	client->ps.ammo[BG_FindAmmoForWeapon(weapon)]     = ammo;
	if (setcurrent) {
		client->ps.weapon = weapon;
	}

	return qtrue;
}
/*
===============
trigger_ammo_touch
===============
*/
void trigger_ammo_touch( gentity_t *self, gentity_t *other, trace_t *trace )
{
  int ammo, clips, maxClips, maxAmmo;

  if( !other->client )
    return;

  if( other->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS )
    return;

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

  if( other->client->ps.weaponstate != WEAPON_READY )
    return;

  if( BG_FindUsesEnergyForWeapon( other->client->ps.weapon ) && self->spawnflags & 2 )
    return;

  if( !BG_FindUsesEnergyForWeapon( other->client->ps.weapon ) && self->spawnflags & 4 )
    return;

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

  BG_FindAmmoForWeapon( other->client->ps.weapon, &maxAmmo, &maxClips );
  BG_UnpackAmmoArray( other->client->ps.weapon, other->client->ps.ammo, other->client->ps.powerups,
                      &ammo, &clips );

  if( ( ammo + self->damage ) > maxAmmo )
  {
    if( clips < maxClips )
    {
      clips++;
      ammo = 1;
    }
    else
      ammo = maxAmmo;
  }
  else
    ammo += self->damage;

  BG_PackAmmoArray( other->client->ps.weapon, other->client->ps.ammo, other->client->ps.powerups,
                    ammo, clips );
}
Ejemplo n.º 6
0
// TAT 11/6/2002
//		Local func to actual do skill upgrade, used by both MP skill system, and SP scripted skill system
static void G_UpgradeSkill( gentity_t *ent, skillType_t skill ) {
	int i, cnt = 0;

	// See if this is the first time we've reached this skill level
	for( i = 0; i < SK_NUM_SKILLS; i++ ) {
		if( i == skill )
			continue;

		if( ent->client->sess.skill[skill] <= ent->client->sess.skill[i] )
			break;
	}

	G_DebugAddSkillLevel( ent, skill );

	if( i == SK_NUM_SKILLS ) {
		// increase rank
		ent->client->sess.rank++;
	}

	if( ent->client->sess.rank >=4 ) {
		// Gordon: count the number of maxed out skills
		for( i = 0; i < SK_NUM_SKILLS; i++ ) {
			if( ent->client->sess.skill[ i ] >= 4 ) {
				cnt++;
			}
		}

		ent->client->sess.rank = cnt + 3;
		if( ent->client->sess.rank > 10 ) {
			ent->client->sess.rank = 10;
		}
	}

	ClientUserinfoChanged( ent-g_entities );

	// Give em rightaway
	if( skill == SK_BATTLE_SENSE && ent->client->sess.skill[skill] == 1 ) {
		if( AddWeaponToPlayer( ent->client, WP_BINOCULARS, 1, 0, qfalse ) ) {
			ent->client->ps.stats[STAT_KEYS] |= ( 1 << INV_BINOCS );
		}
	} else if( skill == SK_FIRST_AID && ent->client->sess.playerType == PC_MEDIC && ent->client->sess.skill[skill] == 4 ) {
		AddWeaponToPlayer( ent->client, WP_MEDIC_ADRENALINE, ent->client->ps.ammo[BG_FindAmmoForWeapon(WP_MEDIC_ADRENALINE)], ent->client->ps.ammoclip[BG_FindClipForWeapon(WP_MEDIC_ADRENALINE)], qfalse );
	}
}
Ejemplo n.º 7
0
/*
=================
TossClientItems

Toss the weapon and powerups for the killed player
=================
*/
void TossClientItems( gentity_t *self ) {
	gitem_t     *item;
	int weapon;
	gentity_t   *drop = 0;

	// drop the weapon if not a gauntlet or machinegun
	weapon = self->s.weapon;

	// make a special check to see if they are changing to a new
	// weapon that isn't the mg or gauntlet.  Without this, a client
	// can pick up a weapon, be killed, and not drop the weapon because
	// their weapon change hasn't completed yet and they are still holding the MG.

	// (SA) always drop what you were switching to
	if ( 1 ) {
		if ( self->client->ps.weaponstate == WEAPON_DROPPING ) {
			weapon = self->client->pers.cmd.weapon;
		}
		if ( !( COM_BitCheck( self->client->ps.weapons, weapon ) ) ) {
			weapon = WP_NONE;
		}
	}

	// JPW NERVE don't drop these weapon types
	if ( ( weapon == WP_FLAMETHROWER ) || ( weapon == WP_GARAND ) || ( weapon == WP_MAUSER ) || ( weapon == WP_VENOM ) ) {
		weapon = WP_NONE;
	}
	// jpw

	if ( weapon > WP_NONE && weapon < WP_MONSTER_ATTACK1 && self->client->ps.ammo[ BG_FindAmmoForWeapon( weapon_t (weapon) )] ) {
		// find the item type for this weapon
		item = BG_FindItemForWeapon( weapon_t (weapon) );
		// spawn the item

		// Rafael
		if ( !( self->client->ps.persistant[PERS_HWEAPON_USE] ) ) {
			drop = Drop_Item( self, item, 0, qfalse );
			// JPW NERVE -- fix ammo counts
			drop->count = self->client->ps.ammoclip[BG_FindClipForWeapon( weapon_t (weapon) )];
			drop->item->quantity = self->client->ps.ammoclip[BG_FindClipForWeapon( weapon_t (weapon) )];
			// jpw
		}
	}
}
Ejemplo n.º 8
0
/*
=================
G_GiveClientMaxAmmo
=================
*/
void G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo )
{
  int       i;
  int       maxAmmo, maxClips;
  qboolean  weaponType, restoredAmmo = qfalse;

  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
  {
    if( buyingEnergyAmmo )
      weaponType = BG_FindUsesEnergyForWeapon( i );
    else
      weaponType = !BG_FindUsesEnergyForWeapon( i );

    if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) &&
        weaponType && !BG_FindInfinteAmmoForWeapon( i ) &&
        !BG_WeaponIsFull( i, ent->client->ps.stats,
          ent->client->ps.ammo, ent->client->ps.powerups ) )
    {
      BG_FindAmmoForWeapon( i, &maxAmmo, &maxClips );

	if(ent->client->pers.trippleammo == 1)
    {
		maxAmmo*=3;
    }

      if( buyingEnergyAmmo )
      {
        G_AddEvent( ent, EV_RPTUSE_SOUND, 0 );

        if( BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
          maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER );
      }

      BG_PackAmmoArray( i, ent->client->ps.ammo, ent->client->ps.powerups,
                        maxAmmo, maxClips );

      restoredAmmo = qtrue;
    }
  }

  if( restoredAmmo )
    G_ForceWeaponChange( ent, ent->client->ps.weapon );
}
Ejemplo n.º 9
0
//----(SA)	modified
void Add_Ammo( gentity_t *ent, int weapon, int count, qboolean fillClip ) {
	int ammoweap = BG_FindAmmoForWeapon( weapon );
	int totalcount;

	ent->client->ps.ammo[ammoweap] += count;

	if ( ammoweap == WP_GRENADE_LAUNCHER ) {         // make sure if he picks up a grenade that he get's the "launcher" too
		COM_BitSet( ent->client->ps.weapons, WP_GRENADE_LAUNCHER );
		fillClip = qtrue;   // grenades always filter into the "clip"
	} else if ( ammoweap == WP_GRENADE_PINEAPPLE ) {
		COM_BitSet( ent->client->ps.weapons, WP_GRENADE_PINEAPPLE );
		fillClip = qtrue;   // grenades always filter into the "clip"
	} else if ( ammoweap == WP_DYNAMITE || ammoweap == WP_DYNAMITE2 ) {
		COM_BitSet( ent->client->ps.weapons, WP_DYNAMITE );
		fillClip = qtrue;
	}

	if ( fillClip ) {
		Fill_Clip( &ent->client->ps, weapon );
	}

	// cap to max ammo
	if ( g_dmflags.integer & DF_NO_WEAPRELOAD ) {      // no clips
		totalcount = ent->client->ps.ammo[ammoweap];
		if ( totalcount > ammoTable[ammoweap].maxammo ) {
			ent->client->ps.ammo[ammoweap] = ammoTable[ammoweap].maxammo;
		}

	} else {                                        // using clips
		totalcount = ent->client->ps.ammo[ammoweap] + ent->client->ps.ammoclip[BG_FindClipForWeapon( weapon )];
		if ( totalcount > ammoTable[ammoweap].maxammo ) {
			ent->client->ps.ammo[ammoweap] = ammoTable[ammoweap].maxammo - ent->client->ps.ammoclip[BG_FindClipForWeapon( weapon )];
		}

	}


	if ( count >= 999 ) { // 'really, give /all/'
		ent->client->ps.ammo[ammoweap] = count;
	}   // JPW NERVE

}
Ejemplo n.º 10
0
/**
 * @brief Add the specified ammount of ammo into the clip.
 * @param ps which player
 * @param weapon to add ammo for
 * @param ammomove amount to add. 0 means fill the clip if possible
 * @param outOfReserve amount to be added out of reserve
 * @return qboolean whether ammo was added to the clip.
 */
int AddToClip(playerState_t *ps, int weapon, int ammomove, int outOfReserve)
{
	int inclip, maxclip;
	int ammoweap = BG_FindAmmoForWeapon(weapon);

	if (weapon < WP_LUGER || weapon >= WP_NUM_WEAPONS)
	{
		return qfalse;
	}

	inclip  = ps->ammoclip[BG_FindClipForWeapon(weapon)];
	maxclip = GetAmmoTableData(weapon)->maxclip;

	if (!ammomove)     // amount to add to the clip not specified
	{
		ammomove = maxclip - inclip;    // max amount that can be moved into the clip
	}
	else if (ammomove > maxclip - inclip)
	{
		ammomove = maxclip - inclip;
	}

	if (outOfReserve)
	{
		// cap move amount if it's more than you've got in reserve
		if (ammomove > ps->ammo[ammoweap])
		{
			ammomove = ps->ammo[ammoweap];
		}
	}

	if (ammomove)
	{
		if (outOfReserve)
		{
			ps->ammo[ammoweap] -= ammomove;
		}
		ps->ammoclip[BG_FindClipForWeapon(weapon)] += ammomove;
		return qtrue;
	}
	return qfalse;
}
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
/*
==============
CG_CheckAmmo

If the ammo has gone low enough to generate the warning, play a sound
==============
*/
void CG_CheckAmmo( void ) {
	int i;
	int total;
	int weapons[MAX_WEAPONS / ( sizeof( int ) * 8 )];

	// see about how many seconds of ammo we have remaining
	memcpy( weapons, cg.snap->ps.weapons, sizeof( weapons ) );

	if ( !weapons[0] && !weapons[1] ) { // (SA) we start out with no weapons, so don't make a click on startup
		return;
	}

	total = 0;

	// first weap now WP_LUGER
	for ( i = WP_FIRST ; i < WP_NUM_WEAPONS ; i++ )
	{
		if ( !( weapons[0] & ( 1 << i ) ) ) {
			continue;
		}
		switch ( i )
		{
		case WP_PANZERFAUST:
		case WP_GRENADE_LAUNCHER:
		case WP_GRENADE_PINEAPPLE:
		case WP_LUGER:
		case WP_COLT:
		case WP_AKIMBO:
		case WP_SILENCER:
		case WP_FG42:
		case WP_FG42SCOPE:
		case WP_MP40:
		case WP_THOMPSON:
		case WP_STEN:
		case WP_VENOM:
		case WP_TESLA:
		case WP_MAUSER:
		case WP_GARAND:
		default:
			total += cg.snap->ps.ammo[BG_FindAmmoForWeapon( i )] * 1000;
//				break;
//			default:
//				total += cg.snap->ps.ammo[BG_FindAmmoForWeapon(i)] * 200;
//				break;
		}

		if ( total >= 5000 ) {
			cg.lowAmmoWarning = 0;
			return;
		}
	}

	if ( !cg.lowAmmoWarning ) {
		// play a sound on this transition
		trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
	}

	if ( total == 0 ) {
		cg.lowAmmoWarning = 2;
	} else {
		cg.lowAmmoWarning = 1;
	}
}
Ejemplo n.º 13
0
/*
===========
ClientSpawn

Called every time a client is placed fresh in the world:
after the first ClientBegin, and after each respawn
Initializes all non-persistant parts of playerState
============
*/
void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles )
{
  int                 index;
  vec3_t              spawn_origin, spawn_angles;
  gclient_t           *client;
  int                 i;
  clientPersistant_t  saved;
  clientSession_t     savedSess;
  int                 persistant[ MAX_PERSISTANT ];
  gentity_t           *spawnPoint = NULL;
  int                 flags;
  int                 savedPing;
  int                 teamLocal;
  int                 eventSequence;
  char                userinfo[ MAX_INFO_STRING ];
  vec3_t              up = { 0.0f, 0.0f, 1.0f };
  int                 maxAmmo, maxClips;
  weapon_t            weapon;


  index = ent - g_entities;
  client = ent->client;

  teamLocal = client->pers.teamSelection;

  //TA: only start client if chosen a class and joined a team
  if( client->pers.classSelection == PCL_NONE && teamLocal == PTE_NONE )
  {
    client->sess.sessionTeam = TEAM_SPECTATOR;
    client->sess.spectatorState = SPECTATOR_FREE;
  }
  else if( client->pers.classSelection == PCL_NONE )
  {
    client->sess.sessionTeam = TEAM_SPECTATOR;
    client->sess.spectatorState = SPECTATOR_LOCKED;
  }
  
  //if client is dead and following teammate, stop following before spawning
  if(ent->client->sess.spectatorClient!=-1)
  {
    ent->client->sess.spectatorClient = -1;
    ent->client->sess.spectatorState = SPECTATOR_FREE;
  }

  if( origin != NULL )
    VectorCopy( origin, spawn_origin );

  if( angles != NULL )
    VectorCopy( angles, spawn_angles );

  // find a spawn point
  // do it before setting health back up, so farthest
  // ranging doesn't count this client
  if( client->sess.sessionTeam == TEAM_SPECTATOR )
  {
    if( teamLocal == PTE_NONE )
      spawnPoint = G_SelectSpectatorSpawnPoint( spawn_origin, spawn_angles );
    else if( teamLocal == PTE_ALIENS )
      spawnPoint = G_SelectAlienLockSpawnPoint( spawn_origin, spawn_angles );
    else if( teamLocal == PTE_HUMANS )
      spawnPoint = G_SelectHumanLockSpawnPoint( spawn_origin, spawn_angles );
  }
  else
  {
    if( spawn == NULL )
    {
      G_Error( "ClientSpawn: spawn is NULL\n" );
      return;
    }

    spawnPoint = spawn;

    if( ent != spawn )
    {
      //start spawn animation on spawnPoint
      G_SetBuildableAnim( spawnPoint, BANIM_SPAWN1, qtrue );

      if( spawnPoint->biteam == PTE_ALIENS )
        spawnPoint->clientSpawnTime = ALIEN_SPAWN_REPEAT_TIME;
      else if( spawnPoint->biteam == PTE_HUMANS )
        spawnPoint->clientSpawnTime = HUMAN_SPAWN_REPEAT_TIME;
    }
  }
  client->pers.teamState.state = TEAM_ACTIVE;

  // toggle the teleport bit so the client knows to not lerp
  flags = ent->client->ps.eFlags & ( EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED );
  flags ^= EF_TELEPORT_BIT;
  G_UnlaggedClear( ent );

  // clear everything but the persistant data

  saved = client->pers;
  savedSess = client->sess;
  savedPing = client->ps.ping;

  for( i = 0; i < MAX_PERSISTANT; i++ )
    persistant[ i ] = client->ps.persistant[ i ];

  eventSequence = client->ps.eventSequence;
  memset( client, 0, sizeof( *client ) );

  client->pers = saved;
  client->sess = savedSess;
  client->ps.ping = savedPing;
  client->lastkilled_client = -1;

  for( i = 0; i < MAX_PERSISTANT; i++ )
    client->ps.persistant[ i ] = persistant[ i ];

  client->ps.eventSequence = eventSequence;

  // increment the spawncount so the client will detect the respawn
  client->ps.persistant[ PERS_SPAWN_COUNT ]++;
  client->ps.persistant[ PERS_TEAM ] = client->sess.sessionTeam;

  // restore really persistant things
  client->ps.persistant[ PERS_SCORE ] = client->pers.score;
  client->ps.persistant[ PERS_CREDIT ] = client->pers.credit;

  client->airOutTime = level.time + 12000;

  trap_GetUserinfo( index, userinfo, sizeof( userinfo ) );
  client->ps.eFlags = flags;

  //Com_Printf( "ent->client->pers->pclass = %i\n", ent->client->pers.classSelection );

  ent->s.groundEntityNum = ENTITYNUM_NONE;
  ent->client = &level.clients[ index ];
  ent->takedamage = qtrue;
  ent->inuse = qtrue;
  ent->classname = "player";
  ent->r.contents = CONTENTS_BODY;
  ent->clipmask = MASK_PLAYERSOLID;
  ent->die = player_die;
  ent->waterlevel = 0;
  ent->watertype = 0;
  ent->flags = 0;

  //TA: calculate each client's acceleration
  ent->evaluateAcceleration = qtrue;

  client->ps.stats[ STAT_WEAPONS ] = 0;
  client->ps.stats[ STAT_WEAPONS2 ] = 0;
  client->ps.stats[ STAT_SLOTS ] = 0;

  client->ps.eFlags = flags;
  client->ps.clientNum = index;

  BG_FindBBoxForClass( ent->client->pers.classSelection, ent->r.mins, ent->r.maxs, NULL, NULL, NULL );

  if( client->sess.sessionTeam != TEAM_SPECTATOR )
    client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] =
      BG_FindHealthForClass( ent->client->pers.classSelection );
  else
    client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] = 100;

  // clear entity values
  if( ent->client->pers.classSelection == PCL_HUMAN )
  {
    BG_AddWeaponToInventory( WP_BLASTER, client->ps.stats );
    BG_AddUpgradeToInventory( UP_MEDKIT, client->ps.stats );
    weapon = client->pers.humanItemSelection;
  }
  else if( client->sess.sessionTeam != TEAM_SPECTATOR )
    weapon = BG_FindStartWeaponForClass( ent->client->pers.classSelection );
  else
    weapon = WP_NONE;

  BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips );
  BG_AddWeaponToInventory( weapon, client->ps.stats );
  BG_PackAmmoArray( weapon, client->ps.ammo, client->ps.powerups, maxAmmo, maxClips );

  ent->client->ps.stats[ STAT_PCLASS ] = ent->client->pers.classSelection;
  ent->client->ps.stats[ STAT_PTEAM ] = ent->client->pers.teamSelection;

  ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE;
  ent->client->ps.stats[ STAT_STATE ] = 0;
  VectorSet( ent->client->ps.grapplePoint, 0.0f, 0.0f, 1.0f );

  // health will count down towards max_health
  ent->health = client->ps.stats[ STAT_HEALTH ] = client->ps.stats[ STAT_MAX_HEALTH ]; //* 1.25;

  //if evolving scale health
  if( ent == spawn )
  {
    ent->health *= ent->client->pers.evolveHealthFraction;
    client->ps.stats[ STAT_HEALTH ] *= ent->client->pers.evolveHealthFraction;
  }

  //clear the credits array
  for( i = 0; i < MAX_CLIENTS; i++ )
    ent->credits[ i ] = 0;

  client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA;

  G_SetOrigin( ent, spawn_origin );
  VectorCopy( spawn_origin, client->ps.origin );

#define UP_VEL  150.0f
#define F_VEL   50.0f

  //give aliens some spawn velocity
  if( client->sess.sessionTeam != TEAM_SPECTATOR &&
      client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
  {
    if( ent == spawn )
    {
      //evolution particle system
      G_AddPredictableEvent( ent, EV_ALIEN_EVOLVE, DirToByte( up ) );
    }
    else
    {
      spawn_angles[ YAW ] += 180.0f;
      AngleNormalize360( spawn_angles[ YAW ] );

      if( spawnPoint->s.origin2[ 2 ] > 0.0f )
      {
        vec3_t  forward, dir;

        AngleVectors( spawn_angles, forward, NULL, NULL );
        VectorScale( forward, F_VEL, forward );
        VectorAdd( spawnPoint->s.origin2, forward, dir );
        VectorNormalize( dir );

        VectorScale( dir, UP_VEL, client->ps.velocity );
      }

      G_AddPredictableEvent( ent, EV_PLAYER_RESPAWN, 0 );
    }
  }
  else if( client->sess.sessionTeam != TEAM_SPECTATOR &&
           client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
  {
    spawn_angles[ YAW ] += 180.0f;
    AngleNormalize360( spawn_angles[ YAW ] );
  }

  // the respawned flag will be cleared after the attack and jump keys come up
  client->ps.pm_flags |= PMF_RESPAWNED;

  trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd );
  G_SetClientViewAngle( ent, spawn_angles );

  if( !( client->sess.sessionTeam == TEAM_SPECTATOR ) )
  {
    /*G_KillBox( ent );*/ //blame this if a newly spawned client gets stuck in another
    trap_LinkEntity( ent );

    // force the base weapon up
    client->ps.weapon = WP_NONE;
    client->ps.weaponstate = WEAPON_READY;
  }

  // don't allow full run speed for a bit
  client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
  client->ps.pm_time = 100;

  client->respawnTime = level.time;
  client->lastKillTime = level.time;

  client->inactivityTime = level.time + g_inactivity.integer * 1000;
  client->latched_buttons = 0;

  // set default animations
  client->ps.torsoAnim = TORSO_STAND;
  client->ps.legsAnim = LEGS_IDLE;

  if( level.intermissiontime )
    MoveClientToIntermission( ent );
  else
  {
    // fire the targets of the spawn point
    if( !spawn )
      G_UseTargets( spawnPoint, ent );

    // select the highest weapon number available, after any
    // spawn given items have fired
    client->ps.weapon = 1;

    for( i = WP_NUM_WEAPONS - 1; i > 0 ; i-- )
    {
      if( BG_InventoryContainsWeapon( i, client->ps.stats ) )
      {
        client->ps.weapon = i;
        break;
      }
    }
  }

  // run a client frame to drop exactly to the floor,
  // initialize animations and other things
  client->ps.commandTime = level.time - 100;
  ent->client->pers.cmd.serverTime = level.time;
  ClientThink( ent-g_entities );

  // positively link the client, even if the command times are weird
  if( client->sess.sessionTeam != TEAM_SPECTATOR )
  {
    BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
    VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
    trap_LinkEntity( ent );
  }

  //TA: must do this here so the number of active clients is calculated
  CalculateRanks( );

  // run the presend to set anything else
  ClientEndFrame( ent );

  // clear entity state values
  BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
}
Ejemplo n.º 14
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.º 15
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 );
	}

	// 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( weapon == WP_MORTAR ) {
		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])] + client->ps.ammoclip[BG_FindClipForWeapon(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;
}
Ejemplo n.º 16
0
/*
==================
ClientTimerActions

Actions that happen once a second
==================
*/
void ClientTimerActions( gentity_t *ent, int msec )
{
  gclient_t *client;
  usercmd_t *ucmd;
  int       aForward, aRight;

  ucmd = &ent->client->pers.cmd;

  aForward  = abs( ucmd->forwardmove );
  aRight    = abs( ucmd->rightmove );

  client = ent->client;
  client->time100 += msec;
  client->time1000 += msec;
  client->time10000 += msec;

  while ( client->time100 >= 100 )
  {
    client->time100 -= 100;

    //if not trying to run then not trying to sprint
    if( aForward <= 64 )
      client->ps.stats[ STAT_STATE ] &= ~SS_SPEEDBOOST;

    if( BG_InventoryContainsUpgrade( UP_JETPACK, client->ps.stats ) && BG_UpgradeIsActive( UP_JETPACK, client->ps.stats ) )
      client->ps.stats[ STAT_STATE ] &= ~SS_SPEEDBOOST;

    if( ( client->ps.stats[ STAT_STATE ] & SS_SPEEDBOOST ) &&  ucmd->upmove >= 0 )
    {
      //subtract stamina
      if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, client->ps.stats ) )
        client->ps.stats[ STAT_STAMINA ] -= STAMINA_LARMOUR_TAKE;
      else
        client->ps.stats[ STAT_STAMINA ] -= STAMINA_SPRINT_TAKE;

      if( client->ps.stats[ STAT_STAMINA ] < -MAX_STAMINA )
        client->ps.stats[ STAT_STAMINA ] = -MAX_STAMINA;
    }

    if( ( aForward <= 64 && aForward > 5 ) || ( aRight <= 64 && aRight > 5 ) )
    {
      //restore stamina
      client->ps.stats[ STAT_STAMINA ] += STAMINA_WALK_RESTORE;

      if( client->ps.stats[ STAT_STAMINA ] > MAX_STAMINA )
        client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA;
    }
    else if( aForward <= 5 && aRight <= 5 )
    {
      //restore stamina faster
      client->ps.stats[ STAT_STAMINA ] += STAMINA_STOP_RESTORE;

      if( client->ps.stats[ STAT_STAMINA ] > MAX_STAMINA )
        client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA;
    }

    //client is charging up for a pounce
    if( client->ps.weapon == WP_ALEVEL3 || client->ps.weapon == WP_ALEVEL3_UPG )
    {
      int pounceSpeed = 0;

      if( client->ps.weapon == WP_ALEVEL3 )
        pounceSpeed = LEVEL3_POUNCE_SPEED;
      else if( client->ps.weapon == WP_ALEVEL3_UPG )
        pounceSpeed = LEVEL3_POUNCE_UPG_SPEED;

      if( client->ps.stats[ STAT_MISC ] < pounceSpeed && ucmd->buttons & BUTTON_ATTACK2 )
        client->ps.stats[ STAT_MISC ] += ( 100.0f / (float)LEVEL3_POUNCE_CHARGE_TIME ) * pounceSpeed;

      if( !( ucmd->buttons & BUTTON_ATTACK2 ) )
      {
        if( client->ps.stats[ STAT_MISC ] > 0 )
        {
          client->allowedToPounce = qtrue;
          client->pouncePayload = client->ps.stats[ STAT_MISC ];
        }

        client->ps.stats[ STAT_MISC ] = 0;
      }

      if( client->ps.stats[ STAT_MISC ] > pounceSpeed )
        client->ps.stats[ STAT_MISC ] = pounceSpeed;
    }

    //client is charging up for a... charge
    if( client->ps.weapon == WP_ALEVEL4 )
    {
      if( client->ps.stats[ STAT_MISC ] < LEVEL4_CHARGE_TIME && ucmd->buttons & BUTTON_ATTACK2 &&
          !client->charging )
      {
        client->charging = qfalse; //should already be off, just making sure
        client->ps.stats[ STAT_STATE ] &= ~SS_CHARGING;

        if( ucmd->forwardmove > 0 )
        {
          //trigger charge sound...is quite annoying
          //if( client->ps.stats[ STAT_MISC ] <= 0 )
          //  G_AddEvent( ent, EV_LEV4_CHARGE_PREPARE, 0 );

          client->ps.stats[ STAT_MISC ] += (int)( 100 * (float)LEVEL4_CHARGE_CHARGE_RATIO );

          if( client->ps.stats[ STAT_MISC ] > LEVEL4_CHARGE_TIME )
            client->ps.stats[ STAT_MISC ] = LEVEL4_CHARGE_TIME;
        }
        else
          client->ps.stats[ STAT_MISC ] = 0;
      }

      if( !( ucmd->buttons & BUTTON_ATTACK2 ) || client->charging ||
          client->ps.stats[ STAT_MISC ] == LEVEL4_CHARGE_TIME )
      {
        if( client->ps.stats[ STAT_MISC ] > LEVEL4_MIN_CHARGE_TIME )
        {
          client->ps.stats[ STAT_MISC ] -= 100;

          if( client->charging == qfalse )
            G_AddEvent( ent, EV_LEV4_CHARGE_START, 0 );

          client->charging = qtrue;
          client->ps.stats[ STAT_STATE ] |= SS_CHARGING;

          //if the charger has stopped moving take a chunk of charge away
          if( VectorLength( client->ps.velocity ) < 64.0f || aRight )
            client->ps.stats[ STAT_MISC ] = client->ps.stats[ STAT_MISC ] / 2;

          //can't charge backwards
          if( ucmd->forwardmove < 0 )
            client->ps.stats[ STAT_MISC ] = 0;
        }
        else
          client->ps.stats[ STAT_MISC ] = 0;


        if( client->ps.stats[ STAT_MISC ] <= 0 )
        {
          client->ps.stats[ STAT_MISC ] = 0;
          client->charging = qfalse;
          client->ps.stats[ STAT_STATE ] &= ~SS_CHARGING;
        }
      }
    }

    //client is charging up an lcannon
    if( client->ps.weapon == WP_LUCIFER_CANNON )
    {
      int ammo;

      BG_UnpackAmmoArray( WP_LUCIFER_CANNON, client->ps.ammo, client->ps.powerups, &ammo, NULL );

      if( client->ps.stats[ STAT_MISC ] < LCANNON_TOTAL_CHARGE && ucmd->buttons & BUTTON_ATTACK )
        client->ps.stats[ STAT_MISC ] += ( 100.0f / LCANNON_CHARGE_TIME ) * LCANNON_TOTAL_CHARGE;

      if( client->ps.stats[ STAT_MISC ] > LCANNON_TOTAL_CHARGE )
        client->ps.stats[ STAT_MISC ] = LCANNON_TOTAL_CHARGE;

      if( client->ps.stats[ STAT_MISC ] > ( ammo * LCANNON_TOTAL_CHARGE ) / 10 )
        client->ps.stats[ STAT_MISC ] = ammo * LCANNON_TOTAL_CHARGE / 10;
    }

    switch( client->ps.weapon )
    {
      case WP_ABUILD:
      case WP_ABUILD2:
      case WP_HBUILD:
      case WP_HBUILD2:
        //set validity bit on buildable
        if( ( client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE )
        {
          int     dist = BG_FindBuildDistForClass( ent->client->ps.stats[ STAT_PCLASS ] );
          vec3_t  dummy;

          if( G_itemFits( ent, (buildable_t)(client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT),
                          dist, dummy ) == IBE_NONE )
            client->ps.stats[ STAT_BUILDABLE ] |= SB_VALID_TOGGLEBIT;
          else
            client->ps.stats[ STAT_BUILDABLE ] &= ~SB_VALID_TOGGLEBIT;
        }

        //update build timer
        if( client->ps.stats[ STAT_MISC ] > 0 )
          client->ps.stats[ STAT_MISC ] -= 100;

        if( client->ps.stats[ STAT_MISC ] < 0 )
          client->ps.stats[ STAT_MISC ] = 0;
        break;

      default:
        break;
    }

    if( client->ps.stats[ STAT_STATE ] & SS_MEDKIT_ACTIVE )
    {
      int remainingStartupTime = MEDKIT_STARTUP_TIME - ( level.time - client->lastMedKitTime );

      if( remainingStartupTime < 0 )
      {
        if( ent->health < ent->client->ps.stats[ STAT_MAX_HEALTH ] &&
            ent->client->medKitHealthToRestore &&
            ent->client->ps.pm_type != PM_DEAD )
        {
          ent->client->medKitHealthToRestore--;
          ent->health++;
        }
        else
          ent->client->ps.stats[ STAT_STATE ] &= ~SS_MEDKIT_ACTIVE;
      }
      else
      {
        if( ent->health < ent->client->ps.stats[ STAT_MAX_HEALTH ] &&
            ent->client->medKitHealthToRestore &&
            ent->client->ps.pm_type != PM_DEAD )
        {
          //partial increase
          if( level.time > client->medKitIncrementTime )
          {
            ent->client->medKitHealthToRestore--;
            ent->health++;

            client->medKitIncrementTime = level.time +
              ( remainingStartupTime / MEDKIT_STARTUP_SPEED );
          }
        }
        else
          ent->client->ps.stats[ STAT_STATE ] &= ~SS_MEDKIT_ACTIVE;
      }
    }
  }

  while( client->time1000 >= 1000 )
  {
    client->time1000 -= 1000;

    //client is poison clouded
    if( client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED )
      G_Damage( ent, client->lastPoisonCloudedClient, client->lastPoisonCloudedClient, NULL, NULL,
                LEVEL1_PCLOUD_DMG, 0, MOD_LEVEL1_PCLOUD );

    //client is poisoned
    if( client->ps.stats[ STAT_STATE ] & SS_POISONED )
    {
      int i;
      int seconds = ( ( level.time - client->lastPoisonTime ) / 1000 ) + 1;
      int damage = ALIEN_POISON_DMG, damage2 = 0;

      for( i = 0; i < seconds; i++ )
      {
        if( i == seconds - 1 )
          damage2 = damage;

        damage *= ALIEN_POISON_DIVIDER;
      }

      damage = damage2 - damage;

      G_Damage( ent, client->lastPoisonClient, client->lastPoisonClient, NULL, NULL,
                damage, 0, MOD_POISON );
    }

    //replenish alien health
    if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
    {
      int       entityList[ MAX_GENTITIES ];
      vec3_t    range = { LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE };
      vec3_t    mins, maxs;
      int       i, num;
      gentity_t *boostEntity;
      float     modifier = 1.0f;

      VectorAdd( client->ps.origin, range, maxs );
      VectorSubtract( client->ps.origin, range, mins );

      num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
      for( i = 0; i < num; i++ )
      {
        boostEntity = &g_entities[ entityList[ i ] ];

        if( boostEntity->client && boostEntity->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS &&
            boostEntity->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_LEVEL4 )
        {
          modifier = LEVEL4_REGEN_MOD;
          break;
        }
        else if( boostEntity->s.eType == ET_BUILDABLE &&
            boostEntity->s.modelindex == BA_A_BOOSTER &&
            boostEntity->spawned )
        {
          modifier = BOOSTER_REGEN_MOD;
          break;
        }
      }

      if( ent->health > 0 && ent->health < client->ps.stats[ STAT_MAX_HEALTH ] &&
          ( ent->lastDamageTime + ALIEN_REGEN_DAMAGE_TIME ) < level.time )
        ent->health += BG_FindRegenRateForClass( client->ps.stats[ STAT_PCLASS ] ) * modifier;

      if( ent->health > client->ps.stats[ STAT_MAX_HEALTH ] )
        ent->health = client->ps.stats[ STAT_MAX_HEALTH ];
    }
  }

  while( client->time10000 >= 10000 )
  {
    client->time10000 -= 10000;

    if( client->ps.weapon == WP_ALEVEL3_UPG )
    {
      int ammo, maxAmmo;

      BG_FindAmmoForWeapon( WP_ALEVEL3_UPG, &maxAmmo, NULL );
      BG_UnpackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, &ammo, NULL );

      if( ammo < maxAmmo )
      {
        ammo++;
        BG_PackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, ammo, 0 );
      }
    }
  }
}
Ejemplo n.º 17
0
// Set up snapshot merge based on this portal
qboolean G_smvRunCamera(gentity_t *ent)
{
	int           id = ent->TargetFlag;
	int           chargeTime, sprintTime, hintTime, weapHeat;
	playerState_t *tps, *ps;

	// Opt out if not a real MV portal
	if (ent->tagParent == NULL || ent->tagParent->client == NULL)
	{
		return qfalse;
	}

	if ((ps = &ent->tagParent->client->ps) == NULL)
	{
		return qfalse;
	}

	// If viewing client is no longer connected, delete this camera
	if (ent->tagParent->client->pers.connected != CON_CONNECTED)
	{
		G_FreeEntity(ent);
		return qtrue;
	}

	// Also remove if the target player is no longer in the game playing
	if (ent->target_ent->client->pers.connected != CON_CONNECTED ||
	    ent->target_ent->client->sess.sessionTeam == TEAM_SPECTATOR)
	{
		G_smvLocateEntityInMVList(ent->tagParent, ent->target_ent - g_entities, qtrue);
		return qtrue;
	}

	// Seems that depending on player's state, we pull from either r.currentOrigin, or s.origin
	//      if(!spec) then use: r.currentOrigin
	//      if(spec) then use:  s.origin
	//
	// This is true for both the portal origin and its target (origin2)
	//
	VectorCopy(ent->tagParent->s.origin, ent->s.origin);
	G_SetOrigin(ent, ent->s.origin);
	VectorCopy(ent->target_ent->r.currentOrigin, ent->s.origin2);
	trap_LinkEntity(ent);

	// Only allow client ids 0 to (MAX_MVCLIENTS-1) to be updated with extra info
	if (id >= MAX_MVCLIENTS)
	{
		return qtrue;
	}

	tps = &ent->target_ent->client->ps;

	if (tps->stats[STAT_PLAYER_CLASS] == PC_ENGINEER)
	{
		chargeTime = g_engineerChargeTime.value;
	}
	else if (tps->stats[STAT_PLAYER_CLASS] == PC_MEDIC)
	{
		chargeTime = g_medicChargeTime.value;
	}
	else if (tps->stats[STAT_PLAYER_CLASS] == PC_FIELDOPS)
	{
		chargeTime = g_fieldopsChargeTime.value;
	}
	else if (tps->stats[STAT_PLAYER_CLASS] == PC_COVERTOPS)
	{
		chargeTime = g_covertopsChargeTime.value;
	}
	else
	{
		chargeTime = g_soldierChargeTime.value;
	}

	chargeTime = (level.time - tps->classWeaponTime >= (int)chargeTime) ? 0 : (1 + floor(15.0f * (float)(level.time - tps->classWeaponTime) / chargeTime));
	sprintTime = (ent->target_ent->client->pmext.sprintTime >= 20000) ? 0.0f : (1 + floor(7.0f * (float)ent->target_ent->client->pmext.sprintTime / 20000.0f));
	weapHeat   = floor((float)tps->curWeapHeat * 15.0f / 255.0f);
	hintTime   = (tps->serverCursorHint != HINT_BUILD && (tps->serverCursorHintVal >= 255 || tps->serverCursorHintVal == 0)) ?
	             0 : (1 + floor(15.0f * (float)tps->serverCursorHintVal / 255.0f));

	// (Remaining bits)
	// ammo      : 0
	// ammo-1    : 0
	// ammiclip  : 0
	// ammoclip-1: 16
	id = MAX_WEAPONS - 1 - (id * 2);

	if (tps->pm_flags & PMF_LIMBO)
	{
		ps->ammo[id]         = 0;
		ps->ammo[id - 1]     = 0;
		ps->ammoclip[id - 1] = 0;
	}
	else
	{
		ps->ammo[id]  = (((ent->target_ent->health > 0) ? ent->target_ent->health : 0) & 0xFF);       // Meds up to 140 :(
		ps->ammo[id] |= (hintTime & 0x0F) << 8;   // 4 bits for work on current item (dynamite, weapon repair, etc.)
		ps->ammo[id] |= (weapHeat & 0x0F) << 12;   // 4 bits for weapon heat info

		ps->ammo[id - 1]  = tps->ammo[BG_FindAmmoForWeapon(tps->weapon)] & 0x3FF;     // 11 bits needed to cover 1500 Venom ammo
		ps->ammo[id - 1] |= (BG_simpleWeaponState(tps->weaponstate) & 0x03) << 11;      // 2 bits for current weapon state
		ps->ammo[id - 1] |= ((tps->persistant[PERS_HWEAPON_USE]) ? 1 : 0) << 13;        // 1 bit for mg42 use
		ps->ammo[id - 1] |= (BG_simpleHintsCollapse(tps->serverCursorHint, hintTime) & 0x03) << 14;     // 2 bits for cursor hints

//  G_Printf("tps->hint: %d, dr: %d, collapse: %d\n", tps->serverCursorHint, HINT_DOOR_ROTATING, G_simpleHintsCollapse(tps->serverCursorHint, hintTime));

		ps->ammoclip[id - 1]  = tps->ammoclip[BG_FindClipForWeapon(tps->weapon)] & 0x1FF;     // 9 bits to cover 500 Venom ammo clip
		ps->ammoclip[id - 1] |= (chargeTime & 0x0F) << 9;     // 4 bits for weapon charge time
		ps->ammoclip[id - 1] |= (sprintTime & 0x07) << 13;    // 3 bits for fatigue
	}

	return qtrue;
}
Ejemplo n.º 18
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.º 19
0
static int CG_PlayerAmmoValue(int *ammo, int *clips, int *akimboammo)
{
	centity_t     *cent;
	playerState_t *ps;
	int           weap;
	qboolean      skipammo = qfalse;

	*ammo = *clips = *akimboammo = -1;

	if (cg.snap->ps.clientNum == cg.clientNum)
	{
		cent = &cg.predictedPlayerEntity;
	}
	else
	{
		cent = &cg_entities[cg.snap->ps.clientNum];
	}
	ps = &cg.snap->ps;

	weap = cent->currentState.weapon;

	if (!weap)
	{
		return weap;
	}

	switch (weap)          // some weapons don't draw ammo count text
	{
	case WP_AMMO:
	case WP_MEDKIT:
	case WP_KNIFE:
	case WP_PLIERS:
	case WP_SMOKE_MARKER:
	case WP_DYNAMITE:
	case WP_SATCHEL:
	case WP_SATCHEL_DET:
	case WP_SMOKE_BOMB:
	case WP_BINOCULARS:
		return weap;

	case WP_LANDMINE:
	case WP_MEDIC_SYRINGE:
	case WP_MEDIC_ADRENALINE:
	case WP_GRENADE_LAUNCHER:
	case WP_GRENADE_PINEAPPLE:
	case WP_FLAMETHROWER:
	case WP_MORTAR:
	case WP_MORTAR_SET:
	case WP_PANZERFAUST:
		skipammo = qtrue;
		break;

	default:
		break;
	}

	if (cg.snap->ps.eFlags & EF_MG42_ACTIVE || cg.snap->ps.eFlags & EF_MOUNTEDTANK)
	{
		return WP_MOBILE_MG42;
	}

	// total ammo in clips
	*clips = cg.snap->ps.ammo[BG_FindAmmoForWeapon(weap)];

	// current clip
	*ammo = ps->ammoclip[BG_FindClipForWeapon(weap)];

	if (BG_IsAkimboWeapon(weap))
	{
		*akimboammo = ps->ammoclip[BG_FindClipForWeapon(BG_AkimboSidearm(weap))];
	}
	else
	{
		*akimboammo = -1;
	}

	if (weap == WP_LANDMINE)
	{
		if (!cgs.gameManager)
		{
			*ammo = 0;
		}
		else
		{
			if (cgs.clientinfo[ps->clientNum].team == TEAM_AXIS)
			{
				*ammo = cgs.gameManager->currentState.otherEntityNum;
			}
			else
			{
				*ammo = cgs.gameManager->currentState.otherEntityNum2;
			}
		}
	}
	else if (weap == WP_MORTAR || weap == WP_MORTAR_SET || weap == WP_PANZERFAUST)
	{
		*ammo += *clips;
	}

	if (skipammo)
	{
		*clips = -1;
	}

	return weap;
}
Ejemplo n.º 20
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.º 21
0
int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
	int quantity;
	qboolean alreadyHave = qfalse;
	int i,weapon;         // JPW NERVE

// JPW NERVE -- magic ammo for any two-handed weapon
	if ( ent->item->giTag == WP_AMMO ) {
// 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_LT ) {
			if ( ent->parent ) {
				if ( other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
					if ( ent->parent->client ) {
						if ( !( ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD ) ) {
							AddScore( ent->parent, WOLF_AMMO_UP );
						}
						ent->parent->client->PCSpecialPickedUpCount++;
					}
				}
			}
		}

		// everybody likes grenades -- abuse weapon var as grenade type and i as max # grenades class can carry
		switch ( other->client->ps.stats[STAT_PLAYER_CLASS] ) {
		case PC_LT: // redundant but added for completeness/flexibility
		case PC_MEDIC:
			i = 1;
			break;
		case PC_SOLDIER:
			i = 4;
			break;
		case PC_ENGINEER:
			i = 8;
			break;
		default:
			i = 1;
			break;
		}
		if ( other->client->sess.sessionTeam == TEAM_RED ) {
			weapon = WP_GRENADE_LAUNCHER;
		} else {
			weapon = WP_GRENADE_PINEAPPLE;
		}
		if ( other->client->ps.ammoclip[BG_FindClipForWeapon( weapon )] < i ) {
			other->client->ps.ammoclip[BG_FindClipForWeapon( weapon )]++;
		}
		COM_BitSet( other->client->ps.weapons,weapon );

		// TTimo - add 8 pistol bullets
		if ( other->client->sess.sessionTeam == TEAM_RED ) {
			weapon = WP_LUGER;
		} else {
			weapon = WP_COLT;
		}
//		G_Printf("filling magazine for weapon %d colt/luger (%d rounds)\n", weapon, ammoTable[weapon].maxclip);
		other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] += ammoTable[weapon].maxclip;
		if ( other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] > ammoTable[weapon].maxclip * 4 ) {
			other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] = ammoTable[weapon].maxclip * 4;
		}

		// and some two-handed ammo
		for ( i = 0; i < MAX_WEAPS_IN_BANK_MP; i++ ) {
			weapon = weapBanksMultiPlayer[3][i];
			if ( COM_BitCheck( other->client->ps.weapons, weapon ) ) {
//				G_Printf("filling magazine for weapon %d (%d rounds)\n",weapon,ammoTable[weapon].maxclip);
				if ( weapon == WP_FLAMETHROWER ) { // FT doesn't use magazines so refill tank
					other->client->ps.ammoclip[BG_FindAmmoForWeapon( WP_FLAMETHROWER )] = ammoTable[weapon].maxclip;
				} else {
					other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] += ammoTable[weapon].maxclip;
					if ( other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] > ammoTable[weapon].maxclip * 3 ) {
						other->client->ps.ammo[BG_FindAmmoForWeapon( weapon )] = ammoTable[weapon].maxclip * 3;
					}
				}
				return RESPAWN_SP;
			}
		}
		return RESPAWN_SP;
	}
// jpw
	if ( ent->count < 0 ) {
		quantity = 0; // None for you, sir!
	} else {
		if ( ent->count ) {
			quantity = ent->count;
		} else {
//----(SA) modified
// JPW NERVE did this so ammocounts work right on dropped weapons
			if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
				quantity = ent->item->quantity;
			} else {
// jpw
				quantity = ( random() * ( ent->item->quantity - 1 ) ) + 1;  // giving 1-<item default count>
			}
		}
	}

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

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

	// DHM - Fixup mauser/sniper issues
	if ( ent->item->giTag == WP_MAUSER ) {
		COM_BitSet( other->client->ps.weapons, WP_SNIPERRIFLE );
	}
	if ( ent->item->giTag == WP_SNIPERRIFLE ) {
		COM_BitSet( other->client->ps.weapons, WP_MAUSER );
	}

	//----(SA)	added
	// snooper == automatic garand mod
	if ( ent->item->giTag == WP_SNOOPERSCOPE ) {
		COM_BitSet( other->client->ps.weapons, WP_GARAND );
	}
	// fg42scope == automatic fg42 mod
	else if ( ent->item->giTag == WP_FG42SCOPE ) {
		COM_BitSet( other->client->ps.weapons, WP_FG42 );
	} else if ( ent->item->giTag == WP_GARAND ) {
		COM_BitSet( other->client->ps.weapons, WP_SNOOPERSCOPE );
	}
	//----(SA)	end

// JPW NERVE  prevents drop/pickup weapon "quick reload" exploit
	if ( alreadyHave ) {
		Add_Ammo( other, ent->item->giTag, quantity, !alreadyHave );
	} else {
		other->client->ps.ammoclip[BG_FindClipForWeapon( ent->item->giTag )] = quantity;
	}
// jpw

	// single player has no respawns	(SA)
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		return RESPAWN_SP;
	}

	if ( g_gametype.integer == GT_TEAM ) {
		return g_weaponTeamRespawn.integer;
	}

	return g_weaponRespawn.integer;
}
Ejemplo n.º 22
0
/*
=================
TossClientItems

Toss the weapon and powerups for the killed player
=================
*/
void TossClientItems( gentity_t *self ) {
	gitem_t     *item;
	vec3_t forward;
	int weapon;
	float angle;
	int i;
	gentity_t   *drop = 0;

	// drop the weapon if not a gauntlet or machinegun
	weapon = self->s.weapon;

	switch ( self->aiCharacter ) {
	case AICHAR_ZOMBIE:
	case AICHAR_WARZOMBIE:
	case AICHAR_LOPER:
		return;         //----(SA)	removed DK's special case
	default:
		break;
	}

	AngleVectors( self->r.currentAngles, forward, NULL, NULL );

	G_ThrowChair( self, forward, qtrue ); // drop chair if you're holding one  //----(SA)	added

	// make a special check to see if they are changing to a new
	// weapon that isn't the mg or gauntlet.  Without this, a client
	// can pick up a weapon, be killed, and not drop the weapon because
	// their weapon change hasn't completed yet and they are still holding the MG.

// (SA) always drop what you were switching to
	if ( 1 ) {
//	if ( weapon == WP_MACHINEGUN || weapon == WP_GRAPPLING_HOOK ) {
		if ( self->client->ps.weaponstate == WEAPON_DROPPING || self->client->ps.weaponstate == WEAPON_DROPPING_TORELOAD ) {
			weapon = self->client->pers.cmd.weapon;
		}
		if ( !( COM_BitCheck( self->client->ps.weapons, weapon ) ) ) {
			weapon = WP_NONE;
		}
	}

//----(SA)	added
	if ( weapon == WP_SNOOPERSCOPE ) {
		weapon = WP_GARAND;
	}
	if ( weapon == WP_FG42SCOPE ) {
		weapon = WP_FG42;
	}
	if ( weapon == WP_AKIMBO ) { //----(SA)	added
		weapon = WP_COLT;
	}
//----(SA)	end


	if ( weapon > WP_NONE && weapon < WP_MONSTER_ATTACK1 && self->client->ps.ammo[ BG_FindAmmoForWeapon( weapon )] ) {
		// find the item type for this weapon
		item = BG_FindItemForWeapon( weapon );
		// spawn the item

		// Rafael
		if ( !( self->client->ps.persistant[PERS_HWEAPON_USE] ) ) {
			drop = Drop_Item( self, item, 0, qfalse );
		}
	}

	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {  // dropped items stay forever in SP
		if ( drop ) {
			drop->nextthink = 0;
		}
	}

	if ( g_gametype.integer != GT_TEAM ) {  // drop all the powerups if not in teamplay
		angle = 45;
		for ( i = 1 ; i < PW_NUM_POWERUPS ; i++ ) {
			if ( self->client->ps.powerups[ i ] > level.time ) {
				item = BG_FindItemForPowerup( i );
				if ( !item ) {
					continue;
				}
				drop = Drop_Item( self, item, angle, qfalse );
				// decide how many seconds it has left
				drop->count = ( self->client->ps.powerups[ i ] - level.time ) / 1000;
				if ( drop->count < 1 ) {
					drop->count = 1;
				}
				drop->nextthink = 0;    // stay forever
				angle += 45;
			}
		}
	}
}