Esempio n. 1
0
void G_Gametype_GENERIC_ClientRespawn( edict_t *self, int old_team, int new_team )
{
	int i;
	gclient_t *client = self->r.client;
	gs_weapon_definition_t *weapondef;

	if( G_ISGHOSTING( self ) )
		return;

	//give default items
	if( self->s.team != TEAM_SPECTATOR )
	{
		if( GS_Instagib() )
		{
			client->ps.inventory[WEAP_INSTAGUN] = 1;
			client->ps.inventory[AMMO_INSTAS] = 1;
			client->ps.inventory[AMMO_WEAK_INSTAS] = 1;
		}
		else
		{
			if( GS_MatchState() <= MATCH_STATE_WARMUP )
			{
				for( i = WEAP_GUNBLADE; i < WEAP_TOTAL; i++ )
				{
					if( i == WEAP_INSTAGUN )  // dont add instagun...
						continue;

					weapondef = GS_GetWeaponDef( i );
					client->ps.inventory[i] = 1;
					if( weapondef->firedef_weak.ammo_id )
						client->ps.inventory[weapondef->firedef_weak.ammo_id] = weapondef->firedef_weak.ammo_max;
					if( weapondef->firedef.ammo_id )
						client->ps.inventory[weapondef->firedef.ammo_id] = weapondef->firedef.ammo_max;
				}

				client->resp.armor = GS_Armor_MaxCountForTag( ARMOR_YA );
			}
			else
			{
				weapondef = GS_GetWeaponDef( WEAP_GUNBLADE );
				client->ps.inventory[WEAP_GUNBLADE] = 1;
				client->ps.inventory[AMMO_GUNBLADE] = weapondef->firedef.ammo_max;;
				client->ps.inventory[AMMO_WEAK_GUNBLADE] = 0;
			}
		}
	}

	// select rocket launcher if available
	if( GS_CheckAmmoInWeapon( &client->ps, WEAP_ROCKETLAUNCHER ) )
		client->ps.stats[STAT_PENDING_WEAPON] = WEAP_ROCKETLAUNCHER;
	else
		client->ps.stats[STAT_PENDING_WEAPON] = GS_SelectBestWeapon( &client->ps );

	// add a teleportation effect
	if( self->r.solid != SOLID_NOT )
		G_RespawnEffect( self );
}
Esempio n. 2
0
//==========================================
// BOT_DMClass_ChangeWeapon
//==========================================
static bool BOT_DMClass_ChangeWeapon( edict_t *self, int weapon )
{
	if( weapon == self->r.client->ps.stats[STAT_PENDING_WEAPON] )
		return false;

	if( !GS_CheckAmmoInWeapon( &self->r.client->ps , weapon ) )
		return false;

	// Change to this weapon
	self->r.client->ps.stats[STAT_PENDING_WEAPON] = weapon;
	self->ai->changeweapon_timeout = level.time + 2000 + ( 4000 * ( 1.0 - self->ai->pers.skillLevel ) );

	return true;
}
Esempio n. 3
0
//==========================================
// BOT_DMclass_ChooseWeapon
// Choose weapon based on range & weights
//==========================================
static float BOT_DMclass_ChooseWeapon( edict_t *self )
{
	float dist;
	int i;
	float best_weight = 0.0;
	gsitem_t *weaponItem;
	int curweapon, weapon_range = 0, best_weapon = WEAP_NONE;

	curweapon = self->r.client->ps.stats[STAT_PENDING_WEAPON];

	// if no enemy, then what are we doing here?
	if( !self->enemy )
	{
		weapon_range = AIWEAP_MEDIUM_RANGE;
		if( curweapon == WEAP_GUNBLADE || curweapon == WEAP_NONE )
			self->ai->changeweapon_timeout = level.time;
	}
	else // Base weapon selection on distance:
	{
		dist = DistanceFast( self->s.origin, self->enemy->s.origin );

		if( dist < 150 )
			weapon_range = AIWEAP_MELEE_RANGE;
		else if( dist < 500 )  // Medium range limit is Grenade launcher range
			weapon_range = AIWEAP_SHORT_RANGE;
		else if( dist < 900 )
			weapon_range = AIWEAP_MEDIUM_RANGE;
		else
			weapon_range = AIWEAP_LONG_RANGE;
	}

	if( self->ai->changeweapon_timeout > level.time )
		return AIWeapons[curweapon].RangeWeight[weapon_range];

	for( i = WEAP_GUNBLADE; i < WEAP_TOTAL; i++ )
	{
		float rangeWeight;

		if( ( weaponItem = GS_FindItemByTag( i ) ) == NULL )
			continue;

		if( !GS_CheckAmmoInWeapon( &self->r.client->ps, i ) )
			continue;

		rangeWeight = AIWeapons[i].RangeWeight[weapon_range] * self->ai->pers.cha.weapon_affinity[i - ( WEAP_GUNBLADE - 1 )];

		// weigh up if having strong ammo
		if( self->r.client->ps.inventory[weaponItem->ammo_tag] )
			rangeWeight *= 1.25;

		// add a small random factor (less random the more skill)
		rangeWeight += brandom( -( 1.0 - self->ai->pers.skillLevel ), 1.0 - self->ai->pers.skillLevel );

		// compare range weights
		if( rangeWeight > best_weight )
		{
			best_weight = rangeWeight;
			best_weapon = i;
		}
	}

	// do the change (same weapon, or null best_weapon is covered at ChangeWeapon)
	if( best_weapon != WEAP_NONE )
		BOT_DMClass_ChangeWeapon( self, best_weapon );

	return AIWeapons[curweapon].RangeWeight[weapon_range]; // return current
}
Esempio n. 4
0
/*
* GS_ThinkPlayerWeapon
*/
int GS_ThinkPlayerWeapon( player_state_t *playerState, int buttons, int msecs, int timeDelta )
{
	firedef_t *firedef;
	qboolean refire = qfalse;

	assert( playerState->stats[STAT_PENDING_WEAPON] >= 0 && playerState->stats[STAT_PENDING_WEAPON] < WEAP_TOTAL );

	if( GS_MatchPaused() )
		return playerState->stats[STAT_WEAPON];

	if( playerState->pmove.pm_type != PM_NORMAL )
	{
		playerState->weaponState = WEAPON_STATE_READY;
		playerState->stats[STAT_PENDING_WEAPON] = playerState->stats[STAT_WEAPON] = WEAP_NONE;
		playerState->stats[STAT_WEAPON_TIME] = 0;
		return playerState->stats[STAT_WEAPON];
	}

	if( playerState->pmove.stats[PM_STAT_NOUSERCONTROL] > 0 )
		buttons = 0;

	if( !msecs )
		goto done;

	if( playerState->stats[STAT_WEAPON_TIME] > 0 )
		playerState->stats[STAT_WEAPON_TIME] -= msecs;
	else
		playerState->stats[STAT_WEAPON_TIME] = 0;

	firedef = GS_FiredefForPlayerState( playerState, playerState->stats[STAT_WEAPON] );

	// during cool-down time it can shoot again or go into reload time
	if( playerState->weaponState == WEAPON_STATE_REFIRE || playerState->weaponState == WEAPON_STATE_REFIRESTRONG )
	{
		int last_firemode;

		if( playerState->stats[STAT_WEAPON_TIME] > 0 )
			goto done;

		last_firemode = ( playerState->weaponState == WEAPON_STATE_REFIRESTRONG ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;
		if( last_firemode == firedef->fire_mode )
			refire = qtrue;

		playerState->weaponState = WEAPON_STATE_READY;
	}

	// nothing can be done during reload time
	if( playerState->weaponState == WEAPON_STATE_RELOADING )
	{
		if( playerState->stats[STAT_WEAPON_TIME] > 0 )
			goto done;

		playerState->weaponState = WEAPON_STATE_READY;
	}

	if( playerState->weaponState == WEAPON_STATE_NOAMMOCLICK )
	{
		if( playerState->stats[STAT_WEAPON_TIME] > 0 )
			goto done;

		if( playerState->stats[STAT_WEAPON] != playerState->stats[STAT_PENDING_WEAPON] )
			playerState->weaponState = WEAPON_STATE_READY;
	}

	// there is a weapon to be changed
	if( playerState->stats[STAT_WEAPON] != playerState->stats[STAT_PENDING_WEAPON] )
	{
		if( ( playerState->weaponState == WEAPON_STATE_READY ) ||
			( playerState->weaponState == WEAPON_STATE_DROPPING ) ||
			( playerState->weaponState == WEAPON_STATE_ACTIVATING ) )
		{
			if( playerState->weaponState != WEAPON_STATE_DROPPING )
			{
				playerState->weaponState = WEAPON_STATE_DROPPING;
				playerState->stats[STAT_WEAPON_TIME] += firedef->weapondown_time;

				if( firedef->weapondown_time )
					module_PredictedEvent( playerState->POVnum, EV_WEAPONDROP, 0 );
			}
		}
	}

	// do the change
	if( playerState->weaponState == WEAPON_STATE_DROPPING )
	{
		if( playerState->stats[STAT_WEAPON_TIME] > 0 )
			goto done;

		playerState->stats[STAT_WEAPON] = playerState->stats[STAT_PENDING_WEAPON];

		// update the firedef
		firedef = GS_FiredefForPlayerState( playerState, playerState->stats[STAT_WEAPON] );
		playerState->weaponState = WEAPON_STATE_ACTIVATING;
		playerState->stats[STAT_WEAPON_TIME] += firedef->weaponup_time;
		module_PredictedEvent( playerState->POVnum, EV_WEAPONACTIVATE, playerState->stats[STAT_WEAPON] );
	}

	if( playerState->weaponState == WEAPON_STATE_ACTIVATING )
	{
		if( playerState->stats[STAT_WEAPON_TIME] > 0 )
			goto done;

		playerState->weaponState = WEAPON_STATE_READY;
	}

	if( ( playerState->weaponState == WEAPON_STATE_READY ) || ( playerState->weaponState == WEAPON_STATE_NOAMMOCLICK ) )
	{
		if( playerState->stats[STAT_WEAPON_TIME] > 0 )
			goto done;

		if( !GS_ShootingDisabled() )
		{
			if( buttons & BUTTON_ATTACK )
			{
				if( GS_CheckAmmoInWeapon( playerState, playerState->stats[STAT_WEAPON] ) )
				{
					playerState->weaponState = WEAPON_STATE_FIRING;
				}
				else
				{
					// player has no ammo nor clips
					if( playerState->weaponState == WEAPON_STATE_NOAMMOCLICK )
					{
						playerState->weaponState = WEAPON_STATE_RELOADING;
						playerState->stats[STAT_WEAPON_TIME] += NOAMMOCLICK_AUTOSWITCH;
						if( playerState->stats[STAT_PENDING_WEAPON] == playerState->stats[STAT_WEAPON] )
							playerState->stats[STAT_PENDING_WEAPON] = GS_SelectBestWeapon( playerState );
					}
					else
					{
						playerState->weaponState = WEAPON_STATE_NOAMMOCLICK;
						playerState->stats[STAT_WEAPON_TIME] += NOAMMOCLICK_PENALTY;
						module_PredictedEvent( playerState->POVnum, EV_NOAMMOCLICK, 0 );
						goto done;
					}
				}
			}
			// gunblade auto attack is special
			else if( playerState->stats[STAT_WEAPON] == WEAP_GUNBLADE &&
				playerState->pmove.stats[PM_STAT_NOUSERCONTROL] <= 0 &&
				playerState->pmove.stats[PM_STAT_NOAUTOATTACK] <= 0 &&
				GS_CheckBladeAutoAttack( playerState, timeDelta ) )
			{
				firedef = &GS_GetWeaponDef( WEAP_GUNBLADE )->firedef_weak;
				playerState->weaponState = WEAPON_STATE_FIRING;
			}
		}
	}

	if( playerState->weaponState == WEAPON_STATE_FIRING )
	{
		int parm = playerState->stats[STAT_WEAPON];
		if( firedef->fire_mode == FIRE_MODE_STRONG )
			parm |= EV_INVERSE;

		playerState->stats[STAT_WEAPON_TIME] += firedef->reload_time;
		if( firedef->fire_mode == FIRE_MODE_STRONG )
			playerState->weaponState = WEAPON_STATE_REFIRESTRONG;
		else
			playerState->weaponState = WEAPON_STATE_REFIRE;

		if( refire && firedef->smooth_refire )
			module_PredictedEvent( playerState->POVnum, EV_SMOOTHREFIREWEAPON, parm );
		else
			module_PredictedEvent( playerState->POVnum, EV_FIREWEAPON, parm );

		// waste ammo
		if( !GS_InfiniteAmmo() )
		{
			if( firedef->ammo_id != AMMO_NONE && firedef->usage_count )
				playerState->inventory[firedef->ammo_id] -= firedef->usage_count;
		}
	}
done:
	return playerState->stats[STAT_WEAPON];
}