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 );
}
bool BotTacticalSpotsCache::FindCloseRangeTacticalSpot( const Vec3 &origin, const Vec3 &enemyOrigin, vec3_t result ) {
	TacticalSpotsRegistry::AdvantageProblemParams problemParams( enemyOrigin.Data() );
	float meleeRange = GS_GetWeaponDef( WEAP_GUNBLADE )->firedef_weak.timeout;
	problemParams.SetMinSpotDistanceToEntity( meleeRange );
	problemParams.SetMaxSpotDistanceToEntity( WorldState::CLOSE_RANGE_MAX );
	problemParams.SetOriginDistanceInfluence( 0.0f );
	problemParams.SetEntityDistanceInfluence( 0.7f );
	problemParams.SetEntityWeightFalloffDistanceRatio( 0.8f );
	problemParams.SetTravelTimeInfluence( 0.0f );
	problemParams.SetMinHeightAdvantageOverOrigin( -16.0f );
	problemParams.SetMinHeightAdvantageOverEntity( -16.0f );
	problemParams.SetHeightOverOriginInfluence( 0.4f );
	problemParams.SetHeightOverEntityInfluence( 0.9f );
	// Bot should be able to retreat from close combat
	problemParams.SetCheckToAndBackReachability( true );

	float searchRadius = WorldState::CLOSE_RANGE_MAX * 2;
	float distanceToEnemy = ( origin - enemyOrigin ).LengthFast();
	if( distanceToEnemy > WorldState::CLOSE_RANGE_MAX ) {
		searchRadius += distanceToEnemy - WorldState::CLOSE_RANGE_MAX;
		// On this range retreating to an old position makes little sense
		if( distanceToEnemy > 0.5f * WorldState::MIDDLE_RANGE_MAX ) {
			problemParams.SetCheckToAndBackReachability( false );
		}
	}

	return FindForOrigin( problemParams, origin, searchRadius, result );
}
Esempio n. 3
0
/*
* CG_OverrideWeapondef
*
* Compares name and tag against the itemlist to make sure cgame and game lists match
*/
void CG_OverrideWeapondef( int index, const char *cstring )
{
	int weapon, i;
	int firemode = FIRE_MODE_WEAK;
	gs_weapon_definition_t *weapondef;
	firedef_t *firedef;

	weapon = index;
	if( index >= (MAX_WEAPONDEFS / 2) )
	{
		weapon -= (MAX_WEAPONDEFS / 2);
		firemode = FIRE_MODE_STRONG;
	}

	weapondef = GS_GetWeaponDef( weapon );
	if( !weapondef )
		CG_Error( "CG_OverrideWeapondef: Invalid weapon index\n" );

	firedef = ( firemode == FIRE_MODE_STRONG ) ? &weapondef->firedef : &weapondef->firedef_weak;

	i = sscanf( cstring, "%7i %7i %7u %7u %7u %7u %7u %7i %7i",
		&firedef->usage_count,
		&firedef->projectile_count,
		&firedef->weaponup_time,
		&firedef->weapondown_time,
		&firedef->reload_time,
		&firedef->cooldown_time,
		&firedef->timeout,
		&firedef->speed,
		&firedef->spread
		);

	if( i != 9 )
		CG_Error( "CG_OverrideWeapondef: Bad configstring: %s \"%s\" (%i)\n", weapondef->name, cstring, i );
}
Esempio n. 4
0
static qboolean GS_CheckBladeAutoAttack( player_state_t *playerState, int timeDelta )
{
	vec3_t origin, dir, end;
	trace_t trace;
	entity_state_t *targ, *player;
	gs_weapon_definition_t *weapondef = GS_GetWeaponDef( WEAP_GUNBLADE );

	if( playerState->POVnum <= 0 || (int)playerState->POVnum > gs.maxclients )
		return qfalse;

	if( !( playerState->pmove.stats[PM_STAT_FEATURES] & PMFEAT_GUNBLADEAUTOATTACK ) )
		return qfalse;

	VectorCopy( playerState->pmove.origin, origin );
	origin[2] += playerState->viewheight;
	AngleVectors( playerState->viewangles, dir, NULL, NULL );
	VectorMA( origin, weapondef->firedef_weak.timeout, dir, end );

	// check for a player to touch
	module_Trace( &trace, origin, vec3_origin, vec3_origin, end, playerState->POVnum, CONTENTS_BODY, timeDelta );
	if( trace.ent <= 0 || trace.ent > gs.maxclients )
		return qfalse;

	player = module_GetEntityState( playerState->POVnum, 0 );
	targ = module_GetEntityState( trace.ent, 0 );
	if( !( targ->effects & EF_TAKEDAMAGE ) || targ->type != ET_PLAYER )
		return qfalse;

	if( GS_TeamBasedGametype() && ( targ->team == player->team ) )
		return qfalse;

	return qtrue;
}
Esempio n. 5
0
void GS_TraceCurveLaserBeam( trace_t *trace, vec3_t origin, vec3_t angles, vec3_t blendPoint, int ignore, int timeDelta, void ( *impact )( trace_t *tr, vec3_t dir ) )
{
	float frac, subdivisions = CURVELASERBEAM_SUBDIVISIONS;
	float range = (float)GS_GetWeaponDef( WEAP_LASERGUN )->firedef_weak.timeout;
	vec3_t from, dir, end;
	int passthrough = ignore;

	int i, j;
	vec3_t tmpangles, blendAngles;

	assert( trace );

	VectorCopy( origin, from );
	VectorSubtract( blendPoint, origin, dir );
	VecToAngles( dir, blendAngles );

	for( i = 1; i <= (int)subdivisions; i++ )
	{
		frac = ( ( range/subdivisions )*(float)i ) / (float)range;

		for( j = 0; j < 3; j++ )
			tmpangles[j] = LerpAngle( angles[j], blendAngles[j], frac );

		AngleVectors( tmpangles, dir, NULL, NULL );
		VectorMA( origin, range * frac, dir, end );

		GS_TraceLaserBeam( trace, from, tmpangles, DistanceFast( from, end ), passthrough, timeDelta, impact );
		if( trace->fraction != 1.0f )
			break;

		passthrough = trace->ent;
		VectorCopy( end, from );
	}
}
Esempio n. 6
0
/*
* CG_Event_FireRiotgun
*/
static void CG_Event_FireRiotgun( vec3_t origin, vec3_t dir, int weapon, int firemode, int seed, int owner ) 
{
	trace_t	trace;
	vec3_t end;
	gs_weapon_definition_t *weapondef = GS_GetWeaponDef( weapon );
	firedef_t *firedef = ( firemode ) ? &weapondef->firedef : &weapondef->firedef_weak;

	CG_Fire_SpiralPattern( origin, dir, &seed, owner, firedef->projectile_count, firedef->spread, firedef->timeout, CG_BulletImpact );

	// spawn a single sound at the impact
	VectorMA( origin, firedef->timeout, dir, end );
	CG_Trace( &trace, origin, vec3_origin, vec3_origin, end, owner, MASK_SHOT );

	if( trace.ent != -1 && !( trace.surfFlags & SURF_NOIMPACT ) )
	{
		if( firedef->fire_mode == FIRE_MODE_STRONG )
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRiotgunStrongHit ), trace.endpos, CHAN_AUTO,
				cg_volume_effects->value, ATTN_IDLE );
		}
		else
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRiotgunWeakHit ), trace.endpos, CHAN_AUTO,
				cg_volume_effects->value, ATTN_IDLE );
		}
	}
}
Esempio n. 7
0
/*
* Pickup_Weapon
*/
bool Pickup_Weapon( edict_t *other, const gsitem_t *item, int flags, int ammo_count )
{
	int ammo_tag;
	gs_weapon_definition_t *weapondef;

	weapondef = GS_GetWeaponDef( item->tag );

	other->r.client->ps.inventory[item->tag]++;

	// never allow the player to carry more than 2 copies of the same weapon
	if( other->r.client->ps.inventory[item->tag] > item->inventory_max )
		other->r.client->ps.inventory[item->tag] = item->inventory_max;

	if( !(flags & DROPPED_ITEM) )
	{
		// give them some ammo with it
		ammo_tag = item->ammo_tag;
		if( ammo_tag )
			Add_Ammo( other->r.client, GS_FindItemByTag( ammo_tag ), weapondef->firedef.weapon_pickup, true );
	}
	else
	{    
		// it's a dropped weapon
		ammo_tag = item->ammo_tag;
		if( ammo_count && ammo_tag )
			Add_Ammo( other->r.client, GS_FindItemByTag( ammo_tag ), ammo_count, true );
	}

	return true;
}
Esempio n. 8
0
/*
* GS_InitWeapons
*/
void GS_InitWeapons( void )
{
	int i;
	gsitem_t *item;
	gs_weapon_definition_t *weapondef;

	for( i = WEAP_GUNBLADE; i < WEAP_TOTAL; i++ )
	{
		item = GS_FindItemByTag( i );
		weapondef = GS_GetWeaponDef( i );

		assert( item && weapondef );

		// hack : use the firedef pickup counts on items
		if( item->weakammo_tag && GS_FindItemByTag( item->weakammo_tag ) )
		{
			GS_FindItemByTag( item->weakammo_tag )->quantity = weapondef->firedef_weak.ammo_pickup;
			GS_FindItemByTag( item->weakammo_tag )->inventory_max = weapondef->firedef_weak.ammo_max;
		}

		if( item->ammo_tag && GS_FindItemByTag( item->ammo_tag ) )
		{
			GS_FindItemByTag( item->ammo_tag )->quantity = weapondef->firedef.ammo_pickup;
			GS_FindItemByTag( item->ammo_tag )->inventory_max = weapondef->firedef.ammo_max;
		}
	}
}
Esempio n. 9
0
/*
* CG_Event_WeaponBeam
*/
static void CG_Event_WeaponBeam( vec3_t origin, vec3_t dir, int ownerNum, int weapon, int firemode )
{
	gs_weapon_definition_t *weapondef;
	int range;
	vec3_t end;
	trace_t trace;

	switch( weapon )
	{
	case WEAP_ELECTROBOLT:
		weapondef = GS_GetWeaponDef( WEAP_ELECTROBOLT );
		range = ELECTROBOLT_RANGE;
		break;

	case WEAP_INSTAGUN:
		weapondef = GS_GetWeaponDef( WEAP_INSTAGUN );
		range = weapondef->firedef.timeout;
		break;

	default:
		return;
	}

	VectorNormalizeFast( dir );

	VectorMA( origin, range, dir, end );

	// retrace to spawn wall impact
	CG_Trace( &trace, origin, vec3_origin, vec3_origin, end, cg.view.POVent, MASK_SOLID );
	if( trace.ent != -1 && !(trace.surfFlags & (SURF_SKY|SURF_NOMARKS|SURF_NOIMPACT)) )
	{
		if( weapondef->weapon_id == WEAP_ELECTROBOLT )
			CG_BoltExplosionMode( trace.endpos, trace.plane.normal, FIRE_MODE_STRONG );
		else if( weapondef->weapon_id == WEAP_INSTAGUN )
			CG_InstaExplosionMode( trace.endpos, trace.plane.normal, FIRE_MODE_STRONG );
	}

	// when it's predicted we have to delay the drawing until the view weapon is calculated
	cg_entities[ownerNum].localEffects[LOCALEFFECT_EV_WEAPONBEAM] = weapon;
	VectorCopy( origin, cg_entities[ownerNum].laserOrigin );
	VectorCopy( trace.endpos, cg_entities[ownerNum].laserPoint );
}
Esempio n. 10
0
/*
* GS_FiredefForPlayerState
*/
firedef_t *GS_FiredefForPlayerState( player_state_t *playerState, int checkweapon )
{
	gs_weapon_definition_t *weapondef;

	weapondef = GS_GetWeaponDef( checkweapon );

	//find out our current fire mode
	if( playerState->inventory[weapondef->firedef.ammo_id] >= weapondef->firedef.usage_count )
		return &weapondef->firedef;

	return &weapondef->firedef_weak;
}
Esempio n. 11
0
void CG_Event_LaserBeam( int entNum, int weapon, int fireMode )
{
	centity_t *cent = &cg_entities[entNum];
	unsigned int timeout;
	vec3_t dir;

	if( !cg_predictLaserBeam->integer )
		return;

	// lasergun's smooth refire
	if( fireMode == FIRE_MODE_STRONG )
	{
		cent->laserCurved = qfalse;
		timeout = GS_GetWeaponDef( WEAP_LASERGUN )->firedef.reload_time + 10;

		// find destiny point
		VectorCopy( cg.predictedPlayerState.pmove.origin, cent->laserOrigin );
		cent->laserOrigin[2] += cg.predictedPlayerState.viewheight;
		AngleVectors( cg.predictedPlayerState.viewangles, dir, NULL, NULL );
		VectorMA( cent->laserOrigin, GS_GetWeaponDef( WEAP_LASERGUN )->firedef.timeout, dir, cent->laserPoint );
	}
	else
	{
		cent->laserCurved = qtrue;
		timeout = GS_GetWeaponDef( WEAP_LASERGUN )->firedef_weak.reload_time + 10;

		// find destiny point
		VectorCopy( cg.predictedPlayerState.pmove.origin, cent->laserOrigin );
		cent->laserOrigin[2] += cg.predictedPlayerState.viewheight;
		if( !G_GetLaserbeamPoint( &cg.weaklaserTrail, &cg.predictedPlayerState, cg.predictingTimeStamp, cent->laserPoint ) )
		{
			AngleVectors( cg.predictedPlayerState.viewangles, dir, NULL, NULL );
			VectorMA( cent->laserOrigin, GS_GetWeaponDef( WEAP_LASERGUN )->firedef.timeout, dir, cent->laserPoint );
		}
	}

	VectorCopy( cent->laserOrigin, cent->laserOriginOld );
	VectorCopy( cent->laserPoint, cent->laserPointOld );
	cent->localEffects[LOCALEFFECT_LASERBEAM] = cg.time + timeout;
}
Esempio n. 12
0
/*
* SetItemNames
* 
* Called by worldspawn
*/
void G_PrecacheItems( void )
{
	int i;
	gsitem_t *item;

	// precache item names and weapondefs
	for( i = 1; ( item = GS_FindItemByTag( i ) ) != NULL; i++ )
	{
		trap_ConfigString( CS_ITEMS + i, item->name );

		if( item->type & IT_WEAPON && GS_GetWeaponDef( item->tag ) )
		{
			G_PrecacheWeapondef( i, &GS_GetWeaponDef( item->tag )->firedef );
			G_PrecacheWeapondef( i, &GS_GetWeaponDef( item->tag )->firedef_weak );
		}
	}

	// precache items
	if( GS_Instagib() )
	{
		item = GS_FindItemByTag( WEAP_INSTAGUN );
		PrecacheItem( item );
	}
	else
	{
		for( i = WEAP_GUNBLADE; i < WEAP_TOTAL; i++ )
		{
			item = GS_FindItemByTag( i );
			PrecacheItem( item );
		}
	}

	// Vic: precache ammo pack if it's droppable
	item = GS_FindItemByClassname( "item_ammopack" );
	if( item && G_Gametype_CanDropItem( item, qtrue ) )
	{
		PrecacheItem( item );
	}
}
Esempio n. 13
0
/*
* GS_SelectBestWeapon
*/
int GS_SelectBestWeapon( player_state_t *playerState )
{
	int weap, weap_chosen = WEAP_NONE;
	gs_weapon_definition_t *weapondef;

	//find with strong ammos
	for( weap = WEAP_TOTAL-1; weap > WEAP_GUNBLADE; weap-- )
	{
		if( !playerState->inventory[weap] )
			continue;

		weapondef = GS_GetWeaponDef( weap );

		if( !weapondef->firedef.usage_count ||
			playerState->inventory[weapondef->firedef.ammo_id] >= weapondef->firedef.usage_count )
		{
			weap_chosen = weap;
			goto found;
		}
	}

	//repeat find with weak ammos
	for( weap = WEAP_TOTAL-1; weap >= WEAP_NONE; weap-- )
	{
		if( !playerState->inventory[weap] )
			continue;

		weapondef = GS_GetWeaponDef( weap );

		if( !weapondef->firedef_weak.usage_count ||
			playerState->inventory[weapondef->firedef_weak.ammo_id] >= weapondef->firedef_weak.usage_count )
		{
			weap_chosen = weap;
			goto found;
		}
	}
found:
	return weap_chosen;
}
Esempio n. 14
0
/*
* Use_Weapon
*/
void Use_Weapon( edict_t *ent, const gsitem_t *item )
{
	int ammocount, weakammocount;
	gs_weapon_definition_t *weapondef;

	//invalid weapon item
	if( item->tag < WEAP_NONE || item->tag >= WEAP_TOTAL )
		return;

	// see if we're already changing to it
	if( ent->r.client->ps.stats[STAT_PENDING_WEAPON] == item->tag )
		return;

	weapondef = GS_GetWeaponDef( item->tag );

	if( !g_select_empty->integer && !( item->type & IT_AMMO ) )
	{
		if( weapondef->firedef.usage_count )
		{
			if( weapondef->firedef.ammo_id )
				ammocount = ent->r.client->ps.inventory[weapondef->firedef.ammo_id];
			else
				ammocount = weapondef->firedef.usage_count;
		}
		else
			ammocount = 1; // can change weapon

		if( weapondef->firedef_weak.usage_count )
		{
			if( weapondef->firedef_weak.ammo_id )
				weakammocount = ent->r.client->ps.inventory[weapondef->firedef_weak.ammo_id];
			else
				weakammocount = weapondef->firedef_weak.usage_count;
		}
		else
			weakammocount = 1; // can change weapon

		if( ammocount < weapondef->firedef.usage_count &&
			weakammocount < weapondef->firedef_weak.usage_count )
		{
			return;
		}
	}

	// change to this weapon when down
	ent->r.client->ps.stats[STAT_PENDING_WEAPON] = item->tag;
}
Esempio n. 15
0
static void WeaponString( edict_t *who, int weapon, char *buf, int buflen, const char *current_color )
{
	int strong_ammo, weak_ammo;
	gs_weapon_definition_t *weapondef = GS_GetWeaponDef( weapon );

	Q_snprintfz( buf, buflen, "%s%s%s", ( GS_FindItemByTag( weapon )->color ? GS_FindItemByTag( weapon )->color : "" ),
		GS_FindItemByTag( weapon )->shortname, current_color );

	strong_ammo = who->r.client->ps.inventory[weapondef->firedef.ammo_id];
	weak_ammo = who->r.client->ps.inventory[weapondef->firedef_weak.ammo_id];
	if( weapon == WEAP_GUNBLADE )
		Q_strncatz( buf, va( ":%i", strong_ammo ), buflen );
	else if( strong_ammo > 0 )
		Q_strncatz( buf, va( ":%i/%i", strong_ammo, weak_ammo ), buflen );
	else
		Q_strncatz( buf, va( ":%i", weak_ammo ), buflen );
}
Esempio n. 16
0
void GS_AddLaserbeamPoint( gs_laserbeamtrail_t *trail, player_state_t *playerState,
						  unsigned int timeStamp )
{
	vec3_t origin, dir;
	int range = GS_GetWeaponDef( WEAP_LASERGUN )->firedef_weak.timeout;

	if( !timeStamp )
		return;

	origin[0] = playerState->pmove.origin[0];
	origin[1] = playerState->pmove.origin[1];
	origin[2] = playerState->pmove.origin[2] + playerState->viewheight;
	AngleVectors( playerState->viewangles, dir, NULL, NULL );

	VectorMA( origin, range, dir, trail->origins[trail->head & LASERGUN_WEAK_TRAIL_MASK] );
	trail->timeStamps[trail->head & LASERGUN_WEAK_TRAIL_MASK] = timeStamp;
	trail->teleported[trail->head & LASERGUN_WEAK_TRAIL_MASK] = ( playerState->pmove.pm_flags & PMF_TIME_TELEPORT ) ? qtrue : qfalse;
	trail->head++;
}
Esempio n. 17
0
static void CG_Event_FireMachinegun( vec3_t origin, vec3_t dir, int weapon, int firemode, int seed, int owner )
{
	float r, u;
	double alpha, s;
	trace_t trace, *water_trace;
	gs_weapon_definition_t *weapondef = GS_GetWeaponDef( weapon );
	firedef_t *firedef = ( firemode ) ? &weapondef->firedef : &weapondef->firedef_weak;
	int range = firedef->timeout, spread = firedef->spread;

	// circle shape
	alpha = M_PI * Q_crandom( &seed ); // [-PI ..+PI]
	s = fabs( Q_crandom( &seed ) ); // [0..1]
	r = s * cos( alpha ) * spread;
	u = s * sin( alpha ) * spread;

	water_trace = GS_TraceBullet( &trace, origin, dir, r, u, range, owner, 0 );
	if( water_trace )
	{
		if( !VectorCompare( water_trace->endpos, origin ) )
			CG_LeadWaterSplash( water_trace );
	}

	if( trace.ent != -1 && !( trace.surfFlags & SURF_NOIMPACT ) )
	{
		CG_BulletImpact( &trace );

		if( !water_trace )
		{
			if( trace.surfFlags & SURF_FLESH ||
				( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_PLAYER ) ||
				( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_CORPSE ) )
			{
				// flesh impact sound
			}
			else
				trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRic[ rand()&2 ] ), trace.endpos, CHAN_AUTO, cg_volume_effects->value, ATTN_STATIC );
		}
	}

	if( water_trace )
		CG_LeadBubbleTrail( &trace, water_trace->endpos );
}
Esempio n. 18
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];
}
Esempio n. 19
0
/*
* G_FireWeapon
*/
void G_FireWeapon( edict_t *ent, int parm )
{
	gs_weapon_definition_t *weapondef;
	firedef_t *firedef;
	edict_t *projectile;
	vec3_t origin, angles;
	vec3_t viewoffset = { 0, 0, 0 };
	int ucmdSeed;

	weapondef = GS_GetWeaponDef( ( parm & ~EV_INVERSE ) );
	firedef = ( parm & EV_INVERSE ) ? &weapondef->firedef : &weapondef->firedef_weak;

	// find this shot projection source
	if( ent->r.client )
	{
		viewoffset[2] += ent->r.client->ps.viewheight;
		VectorCopy( ent->r.client->ps.viewangles, angles );
		is_quad = ( ent->r.client->ps.inventory[POWERUP_QUAD] > 0 ) ? true : false;
		ucmdSeed = ent->r.client->ucmd.serverTimeStamp & 255;
	}
	else
	{
		VectorCopy( ent->s.angles, angles );
		is_quad = false;
		ucmdSeed = rand() & 255;
	}

	VectorAdd( ent->s.origin, viewoffset, origin );


	// shoot 

	projectile = NULL;

	switch( weapondef->weapon_id )
	{
	default:
	case WEAP_NONE:
		break;

	case WEAP_GUNBLADE:
		if( firedef->fire_mode == FIRE_MODE_STRONG )
			projectile = G_Fire_Gunblade_Blast( origin, angles, firedef, ent, ucmdSeed );
		else
			projectile = G_Fire_Gunblade_Knife( origin, angles, firedef, ent );
		break;

	case WEAP_MACHINEGUN:
		projectile = G_Fire_Machinegun( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_RIOTGUN:
		projectile = G_Fire_Riotgun( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_GRENADELAUNCHER:
		projectile = G_Fire_Grenade( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_ROCKETLAUNCHER:
		projectile = G_Fire_Rocket( origin, angles, firedef, ent, ucmdSeed );
		break;
	case WEAP_PLASMAGUN:
		projectile = G_Fire_Plasma( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_LASERGUN:
		projectile = G_Fire_Lasergun( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_ELECTROBOLT:
		projectile = G_Fire_StrongBolt( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_INSTAGUN:
		projectile = G_Fire_Instagun( origin, angles, firedef, ent, ucmdSeed );
		break;
	}

	// add stats
	if( ent->r.client && weapondef->weapon_id != WEAP_NONE ) 
		ent->r.client->level.stats.accuracy_shots[firedef->ammo_id - AMMO_GUNBLADE] += firedef->projectile_count;

	if( projectile )
	{
		//if( projectile->s.linearProjectile ) // convert distance to time for linear projectiles
		//	G_ProjectileTimePrestep( projectile, 1000.0f * ( g_projectile_prestep->value / VectorLengthFast( projectile->velocity ) ) );
		//else
			G_ProjectileDistancePrestep( projectile, g_projectile_prestep->value );
	}

#ifdef NO_ROCKET_ANTILAG
	// hack for disabling antilag on rockets
	if( projectile && projectile->s.type == ET_ROCKET )
	{
		int timeOffset;

		timeOffset = -projectile->timeDelta;
		projectile->timeDelta = 0;
		if( projectile->s.linearProjectile )
			projectile->s.modelindex2 = 0;

		G_ProjectileTimePrestep( projectile, timeOffset );
	}
#endif
}
Esempio n. 20
0
/*
* GS_Cmd_UseItem
*/
gsitem_t *GS_Cmd_UseItem( player_state_t *playerState, const char *string, int typeMask )
{
	gsitem_t *item = NULL;

	assert( playerState );

	if( playerState->pmove.pm_type >= PM_SPECTATOR )
		return NULL;

	if( !string || !string[0] )
		return NULL;

	if( Q_isdigit( string ) )
	{
		int tag = atoi( string );
		item = GS_FindItemByTag( tag );
	}
	else
		item = GS_FindItemByName( string );

	if( !item )
		return NULL;

	if( typeMask && !( item->type & typeMask ) )
		return NULL;

	// we don't have this item in the inventory
	if( !playerState->inventory[item->tag] )
	{
		if( gs.module == GS_MODULE_CGAME && !( item->type & IT_WEAPON ) )
			module_Printf( "Item %s is not in inventory\n", item->name );
		return NULL;
	}

	// see if we can use it

	if( !(item->flags & ITFLAG_USABLE) )
		return NULL;

	if( item->type & IT_WEAPON )
	{
		if( !( playerState->pmove.stats[PM_STAT_FEATURES] & PMFEAT_WEAPONSWITCH ) )
			return NULL;

		if( item->tag == playerState->stats[STAT_PENDING_WEAPON] )  // it's already being loaded
			return NULL;

		// check for need of any kind of ammo/fuel/whatever
		if( item->ammo_tag != AMMO_NONE && item->weakammo_tag != AMMO_NONE )
		{
			gs_weapon_definition_t *weapondef = GS_GetWeaponDef( item->tag );

			if( weapondef )
			{	
				// do we have any of these ammos ?
				if( playerState->inventory[item->weakammo_tag] >= weapondef->firedef_weak.usage_count )
					return item;

				if( playerState->inventory[item->ammo_tag] >= weapondef->firedef.usage_count )
					return item;
			}

			return NULL;
		}

		return item; // one of the weapon modes doesn't require ammo to be fired
	}

	if( item->type & IT_AMMO )
		return item;

	if( item->type & IT_HEALTH )
		return item;

	if( item->type & IT_POWERUP )
		return item;

	return NULL;
}
Esempio n. 21
0
/*
* W_Fire_Electrobolt_Combined
*/
void W_Fire_Electrobolt_Combined( edict_t *self, vec3_t start, vec3_t angles, float maxdamage, float mindamage, float maxknockback, float minknockback, int stun, int range, int mod, int timeDelta )
{
	vec3_t from, end, dir;
	trace_t	tr;
	edict_t	*ignore, *event, *hit, *damaged;
	int mask;
	qboolean missed = qtrue;
	int dmgflags = 0;
	int fireMode;

#ifdef ELECTROBOLT_TEST
	fireMode = FIRE_MODE_WEAK;
#else
	fireMode = FIRE_MODE_STRONG;
#endif

	if( GS_Instagib() )
		maxdamage = mindamage = 9999;

	AngleVectors( angles, dir, NULL, NULL );
	VectorMA( start, range, dir, end );
	VectorCopy( start, from );

	ignore = self;
	hit = damaged = NULL;

	mask = MASK_SHOT;
	if( GS_RaceGametype() )
		mask = MASK_SOLID;

	clamp_high( mindamage, maxdamage );
	clamp_high( minknockback, maxknockback );

	tr.ent = -1;
	while( ignore )
	{
		G_Trace4D( &tr, from, NULL, NULL, end, ignore, mask, timeDelta );

		VectorCopy( tr.endpos, from );
		ignore = NULL;

		if( tr.ent == -1 )
			break;

		// some entity was touched
		hit = &game.edicts[tr.ent];
		if( hit == world )  // stop dead if hit the world
			break;
		if( hit->movetype == MOVETYPE_NONE || hit->movetype == MOVETYPE_PUSH )
			break;

		// allow trail to go through BBOX entities (players, gibs, etc)
		if( !ISBRUSHMODEL( hit->s.modelindex ) )
			ignore = hit;

		if( ( hit != self ) && ( hit->takedamage ) )
		{
			float frac, damage, knockback;

			frac = DistanceFast( tr.endpos, start ) / (float)range;
			clamp( frac, 0.0f, 1.0f );

			damage = maxdamage - ( ( maxdamage - mindamage ) * frac );
			knockback = maxknockback - ( ( maxknockback - minknockback ) * frac );

			G_Damage( hit, self, self, dir, dir, tr.endpos, damage, knockback, stun, dmgflags, mod );
			
			// spawn a impact event on each damaged ent
			event = G_SpawnEvent( EV_BOLT_EXPLOSION, DirToByte( tr.plane.normal ), tr.endpos );
			event->s.firemode = fireMode;
			if( hit->r.client )
				missed = qfalse;

			damaged = hit;
		}
	}

	if( missed && self->r.client )
		G_AwardPlayerMissedElectrobolt( self, mod );

	// send the weapon fire effect
	event = G_SpawnEvent( EV_ELECTROTRAIL, ENTNUM( self ), start );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorScale( dir, 1024, event->s.origin2 );
	event->s.firemode = fireMode;

	if( !GS_Instagib() && tr.ent == -1 )	// didn't touch anything, not even a wall
	{
		edict_t *bolt;
		gs_weapon_definition_t *weapondef = GS_GetWeaponDef( self->s.weapon );

		// fire a weak EB from the end position
		bolt = W_Fire_Electrobolt_Weak( self, end, angles, weapondef->firedef_weak.speed, mindamage, minknockback, minknockback, stun, weapondef->firedef_weak.timeout, mod, timeDelta );
		bolt->enemy = damaged;
	}
}
Esempio n. 22
0
void CG_LaserBeamEffect( centity_t *cent )
{
	struct sfx_s *sound = NULL;
	float range;
	trace_t trace;
	orientation_t projectsource;
	vec4_t color;
	vec3_t laserOrigin, laserAngles, laserPoint;
	int i, j;

	if( cent->localEffects[LOCALEFFECT_LASERBEAM] <= cg.time )
		return;

	laserOwner = cent;

	if( cg_teamColoredBeams->integer && ( cent->current.team == TEAM_ALPHA || cent->current.team == TEAM_BETA ) )
		CG_TeamColor( cent->current.team, color );
	else
		Vector4Set( color, 1, 1, 1, 1 );

	// interpolate the positions

	if( ISVIEWERENTITY( cent->current.number ) && !cg.view.thirdperson )
	{
		VectorCopy( cg.predictedPlayerState.pmove.origin, laserOrigin );
		laserOrigin[2] += cg.predictedPlayerState.viewheight;
		VectorCopy( cg.predictedPlayerState.viewangles, laserAngles );

		VectorLerp( cent->laserPointOld, cg.lerpfrac, cent->laserPoint, laserPoint );
	}
	else
	{
		VectorLerp( cent->laserOriginOld, cg.lerpfrac, cent->laserOrigin, laserOrigin );
		VectorLerp( cent->laserPointOld, cg.lerpfrac, cent->laserPoint, laserPoint );
		if( !cent->laserCurved )
		{
			vec3_t dir;

			// make up the angles from the start and end points (s->angles is not so precise)
			VectorSubtract( laserPoint, laserOrigin, dir );
			VecToAngles( dir, laserAngles );
		}
		else // use player entity angles
		{
			for( i = 0; i < 3; i++ )
				laserAngles[i] = LerpAngle( cent->prev.angles[i], cent->current.angles[i], cg.lerpfrac );
		}
	}

	if( !cent->laserCurved )
	{
		range = GS_GetWeaponDef( WEAP_LASERGUN )->firedef.timeout;

		if( cent->current.effects & EF_QUAD )
			sound = CG_MediaSfx( cgs.media.sfxLasergunStrongQuadHum );
		else
			sound = CG_MediaSfx( cgs.media.sfxLasergunStrongHum );

		// trace the beam: for tracing we use the real beam origin
		GS_TraceLaserBeam( &trace, laserOrigin, laserAngles, range, cent->current.number, 0, _LaserImpact );
		
		// draw the beam: for drawing we use the weapon projection source (already handles the case of viewer entity)
		if( !CG_PModel_GetProjectionSource( cent->current.number, &projectsource ) )
			VectorCopy( laserOrigin, projectsource.origin );

		CG_KillPolyBeamsByTag( cent->current.number );
		CG_LaserGunPolyBeam( projectsource.origin, trace.endpos, color, cent->current.number );
	}
	else
	{
		float frac, subdivisions = cg_laserBeamSubdivisions->integer;
		vec3_t from, dir, end, blendPoint;
		int passthrough = cent->current.number;
		vec3_t tmpangles, blendAngles;

		range = GS_GetWeaponDef( WEAP_LASERGUN )->firedef_weak.timeout;

		if( cent->current.effects & EF_QUAD )
			sound = CG_MediaSfx( cgs.media.sfxLasergunWeakQuadHum );
		else
			sound = CG_MediaSfx( cgs.media.sfxLasergunWeakHum );

		// trace the beam: for tracing we use the real beam origin
		GS_TraceCurveLaserBeam( &trace, laserOrigin, laserAngles, laserPoint, cent->current.number, 0, _LaserImpact );

		// draw the beam: for drawing we use the weapon projection source (already handles the case of viewer entity)
		if( !CG_PModel_GetProjectionSource( cent->current.number, &projectsource ) )
			VectorCopy( laserOrigin, projectsource.origin );

		if( subdivisions < CURVELASERBEAM_SUBDIVISIONS )
			subdivisions = CURVELASERBEAM_SUBDIVISIONS;

		CG_KillPolyBeamsByTag( cent->current.number );

		// we redraw the full beam again, and trace each segment for stop dead impact
		VectorCopy( laserPoint, blendPoint );
		VectorCopy( projectsource.origin, from );
		VectorSubtract( blendPoint, projectsource.origin, dir );
		VecToAngles( dir, blendAngles );

		for( i = 1; i <= (int)subdivisions; i++ )
		{
			frac = ( ( range/subdivisions )*(float)i ) / (float)range;

			for( j = 0; j < 3; j++ )
				tmpangles[j] = LerpAngle( laserAngles[j], blendAngles[j], frac );

			AngleVectors( tmpangles, dir, NULL, NULL );
			VectorMA( projectsource.origin, range * frac, dir, end );

			GS_TraceLaserBeam( &trace, from, tmpangles, DistanceFast( from, end ), passthrough, 0, NULL );
			CG_LaserGunPolyBeam( from, trace.endpos, color, cent->current.number );
			if( trace.fraction != 1.0f )
				break;

			passthrough = trace.ent;
			VectorCopy( trace.endpos, from );
		}
	}

	// enable continuous flash on the weapon owner
	if( cg_weaponFlashes->integer )
		cg_entPModels[cent->current.number].flash_time = cg.time + CG_GetWeaponInfo( WEAP_LASERGUN )->flashTime;

	if( sound )
	{
		if( ISVIEWERENTITY( cent->current.number ) )
			trap_S_AddLoopSound( sound, cent->current.number, 1.0, ATTN_NONE );
		else
			trap_S_AddLoopSound( sound, cent->current.number, 1.0, ATTN_STATIC );
	}

	laserOwner = NULL;
}
Esempio n. 23
0
/*
* G_RadiusDamage
*/
void G_RadiusDamage( edict_t *inflictor, edict_t *attacker, cplane_t *plane, edict_t *ignore, int mod )
{
	edict_t *ent = NULL;
	float dmgFrac, kickFrac, damage, knockback, stun;
	vec3_t pushDir;
	int timeDelta;

	float maxdamage, mindamage, maxknockback, minknockback, maxstun, minstun, radius;

	assert( inflictor );

	maxdamage = inflictor->projectileInfo.maxDamage;
	mindamage = inflictor->projectileInfo.minDamage;
	maxknockback = inflictor->projectileInfo.maxKnockback;
	minknockback = inflictor->projectileInfo.minKnockback;
	maxstun = inflictor->projectileInfo.stun;
	minstun = 1;
	radius = inflictor->projectileInfo.radius;

	if( radius <= 1.0f || ( maxdamage <= 0.0f && maxknockback <= 0.0f ) )
		return;

	clamp_high( mindamage, maxdamage );
	clamp_high( minknockback, maxknockback );
	clamp_high( minstun, maxstun );

	while( ( ent = GClip_FindBoxInRadius4D( ent, inflictor->s.origin, radius, inflictor->timeDelta ) ) != NULL )
	{
		if( ent == ignore || !ent->takedamage )
			continue;

		if( ent == attacker && ent->r.client )
			timeDelta = 0;
		else
			timeDelta = inflictor->timeDelta;

		G_SplashFrac4D( ENTNUM( ent ), inflictor->s.origin, radius, pushDir, &kickFrac, &dmgFrac, timeDelta );

		damage = max( 0, mindamage + ( ( maxdamage - mindamage ) * dmgFrac ) );
		stun = max( 0, minstun + ( ( maxstun - minstun ) * dmgFrac ) );
		knockback = max( 0, minknockback + ( ( maxknockback - minknockback ) * kickFrac ) );

		// weapon jumps hack : when knockback on self, use strong weapon definition
		if( ent == attacker && ent->r.client )
		{
			gs_weapon_definition_t *weapondef = NULL;
			if( inflictor->s.type == ET_ROCKET )
				weapondef = GS_GetWeaponDef( WEAP_ROCKETLAUNCHER );
			else if( inflictor->s.type == ET_GRENADE )
				weapondef = GS_GetWeaponDef( WEAP_GRENADELAUNCHER );
			else if( inflictor->s.type == ET_PLASMA )
				weapondef = GS_GetWeaponDef( WEAP_PLASMAGUN );
			else if( inflictor->s.type == ET_BLASTER )
				weapondef = GS_GetWeaponDef( WEAP_GUNBLADE );

			if( weapondef )
			{
				G_SplashFrac4D( ENTNUM( ent ), inflictor->s.origin, radius, pushDir, &kickFrac, NULL, 0 );

				minknockback = weapondef->firedef.minknockback;
				maxknockback = weapondef->firedef.knockback;
				clamp_high( minknockback, maxknockback );
				knockback = ( minknockback + ( (float)( maxknockback - minknockback ) * kickFrac ) ) * g_self_knockback->value;
				damage *= weapondef->firedef.selfdamage;
			}
		}

		if( knockback < 1.0f )
			knockback = 0.0f;

		if( stun < 1.0f )
			stun = 0.0f;

		if( damage <= 0.0f && knockback <= 0.0f && stun <= 0.0f )
			continue;

		if( G_CanSplashDamage( ent, inflictor, plane ) )
			G_Damage( ent, inflictor, attacker, pushDir, inflictor->velocity, inflictor->s.origin, damage, knockback, stun, DAMAGE_RADIUS, mod );
	}
}
Esempio n. 24
0
/*
* G_FireWeapon
*/
void G_FireWeapon( edict_t *ent, int parm )
{
	gs_weapon_definition_t *weapondef;
	firedef_t *firedef;
	edict_t *projectile;
	vec3_t origin, angles;
	vec3_t viewoffset = { 0, 0, 0 };
	int ucmdSeed;
	// racesow
	float prestep;
	// !racesow

	weapondef = GS_GetWeaponDef( ( parm & ~EV_INVERSE ) );
	firedef = ( parm & EV_INVERSE ) ? &weapondef->firedef : &weapondef->firedef_weak;

	// find this shot projection source
	if( ent->r.client )
	{
		viewoffset[2] += ent->r.client->ps.viewheight;
		VectorCopy( ent->r.client->ps.viewangles, angles );
		is_quad = ( ent->r.client->ps.inventory[POWERUP_QUAD] > 0 );
		ucmdSeed = ent->r.client->ucmd.serverTimeStamp & 255;
	}
	else
	{
		VectorCopy( ent->s.angles, angles );
		is_quad = qfalse;
		ucmdSeed = rand() & 255;
	}

	VectorAdd( ent->s.origin, viewoffset, origin );

	// racesow
	prestep=g_projectile_prestep->value;
	// !racesow

	// shoot 

	projectile = NULL;

	switch( weapondef->weapon_id )
	{
	default:
	case WEAP_NONE:
		break;

	case WEAP_GUNBLADE:
		if( firedef->fire_mode == FIRE_MODE_STRONG )
			projectile = G_Fire_Gunblade_Blast( origin, angles, firedef, ent, ucmdSeed );
		else
			projectile = G_Fire_Gunblade_Knife( origin, angles, firedef, ent );
		break;

	case WEAP_MACHINEGUN:
		projectile = G_Fire_Machinegun( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_RIOTGUN:
		projectile = G_Fire_Riotgun( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_GRENADELAUNCHER:
		projectile = G_Fire_Grenade( origin, angles, firedef, ent, ucmdSeed );
		// racesow
		if( GS_RaceGametype() )
			//prestep/=2; // racesow 0.42 had default prestep=48 and genade prestep=24
			prestep=trap_Cvar_Get( "rs_grenade_prestep", "90", CVAR_ARCHIVE )->integer;
		// !racesow
		break;

	case WEAP_ROCKETLAUNCHER:
		projectile = G_Fire_Rocket( origin, angles, firedef, ent, ucmdSeed );
		// racesow
		if( GS_RaceGametype() )
			//prestep=0; // racesow 0.42 had rocket prestep=0
			prestep=trap_Cvar_Get( "rs_rocket_prestep", "90", CVAR_ARCHIVE )->integer;
		// !racesow
		break;
	case WEAP_PLASMAGUN:
		projectile = G_Fire_Plasma( origin, angles, firedef, ent, ucmdSeed );
		// racesow
		if( GS_RaceGametype() )
			//prestep*=2/3; // racesow 0.42 had plasma prestep=32
			prestep=trap_Cvar_Get( "rs_plasma_prestep", "90", CVAR_ARCHIVE )->integer;
		// !racesow
		break;

	case WEAP_LASERGUN:
		projectile = G_Fire_Lasergun( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_ELECTROBOLT:
		projectile = G_Fire_StrongBolt( origin, angles, firedef, ent, ucmdSeed );
		break;

	case WEAP_INSTAGUN:
		projectile = G_Fire_Instagun( origin, angles, firedef, ent, ucmdSeed );
		break;
	}

	// add stats
	if( ent->r.client && weapondef->weapon_id != WEAP_NONE ) 
		ent->r.client->level.stats.accuracy_shots[firedef->ammo_id - AMMO_GUNBLADE] += firedef->projectile_count;

	if( projectile )
	{
		//if( projectile->s.linearProjectile ) // convert distance to time for linear projectiles
		//	G_ProjectileTimePrestep( projectile, 1000.0f * ( g_projectile_prestep->value / VectorLengthFast( projectile->velocity ) ) );
		//else
			//G_ProjectileDistancePrestep( projectile, g_projectile_prestep->value ); //racesow Seems like this was added in warsow 0.7 -K1ll
		// racesow: modified prestep
		G_ProjectileDistancePrestep( projectile, prestep );
		// !racesow
	}

	// racesow: enable skipping no_antilag if rs_rocket_antilag is 1
	if ( GS_RaceGametype() && ((trap_Cvar_Get( "rs_rocket_antilag", "0", CVAR_ARCHIVE )->integer==1 && projectile->s.type == ET_ROCKET)))
		return;
	// !racesow

#ifdef NO_ROCKET_ANTILAG
	// hack for disabling antilag on rockets
	if( projectile && (projectile->s.type == ET_ROCKET || projectile->s.type == ET_PLASMA) )//racesow
	{
		int timeOffset;

		timeOffset = -projectile->timeDelta;
		projectile->timeDelta = 0;
		if( projectile->s.linearProjectile )
			projectile->s.modelindex2 = 0;

		// racesow: testing .42 time prestep function, because im really not sure it is equivalent to the .5 one; the difference is not that major anyway..
		//  G_ProjectileTimePrestep( projectile, timeOffset );
		rs_TimeDeltaPrestepProjectile(projectile,-timeOffset);
		// !racesow
	}
#endif
}