Exemple #1
0
/*
* W_Fire_Rocket
*/
edict_t *W_Fire_Rocket( edict_t *self, vec3_t start, vec3_t angles, int speed, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int timeout, int mod, int timeDelta )
{
	edict_t	*rocket;

	if( GS_Instagib() )
		damage = 9999;

	rocket = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta );

	rocket->s.type = ET_ROCKET; //rocket trail sfx
	if( mod == MOD_ROCKET_S )
	{
		rocket->s.modelindex = trap_ModelIndex( PATH_ROCKET_STRONG_MODEL );
		rocket->s.effects |= EF_STRONG_WEAPON;
		rocket->s.sound = trap_SoundIndex( S_WEAPON_ROCKET_S_FLY );
	}
	else
	{
		rocket->s.modelindex = trap_ModelIndex( PATH_ROCKET_WEAK_MODEL );
		rocket->s.effects &= ~EF_STRONG_WEAPON;
		rocket->s.sound = trap_SoundIndex( S_WEAPON_ROCKET_W_FLY );
	}
	rocket->touch = W_Touch_Rocket;
	rocket->think = G_FreeEdict;
	rocket->classname = "rocket";
	rocket->style = mod;

	return rocket;
}
Exemple #2
0
/*
* W_Fire_Plasma
*/
edict_t *W_Fire_Plasma( edict_t *self, vec3_t start, vec3_t angles, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int speed, int timeout, int mod, int timeDelta )
{
	edict_t	*plasma;

	if( GS_Instagib() )
		damage = 9999;

	plasma = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta );
	plasma->s.type = ET_PLASMA;
	plasma->classname = "plasma";
	plasma->style = mod;

	plasma->think = W_Think_Plasma;
	plasma->touch = W_AutoTouch_Plasma;
	plasma->nextThink = level.time + 1;
	plasma->timeout = level.time + timeout;

	if( mod == MOD_PLASMA_S )
	{
		plasma->s.modelindex = trap_ModelIndex( PATH_PLASMA_STRONG_MODEL );
		plasma->s.sound = trap_SoundIndex( S_WEAPON_PLASMAGUN_S_FLY );
		plasma->s.effects |= EF_STRONG_WEAPON;
	}
	else
	{
		plasma->s.modelindex = trap_ModelIndex( PATH_PLASMA_WEAK_MODEL );
		plasma->s.sound = trap_SoundIndex( S_WEAPON_PLASMAGUN_W_FLY );
		plasma->s.effects &= ~EF_STRONG_WEAPON;
	}

	return plasma;
}
Exemple #3
0
/*
* W_Fire_Grenade
*/
edict_t *W_Fire_Grenade( edict_t *self, vec3_t start, vec3_t dir, int speed, float damage,
						 int minKnockback, int maxKnockback, int stun, int minDamage, float radius,
						 int timeout, int mod, int timeDelta ) {
	edict_t *grenade;

	if( GS_Instagib() ) {
		damage = 9999;
	}

	grenade = W_Fire_TossProjectile( self, start, dir, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta );
	VectorClear( grenade->s.angles );
	grenade->style = mod;
	grenade->s.type = ET_GRENADE;
	grenade->movetype = MOVETYPE_BOUNCEGRENADE;
	grenade->touch = W_Touch_Grenade;
	grenade->use = NULL;
	grenade->think = W_Grenade_Explode;
	grenade->classname = "grenade";
	grenade->enemy = NULL;
	VectorSet( grenade->avelocity, 300, 300, 300 );

	if( mod == MOD_GRENADE_S ) {
		grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_STRONG_MODEL );
		grenade->s.effects |= EF_STRONG_WEAPON;
	} else {
		grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_WEAK_MODEL );
		grenade->s.effects &= ~EF_STRONG_WEAPON;
	}

	GClip_LinkEntity( grenade );

	return grenade;
}
void G_Gametype_GENERIC_SetUpWarmup( void )
{
	level.gametype.readyAnnouncementEnabled = true;
	level.gametype.scoreAnnouncementEnabled = false;
	level.gametype.countdownEnabled = false;
	level.gametype.pickableItemsMask = ( level.gametype.spawnableItemsMask|level.gametype.dropableItemsMask );
	if( GS_Instagib() )
		level.gametype.pickableItemsMask &= ~G_INSTAGIB_NEGATE_ITEMMASK;

	if( GS_TeamBasedGametype() )
	{
		bool any = false;
		int team;
		for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
		{
			if( G_Teams_TeamIsLocked( team ) )
			{
				G_Teams_UnLockTeam( team );
				any = true;
			}
		}
		if( any )
			G_PrintMsg( NULL, "Teams unlocked.\n" );
	}
	else
	{
		if( G_Teams_TeamIsLocked( TEAM_PLAYERS ) )
		{
			G_Teams_UnLockTeam( TEAM_PLAYERS );
			G_PrintMsg( NULL, "Teams unlocked.\n" );
		}
	}
	G_Teams_RemoveInvites();
}
static void G_Gametype_GENERIC_Init( void )
{
	trap_ConfigString( CS_GAMETYPETITLE, "Generic Deathmatch" );
	trap_ConfigString( CS_GAMETYPEVERSION, "1.0" );
	trap_ConfigString( CS_GAMETYPEAUTHOR, "Warsow Development Team" );
	trap_Cvar_ForceSet( "g_gametype", "generic" );

	level.gametype.spawnableItemsMask = ( IT_WEAPON|IT_AMMO|IT_ARMOR|IT_POWERUP|IT_HEALTH );
	level.gametype.respawnableItemsMask = ( IT_WEAPON|IT_AMMO|IT_ARMOR|IT_POWERUP|IT_HEALTH );
	level.gametype.dropableItemsMask = ( IT_WEAPON|IT_AMMO|IT_ARMOR|IT_POWERUP|IT_HEALTH );
	level.gametype.pickableItemsMask = ( level.gametype.spawnableItemsMask|level.gametype.dropableItemsMask );
	if( GS_Instagib() )
		level.gametype.pickableItemsMask &= ~G_INSTAGIB_NEGATE_ITEMMASK;

	level.gametype.isTeamBased = false;
	level.gametype.isRace = false;
	level.gametype.isTutorial = false;
	level.gametype.inverseScore = false;
	level.gametype.hasChallengersQueue = false;
	level.gametype.maxPlayersPerTeam = 0;

	level.gametype.ammo_respawn = 20;
	level.gametype.armor_respawn = 25;
	level.gametype.weapon_respawn = 5;
	level.gametype.health_respawn = 25;
	level.gametype.powerup_respawn = 90;
	level.gametype.megahealth_respawn = 20;
	level.gametype.ultrahealth_respawn = 60;

	level.gametype.countdownEnabled = false;
	level.gametype.mathAbortDisabled = false;
	level.gametype.canForceModels = true;
	level.gametype.canShowMinimap = false;
	level.gametype.teamOnlyMinimap = true;
	level.gametype.spawnpointRadius = 256;

	level.gametype.canShowMinimap = false;
	level.gametype.teamOnlyMinimap = true;

	level.gametype.mmCompatible = false;

	if( GS_Instagib() )
		level.gametype.spawnpointRadius *= 2;

	trap_ConfigString( CS_SCB_PLAYERTAB_LAYOUT, "%n 164 %i 64 %l 48 %p 18 %p 18" );
	trap_ConfigString( CS_SCB_PLAYERTAB_TITLES, "Name Score Ping C R" );
}
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 );
}
Exemple #7
0
/*
* W_Fire_Grenade
*/
edict_t *W_Fire_Grenade( edict_t *self, vec3_t start, vec3_t angles, int speed, float damage,
						int minKnockback, int maxKnockback, int stun, int minDamage, float radius,
						int timeout, int mod, int timeDelta, qboolean aim_up )
{
	edict_t	*grenade;
	static cvar_t *g_grenade_gravity = NULL;

	if( GS_Instagib() )
		damage = 9999;

	if( !g_grenade_gravity )
		g_grenade_gravity = trap_Cvar_Get( "g_grenade_gravity", "1.3", CVAR_DEVELOPER );

	if( aim_up )
	{
		angles[PITCH] -= 10; // aim some degrees upwards from view dir

		// clamp to front side of the player
		angles[PITCH] += -90; // rotate to make easier the check
		while( angles[PITCH] < -360 ) angles[PITCH] += 360;
		clamp( angles[PITCH], -180, 0 );
		angles[PITCH] += 90;
		while( angles[PITCH] > 360 ) angles[PITCH] -= 360;
	}

	grenade = W_Fire_TossProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta );
	VectorClear( grenade->s.angles );
	grenade->style = mod;
	grenade->s.type = ET_GRENADE;
	grenade->movetype = MOVETYPE_BOUNCEGRENADE;
	grenade->touch = W_Touch_Grenade;
	grenade->use = NULL;
	grenade->think = W_Grenade_Explode;
	grenade->classname = "grenade";
	grenade->gravity = g_grenade_gravity->value;
	grenade->enemy = NULL;

	if( mod == MOD_GRENADE_S )
	{
		grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_STRONG_MODEL );
		grenade->s.effects |= EF_STRONG_WEAPON;
	}
	else
	{
		grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_WEAK_MODEL );
		grenade->s.effects &= ~EF_STRONG_WEAPON;
	}

	GClip_LinkEntity( grenade );

	return grenade;
}
/*
* G_Gametype_CanRespawnItem
*/
bool G_Gametype_CanRespawnItem( const gsitem_t *item )
{
	int itemmask;

	if( !item )
		return false;

	itemmask = level.gametype.respawnableItemsMask;
	if( GS_Instagib() )
	{
		itemmask &= ~G_INSTAGIB_NEGATE_ITEMMASK;
	}

	return ( ( itemmask & item->type ) != 0 ) ? true : false;
}
Exemple #9
0
/*
* W_Fire_Lasergun
*/
edict_t	*W_Fire_Lasergun( edict_t *self, vec3_t start, vec3_t angles, float damage, int knockback, int stun, int range, int mod, int timeDelta )
{
	edict_t	*laser;
	qboolean newLaser;
	trace_t	tr;
	vec3_t dir;

	if( GS_Instagib() )
		damage = 9999;

	laser = _FindOrSpawnLaser( self, ET_LASERBEAM, &newLaser );
	if( newLaser )
	{
		// the quad start sound is added from the server
		if( self->r.client && self->r.client->ps.inventory[POWERUP_QUAD] > 0 )
			G_Sound( self, CHAN_AUTO, trap_SoundIndex( S_QUAD_FIRE ), ATTN_NORM );
	}

	laser_damage = damage;
	laser_knockback = knockback;
	laser_stun = stun;
	laser_attackerNum = ENTNUM( self );
	laser_mod = mod;
	laser_missed = qtrue;

	GS_TraceLaserBeam( &tr, start, angles, range, ENTNUM( self ), timeDelta, _LaserImpact );

	laser->r.svflags |= SVF_FORCEOWNER;
	VectorCopy( start, laser->s.origin );
	AngleVectors( angles, dir, NULL, NULL );
	VectorMA( laser->s.origin, range, dir, laser->s.origin2 );

	laser->think = G_Laser_Think;
	laser->nextThink = level.time + 100;

	if( laser_missed && self->r.client )
		G_AwardPlayerMissedLasergun( self, mod );

	// calculate laser's mins and maxs for linkEntity
	G_SetBoundsForSpanEntity( laser, 8 );

	GClip_LinkEntity( laser );

	return laser;
}
Exemple #10
0
/*
* W_Fire_Bullet
*/
void W_Fire_Bullet( edict_t *self, vec3_t start, vec3_t angles, int seed, int range, int spread, float damage, int knockback, int stun, int mod, int timeDelta )
{
	vec3_t dir;
	edict_t *event;
	float r, u;
	double alpha, s;
	trace_t trace;
	int dmgflags = DAMAGE_STUN_CLAMP|DAMAGE_KNOCKBACK_SOFT;

	if( GS_Instagib() )
		damage = 9999;

	AngleVectors( angles, dir, NULL, NULL );

	// send the event
	event = G_SpawnEvent( EV_FIRE_BULLET, seed, start );
	event->s.ownerNum = ENTNUM( self );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorScale( dir, 4096, event->s.origin2 ); // DirToByte is too inaccurate
	event->s.weapon = WEAP_MACHINEGUN;
	if( mod == MOD_MACHINEGUN_S )
		event->s.weapon |= EV_INVERSE;

	// 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;

	GS_TraceBullet( &trace, start, dir, r, u, range, ENTNUM( self ), timeDelta );
	if( trace.ent != -1 )
	{
		if( game.edicts[trace.ent].takedamage )
		{
			G_Damage( &game.edicts[trace.ent], self, self, dir, dir, trace.endpos, damage, knockback, stun, dmgflags, mod );
		}
		else
		{
			if( !( trace.surfFlags & SURF_NOIMPACT ) )
			{
			}
		}
	}
}
Exemple #11
0
/*
* W_Fire_Electrobolt_Weak
*/
edict_t *W_Fire_Electrobolt_Weak( edict_t *self, vec3_t start, vec3_t angles, float speed, float damage, int minKnockback, int maxKnockback, int stun, int timeout, int mod, int timeDelta )
{
	edict_t	*bolt;

	if( GS_Instagib() )
		damage = 9999;

	// projectile, weak mode
	bolt = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, 0, 0, timeout, timeDelta );
	bolt->s.modelindex = trap_ModelIndex( PATH_ELECTROBOLT_WEAK_MODEL );
	bolt->s.type = ET_ELECTRO_WEAK; //add particle trail and light
	bolt->s.ownerNum = ENTNUM( self );
	bolt->touch = W_Touch_Bolt;
	bolt->classname = "bolt";
	bolt->style = mod;
	bolt->s.effects &= ~EF_STRONG_WEAPON;

	return bolt;
}
Exemple #12
0
/*
* W_Fire_GunbladeBlast
*/
edict_t *W_Fire_GunbladeBlast( edict_t *self, vec3_t start, vec3_t angles, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int speed, int timeout, int mod, int timeDelta )
{
	edict_t	*blast;

	if( GS_Instagib() )
		damage = 9999;

	blast = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta );
	blast->s.modelindex = trap_ModelIndex( PATH_GUNBLADEBLAST_STRONG_MODEL );
	blast->s.type = ET_BLASTER;
	blast->s.effects |= EF_STRONG_WEAPON;
	blast->touch = W_Touch_GunbladeBlast;
	blast->classname = "gunblade_blast";
	blast->style = mod;

	blast->s.sound = trap_SoundIndex( S_WEAPON_PLASMAGUN_S_FLY );

	return blast;
}
Exemple #13
0
void W_Fire_Riotgun( edict_t *self, vec3_t start, vec3_t fv, vec3_t rv, vec3_t uv, int seed, int range, 
	int hspread, int vspread, int count, float damage, int knockback, int stun, int mod, int timeDelta ) {
	edict_t *event;
	int dmgflags = 0;

	if( GS_Instagib() ) {
		damage = 9999;
	}

	// send the event
	event = G_SpawnEvent( EV_FIRE_RIOTGUN, seed, start );
	event->s.ownerNum = ENTNUM( self );
	VectorCopy( fv, event->s.origin2 );
	VectorCopy( rv, event->s.origin3 );
	event->s.weapon = WEAP_RIOTGUN;
	event->s.firemode = ( mod == MOD_RIOTGUN_S ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;

	W_Fire_SunflowerBucket( self, start, fv, rv, uv, &seed, count, hspread, vspread,
		range, damage, knockback, stun, dmgflags, mod, timeDelta );
}
/*
* G_Gametype_CanDropItem
*/
bool G_Gametype_CanDropItem( const gsitem_t *item, bool ignoreMatchState )
{
	int itemmask;

	if( !item )
		return false;

	if( !ignoreMatchState )
	{
		if( GS_MatchState() > MATCH_STATE_PLAYTIME )
			return false;
	}

	itemmask = level.gametype.dropableItemsMask;
	if( GS_Instagib() )
	{
		itemmask &= ~G_INSTAGIB_NEGATE_ITEMMASK;
	}

	return ( itemmask & item->type ) ? true : false;
}
Exemple #15
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 );
	}
}
Exemple #16
0
/*
* G_ClientThink
* Client frame think, and call to execute its usercommands thinking
*/
void G_ClientThink( edict_t *ent )
{
	if( !ent || !ent->r.client )
		return;

	if( trap_GetClientState( PLAYERNUM( ent ) ) < CS_SPAWNED )
		return;

	ent->r.client->ps.POVnum = ENTNUM( ent ); // set self

	// load instashield
	if( GS_Instagib() && g_instashield->integer )
	{
		if( ent->s.team >= TEAM_PLAYERS && ent->s.team < GS_MAX_TEAMS )
		{
			if( ent->r.client->ps.inventory[POWERUP_SHELL] > 0 )
			{
				ent->r.client->resp.instashieldCharge -= ( game.frametime * 0.001f ) * 60.0f;
				clamp( ent->r.client->resp.instashieldCharge, 0, INSTA_SHIELD_MAX );
				if( ent->r.client->resp.instashieldCharge == 0 )
					ent->r.client->ps.inventory[POWERUP_SHELL] = 0;
			}
			else
			{
				ent->r.client->resp.instashieldCharge += ( game.frametime * 0.001f ) * 20.0f;
				clamp( ent->r.client->resp.instashieldCharge, 0, INSTA_SHIELD_MAX );
			}
		}
	}

	// run bots thinking with the rest of clients
	if( ent->r.svflags & SVF_FAKECLIENT )
	{
		if( !ent->think && AI_GetType( ent->ai ) == AI_ISBOT )
			AI_Think( ent );
	}

	trap_ExecuteClientThinks( PLAYERNUM( ent ) );
}
void G_Gametype_GENERIC_SetUpMatch( void )
{
	int i;

	level.gametype.readyAnnouncementEnabled = false;
	level.gametype.scoreAnnouncementEnabled = true;
	level.gametype.countdownEnabled = true;
	level.gametype.pickableItemsMask = ( level.gametype.spawnableItemsMask|level.gametype.dropableItemsMask );
	if( GS_Instagib() )
		level.gametype.pickableItemsMask &= ~G_INSTAGIB_NEGATE_ITEMMASK;

	// clear player stats and scores, team scores and respawn clients in team lists
	for( i = TEAM_PLAYERS; i < GS_MAX_TEAMS; i++ )
	{
		int j;
		g_teamlist_t *team = &teamlist[i];
		memset( &team->stats, 0, sizeof( team->stats ) );

		// respawn all clients inside the playing teams
		for( j = 0; j < team->numplayers; j++ )
		{
			edict_t *ent = &game.edicts[ team->playerIndices[j] ];
			G_ClientClearStats( ent );
			G_ClientRespawn( ent, false );
		}
	}

	// set items to be spawned with a delay
	G_Items_RespawnByType( IT_ARMOR, ARMOR_RA, 15 );
	G_Items_RespawnByType( IT_ARMOR, ARMOR_RA, 15 );
	G_Items_RespawnByType( IT_HEALTH, HEALTH_MEGA, 15 );
	G_Items_RespawnByType( IT_HEALTH, HEALTH_ULTRA, 15 );
	G_Items_RespawnByType( IT_POWERUP, 0, brandom( 20, 40 ) );
	G_Match_FreeBodyQueue();

	G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_FIGHT_1_to_2, ( rand()&1 )+1 ) ), GS_MAX_TEAMS, false, NULL );
	G_CenterPrintMsg( NULL, "FIGHT!" );
}
Exemple #18
0
/*
* W_Fire_Blade
*/
void W_Fire_Blade( edict_t *self, int range, vec3_t start, vec3_t angles, float damage, int knockback, int stun, int mod, int timeDelta )
{
	edict_t *event, *other = NULL;
	vec3_t end;
	trace_t	trace;
	int mask = MASK_SHOT;
	vec3_t dir;
	int dmgflags = 0;

	if( GS_Instagib() )
		damage = 9999;

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

	if( GS_RaceGametype() )
		mask = MASK_SOLID;

	G_Trace4D( &trace, start, NULL, NULL, end, self, MASK_SHOT, timeDelta );
	if( trace.ent == -1 )  //didn't touch anything
		return;

	// find out what touched
	other = &game.edicts[trace.ent];
	if( !other->takedamage ) // it was the world
	{
		// wall impact
		VectorMA( trace.endpos, -0.02, dir, end );
		event = G_SpawnEvent( EV_BLADE_IMPACT, 0, end );
		event->s.ownerNum = ENTNUM( self );
		VectorScale( trace.plane.normal, 1024, event->s.origin2 );
		event->r.svflags = SVF_TRANSMITORIGIN2;
		return;
	}

	// it was a player
	G_Damage( other, self, self, dir, dir, other->s.origin, damage, knockback, stun, dmgflags, mod );
}
Exemple #19
0
void W_Fire_Riotgun( edict_t *self, vec3_t start, vec3_t angles, int seed, int range, int spread,
					int count, float damage, int knockback, int stun, int mod, int timeDelta )
{
	vec3_t dir;
	edict_t *event;
	int dmgflags = 0;

	if( GS_Instagib() )
		damage = 9999;

	AngleVectors( angles, dir, NULL, NULL );

	// send the event
	event = G_SpawnEvent( EV_FIRE_RIOTGUN, seed, start );
	event->s.ownerNum = ENTNUM( self );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorScale( dir, 4096, event->s.origin2 ); // DirToByte is too inaccurate
	event->s.weapon = WEAP_RIOTGUN;
	if( mod == MOD_RIOTGUN_S )
		event->s.weapon |= EV_INVERSE;

	G_Fire_SpiralPattern( self, start, dir, &seed, count, spread, range, damage, knockback, stun, dmgflags, mod, timeDelta );
}
Exemple #20
0
/*
* W_Fire_Bullet
*/
void W_Fire_Bullet( edict_t *self, vec3_t start, vec3_t fv, vec3_t rv, vec3_t uv, int seed, int range, 
	int hspread, int vspread, float damage, int knockback, int stun, int mod, int timeDelta ) {
	edict_t *event;
	float r, u;
	double alpha, s;
	trace_t trace;
	int dmgflags = DAMAGE_STUN_CLAMP | DAMAGE_KNOCKBACK_SOFT;

	if( GS_Instagib() ) {
		damage = 9999;
	}

	// send the event
	event = G_SpawnEvent( EV_FIRE_BULLET, seed, start );
	event->s.ownerNum = ENTNUM( self );
	VectorCopy( fv, event->s.origin2 );
	VectorCopy( rv, event->s.origin3 );
	event->s.weapon = WEAP_MACHINEGUN;
	event->s.firemode = ( mod == MOD_MACHINEGUN_S ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;

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

	GS_TraceBullet( &trace, start, fv, rv, uv, r, u, range, ENTNUM( self ), timeDelta );
	if( trace.ent != -1 ) {
		if( game.edicts[trace.ent].takedamage ) {
			G_Damage( &game.edicts[trace.ent], self, self, fv, fv, trace.endpos, damage, knockback, stun, dmgflags, mod );
		} else {
			if( !( trace.surfFlags & SURF_NOIMPACT ) ) {
			}
		}
	}
}
Exemple #21
0
/*
* G_SetClientStats
*/
void G_SetClientStats( edict_t *ent )
{
	gclient_t *client = ent->r.client;
	int team, i;

	if( ent->r.client->resp.chase.active )  // in chasecam it copies the other player stats
		return;

	//
	// layouts
	//
	client->ps.stats[STAT_LAYOUTS] = 0;

	// don't force scoreboard when dead during timeout
	if( ent->r.client->level.showscores || GS_MatchState() >= MATCH_STATE_POSTMATCH )
		client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_SCOREBOARD;
	if( GS_TeamBasedGametype() && !GS_InvidualGameType() )
		client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_TEAMTAB;
	if( GS_HasChallengers() && ent->r.client->queueTimeStamp )
		client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_CHALLENGER;
	if( GS_MatchState() <= MATCH_STATE_WARMUP && level.ready[PLAYERNUM( ent )] )
		client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_READY;
	if( G_SpawnQueue_GetSystem( ent->s.team ) == SPAWNSYSTEM_INSTANT )
		client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_INSTANTRESPAWN;

	//
	// team
	//
	client->ps.stats[STAT_TEAM] = client->ps.stats[STAT_REALTEAM] = ent->s.team;

	//
	// health
	//
	if( ent->s.team == TEAM_SPECTATOR )
		client->ps.stats[STAT_HEALTH] = STAT_NOTSET; // no health for spectator
	else
		client->ps.stats[STAT_HEALTH] = HEALTH_TO_INT( ent->health );
	client->r.frags = client->ps.stats[STAT_SCORE];

	//
	// armor
	//
	if( GS_Instagib() )
	{
		if( g_instashield->integer )
			client->ps.stats[STAT_ARMOR] = ARMOR_TO_INT( 100.0f * ( client->resp.instashieldCharge / INSTA_SHIELD_MAX ) );
		else
			client->ps.stats[STAT_ARMOR] = 0;
	}
	else
		client->ps.stats[STAT_ARMOR] = ARMOR_TO_INT( client->resp.armor );

	//
	// pickup message
	//
	if( level.time > client->resp.pickup_msg_time )
	{
		client->ps.stats[STAT_PICKUP_ITEM] = 0;
	}

	//
	// frags
	//
	if( ent->s.team == TEAM_SPECTATOR )
	{
		client->ps.stats[STAT_SCORE] = STAT_NOTSET; // no frags for spectators
	}
	else
	{
		client->ps.stats[STAT_SCORE] = ent->r.client->level.stats.score;
	}

	//
	// Team scores
	//
	if( GS_TeamBasedGametype() )
	{
		// team based
		i = 0;
		for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
		{
			client->ps.stats[STAT_TEAM_ALPHA_SCORE+i] = teamlist[team].stats.score;
			i++;
		}
		// mark the rest as not set
		for(; team < GS_MAX_TEAMS; team++ )
		{
			client->ps.stats[STAT_TEAM_ALPHA_SCORE+i] = STAT_NOTSET;
			i++;
		}
	}
	else
	{
		// not team based
		i = 0;
		for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
		{
			client->ps.stats[STAT_TEAM_ALPHA_SCORE+i] = STAT_NOTSET;
			i++;
		}
	}

	// spawn system
	client->ps.stats[STAT_NEXT_RESPAWN] = ceil( G_SpawnQueue_NextRespawnTime( client->team ) * 0.001f );

	// pointed player
	client->ps.stats[STAT_POINTED_TEAMPLAYER] = 0;
	client->ps.stats[STAT_POINTED_PLAYER] = G_FindPointedPlayer( ent );
	if( client->ps.stats[STAT_POINTED_PLAYER] && GS_TeamBasedGametype() )
	{
		edict_t	*e = &game.edicts[client->ps.stats[STAT_POINTED_PLAYER]];
		if( e->s.team == ent->s.team )
		{
			int pointedhealth = HEALTH_TO_INT( e->health );
			int pointedarmor = 0;
			int available_bits = 0;
			bool mega = false;

			if( pointedhealth < 0 ) pointedhealth = 0;
			if( pointedhealth > 100 )
			{
				pointedhealth -= 100;
				mega = true;
				if( pointedhealth > 100 )
					pointedhealth = 100;
			}
			pointedhealth /= 3.2;

			if( GS_Armor_TagForCount( e->r.client->resp.armor ) )
			{
				pointedarmor = ARMOR_TO_INT( e->r.client->resp.armor );
			}
			if( pointedarmor > 150 )
			{
				pointedarmor = 150;
			}
			pointedarmor /= 5;

			client->ps.stats[STAT_POINTED_TEAMPLAYER] = ( ( pointedhealth &0x1F )|( pointedarmor&0x3F )<<6|( available_bits&0xF )<<12 );
			if( mega )
			{
				client->ps.stats[STAT_POINTED_TEAMPLAYER] |= 0x20;
			}
		}
	}

	// last killer. ignore world and team kills
	if( client->teamstate.last_killer )
	{
		edict_t *targ = ent, *attacker = client->teamstate.last_killer;
		client->ps.stats[STAT_LAST_KILLER] = (attacker->r.client && !GS_IsTeamDamage( &targ->s, &attacker->s ) ? 
			ENTNUM( attacker ) : 0);
	}
	else
	{
		client->ps.stats[STAT_LAST_KILLER] = 0;
	}
}
Exemple #22
0
edict_t *Drop_Item( edict_t *ent, const gsitem_t *item )
{
	edict_t	*dropped;
	vec3_t forward, right;
	vec3_t offset;

	if( !G_Gametype_CanDropItem( item, false ) )
		return NULL;

	dropped = G_Spawn();
	dropped->classname = item->classname;
	dropped->item = item;
	dropped->spawnflags = DROPPED_ITEM;
	VectorCopy( item_box_mins, dropped->r.mins );
	VectorCopy( item_box_maxs, dropped->r.maxs );
	dropped->r.solid = SOLID_TRIGGER;
	dropped->movetype = MOVETYPE_TOSS;
	dropped->touch = drop_temp_touch;
	dropped->stop = AI_AddGoalEntity;
	dropped->r.owner = ent;
	dropped->r.svflags &= ~SVF_NOCLIENT;
	dropped->s.team = ent->s.team;
	dropped->s.type = ET_ITEM;
	dropped->s.itemNum = item->tag;
	dropped->s.effects = 0; // default effects are applied client side
	dropped->s.modelindex = trap_ModelIndex( dropped->item->world_model[0] );
	dropped->s.modelindex2 = trap_ModelIndex( dropped->item->world_model[1] );
	dropped->attenuation = 1;

	if( ent->r.client )
	{
		trace_t	trace;

		AngleVectors( ent->r.client->ps.viewangles, forward, right, NULL );
		VectorSet( offset, 24, 0, -16 );
		G_ProjectSource( ent->s.origin, offset, forward, right, dropped->s.origin );
		G_Trace( &trace, ent->s.origin, dropped->r.mins, dropped->r.maxs,
			dropped->s.origin, ent, CONTENTS_SOLID );
		VectorCopy( trace.endpos, dropped->s.origin );

		dropped->spawnflags |= DROPPED_PLAYER_ITEM;

		// ugly hack for dropping backpacks
		if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK )
		{
			int w;
			bool anything = false;

			for( w = WEAP_GUNBLADE + 1; w < WEAP_TOTAL; w++ )
			{
				if( w == WEAP_INSTAGUN && !GS_Instagib() )
					continue;

				if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK )
				{
					int weakTag = GS_FindItemByTag( w )->weakammo_tag;
					if( ent->r.client->ps.inventory[weakTag] > 0 )
					{
						dropped->invpak[weakTag] = ent->r.client->ps.inventory[weakTag];
						ent->r.client->ps.inventory[weakTag] = 0;
						anything = true;
					}
				}

				if( item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK )
				{
					int strongTag = GS_FindItemByTag( w )->ammo_tag;
					if( ent->r.client->ps.inventory[strongTag] )
					{
						dropped->invpak[strongTag] = ent->r.client->ps.inventory[strongTag];
						ent->r.client->ps.inventory[strongTag] = 0;
						anything = true;
					}
				}
			}

			if( !anything ) // if nothing was added to the pack, don't bother spawning it
			{
				G_FreeEdict( dropped );
				return NULL;
			}
		}

		// power-ups are special
		if( ( item->type & IT_POWERUP ) && item->quantity )
		{
			if( ent->r.client->ps.inventory[item->tag] )
			{
				dropped->count = ent->r.client->ps.inventory[item->tag];
				ent->r.client->ps.inventory[item->tag] = 0;
			}
			else
			{
				dropped->count = item->quantity;
			}
		}

		ent->r.client->teamstate.last_drop_item = item;
		VectorCopy( dropped->s.origin, ent->r.client->teamstate.last_drop_location );
	}
	else
	{
		AngleVectors( ent->s.angles, forward, right, NULL );
		VectorCopy( ent->s.origin, dropped->s.origin );

		// ugly hack for dropping backpacks
		if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK )
		{
			int w;

			for( w = WEAP_GUNBLADE + 1; w < WEAP_TOTAL; w++ )
			{
				if( w == WEAP_INSTAGUN && !GS_Instagib() )
					continue;

				if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK )
				{
					gsitem_t *ammo = GS_FindItemByTag( GS_FindItemByTag( w )->weakammo_tag );
					if( ammo )
						dropped->invpak[ammo->tag] = ammo->quantity;
				}

				if( item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK )
				{
					gsitem_t *ammo = GS_FindItemByTag( GS_FindItemByTag( w )->ammo_tag );
					if( ammo )
						dropped->invpak[ammo->tag] = ammo->quantity;
				}
			}
		}

		// power-ups are special
		if( ( item->type & IT_POWERUP ) && item->quantity )
		{
			dropped->count = item->quantity;
		}
	}

	VectorScale( forward, 100, dropped->velocity );
	dropped->velocity[2] = 300;

	dropped->think = drop_make_touchable;
	dropped->nextThink = level.time + 1000;

	GClip_LinkEntity( dropped );

	return dropped;
}
Exemple #23
0
/*
* G_CheckCvars
* Check for cvars that have been modified and need the game to be updated
*/
void G_CheckCvars( void )
{
	if( g_antilag_maxtimedelta->modified )
	{
		if( g_antilag_maxtimedelta->integer < 0 )
			trap_Cvar_SetValue( "g_antilag_maxtimedelta", abs( g_antilag_maxtimedelta->integer ) );
		g_antilag_maxtimedelta->modified = false;
		g_antilag_timenudge->modified = true;
	}

	if( g_antilag_timenudge->modified )
	{
		if( g_antilag_timenudge->integer > g_antilag_maxtimedelta->integer )
			trap_Cvar_SetValue( "g_antilag_timenudge", g_antilag_maxtimedelta->integer );
		else if( g_antilag_timenudge->integer < -g_antilag_maxtimedelta->integer )
			trap_Cvar_SetValue( "g_antilag_timenudge", -g_antilag_maxtimedelta->integer );
		g_antilag_timenudge->modified = false;
	}

	if( g_warmup_timelimit->modified )
	{
		// if we are inside timelimit period, update the endtime
		if( GS_MatchState() == MATCH_STATE_WARMUP )
		{
			gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)fabs( 60.0f * 1000 * g_warmup_timelimit->integer );
		}
		g_warmup_timelimit->modified = false;
	}

	if( g_timelimit->modified )
	{
		// if we are inside timelimit period, update the endtime
		if( GS_MatchState() == MATCH_STATE_PLAYTIME &&
			!GS_MatchExtended() )
		{
			if( g_timelimit->value )
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)fabs( 60.0f * 1000 * g_timelimit->value );
			else
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = 0;
		}
		g_timelimit->modified = false;
	}

	if( g_match_extendedtime->modified )
	{
		// if we are inside extended_time period, update the endtime
		if( GS_MatchExtended() )
		{
			if( g_match_extendedtime->integer )
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)fabs( 60 * 1000 * g_match_extendedtime->value );
		}
		g_match_extendedtime->modified = false;
	}

	if( g_allow_falldamage->modified )
	{
		g_allow_falldamage->modified = false;
	}

	// update gameshared server settings

	// FIXME: This should be restructured so gameshared settings are the master settings
	GS_GamestatSetFlag( GAMESTAT_FLAG_INSTAGIB, ( g_instagib->integer != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_FALLDAMAGE, ( g_allow_falldamage->integer != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_SELFDAMAGE, ( g_allow_selfdamage->integer != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_HASCHALLENGERS, ( level.gametype.hasChallengersQueue != 0 ) );

	GS_GamestatSetFlag( GAMESTAT_FLAG_ISTEAMBASED, ( level.gametype.isTeamBased != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_ISRACE, ( level.gametype.isRace != 0 ) );

	GS_GamestatSetFlag( GAMESTAT_FLAG_COUNTDOWN, level.gametype.countdownEnabled );
	GS_GamestatSetFlag( GAMESTAT_FLAG_INHIBITSHOOTING, level.gametype.shootingDisabled );
	GS_GamestatSetFlag( GAMESTAT_FLAG_INFINITEAMMO, ( level.gametype.infiniteAmmo || GS_Instagib() ) != 0 );
	GS_GamestatSetFlag( GAMESTAT_FLAG_CANFORCEMODELS, level.gametype.canForceModels );
	GS_GamestatSetFlag( GAMESTAT_FLAG_CANSHOWMINIMAP, level.gametype.canShowMinimap );
	GS_GamestatSetFlag( GAMESTAT_FLAG_TEAMONLYMINIMAP, level.gametype.teamOnlyMinimap );

	GS_GamestatSetFlag( GAMESTAT_FLAG_MMCOMPATIBLE, level.gametype.mmCompatible );

	GS_GamestatSetLongFlag( GAMELONG_FLAG_ISTUTORIAL, ( level.gametype.isTutorial != 0 ) );

	gs.gameState.stats[GAMESTAT_MAXPLAYERSINTEAM] = level.gametype.maxPlayersPerTeam;
	clamp( gs.gameState.stats[GAMESTAT_MAXPLAYERSINTEAM], 0, 255 );

}
Exemple #24
0
/*
* ClientThink
*/
void ClientThink( edict_t *ent, usercmd_t *ucmd, int timeDelta )
{
	gclient_t *client;
	int i, j;
	static pmove_t pm;
	int delta, count;

	client = ent->r.client;

	client->ps.POVnum = ENTNUM( ent );
	client->ps.playerNum = PLAYERNUM( ent );

	// anti-lag
	if( ent->r.svflags & SVF_FAKECLIENT )
	{
		client->timeDelta = 0;
	}
	else
	{
		int nudge;
		int fixedNudge = ( game.snapFrameTime ) * 0.5; // fixme: find where this nudge comes from.

		// add smoothing to timeDelta between the last few ucmds and a small fine-tuning nudge.
		nudge = fixedNudge + g_antilag_timenudge->integer;
		timeDelta += nudge;
		clamp( timeDelta, -g_antilag_maxtimedelta->integer, 0 );

		// smooth using last valid deltas
		i = client->timeDeltasHead - 6;
		if( i < 0 ) i = 0;
		for( count = 0, delta = 0; i < client->timeDeltasHead; i++ )
		{
			if( client->timeDeltas[i & G_MAX_TIME_DELTAS_MASK] < 0 )
			{
				delta += client->timeDeltas[i & G_MAX_TIME_DELTAS_MASK];
				count++;
			}
		}

		if( !count )
			client->timeDelta = timeDelta;
		else
		{
			delta /= count;
			client->timeDelta = ( delta + timeDelta ) * 0.5;
		}

		client->timeDeltas[client->timeDeltasHead & G_MAX_TIME_DELTAS_MASK] = timeDelta;
		client->timeDeltasHead++;

#ifdef UCMDTIMENUDGE
		client->timeDelta += client->pers.ucmdTimeNudge;
#endif
	}

	clamp( client->timeDelta, -g_antilag_maxtimedelta->integer, 0 );

	// update activity if he touched any controls
	if( ucmd->forwardmove != 0 || ucmd->sidemove != 0 || ucmd->upmove != 0 || ( ucmd->buttons & ~BUTTON_BUSYICON ) != 0
		|| client->ucmd.angles[PITCH] != ucmd->angles[PITCH] || client->ucmd.angles[YAW] != ucmd->angles[YAW] )
		G_Client_UpdateActivity( client );

	client->ucmd = *ucmd;

	// can exit intermission after two seconds, not counting postmatch
	if( GS_MatchState() == MATCH_STATE_WAITEXIT && ( ucmd->buttons & BUTTON_ATTACK ) && game.serverTime > GS_MatchStartTime() + 2000 )
		level.exitNow = true;

	// (is this really needed?:only if not cared enough about ps in the rest of the code)
	// refresh player state position from the entity
	VectorCopy( ent->s.origin, client->ps.pmove.origin );
	VectorCopy( ent->velocity, client->ps.pmove.velocity );
	VectorCopy( ent->s.angles, client->ps.viewangles );

	client->ps.pmove.gravity = level.gravity;

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH || GS_MatchPaused() 
		|| ( ent->movetype != MOVETYPE_PLAYER && ent->movetype != MOVETYPE_NOCLIP ) )
		client->ps.pmove.pm_type = PM_FREEZE;
	else if( ent->s.type == ET_GIB )
		client->ps.pmove.pm_type = PM_GIB;
	else if( ent->movetype == MOVETYPE_NOCLIP || client->isTV )
		client->ps.pmove.pm_type = PM_SPECTATOR;
	else
		client->ps.pmove.pm_type = PM_NORMAL;

	// set up for pmove
	memset( &pm, 0, sizeof( pmove_t ) );
	pm.playerState = &client->ps;

	if( !client->isTV )
		pm.cmd = *ucmd;

	if( memcmp( &client->old_pmove, &client->ps.pmove, sizeof( pmove_state_t ) ) )
		pm.snapinitial = true;

	// perform a pmove
	Pmove( &pm );

	// save results of pmove
	client->old_pmove = client->ps.pmove;

	// update the entity with the new position
	VectorCopy( client->ps.pmove.origin, ent->s.origin );
	VectorCopy( client->ps.pmove.velocity, ent->velocity );
	VectorCopy( client->ps.viewangles, ent->s.angles );
	ent->viewheight = client->ps.viewheight;
	VectorCopy( pm.mins, ent->r.mins );
	VectorCopy( pm.maxs, ent->r.maxs );

	ent->waterlevel = pm.waterlevel;
	ent->watertype = pm.watertype;
	if( pm.groundentity == -1 )
	{
		ent->groundentity = NULL;
	}
	else
	{
		G_AwardResetPlayerComboStats( ent );

		ent->groundentity = &game.edicts[pm.groundentity];
		ent->groundentity_linkcount = ent->groundentity->linkcount;
	}
	
	GClip_LinkEntity( ent );

	GS_AddLaserbeamPoint( &ent->r.client->resp.trail, &ent->r.client->ps, ucmd->serverTimeStamp );

	// Regeneration
	if( ent->r.client->ps.inventory[POWERUP_REGEN] > 0 && ent->health < 200)
	{
		ent->health += ( game.frametime * 0.001f ) * 10.0f;

		// Regen expires if health reaches 200
		if ( ent->health >= 199.0f )
			ent->r.client->ps.inventory[POWERUP_REGEN]--;
	}

	// fire touch functions
	if( ent->movetype != MOVETYPE_NOCLIP )
	{
		edict_t *other;

		// touch other objects
		for( i = 0; i < pm.numtouch; i++ )
		{
			other = &game.edicts[pm.touchents[i]];
			for( j = 0; j < i; j++ )
			{
				if( &game.edicts[pm.touchents[j]] == other )
					break;
			}
			if( j != i )
				continue; // duplicated

			// player can't touch projectiles, only projectiles can touch the player
			G_CallTouch( other, ent, NULL, 0 );
		}
	}

	ent->s.weapon = GS_ThinkPlayerWeapon( &client->ps, ucmd->buttons, ucmd->msec, client->timeDelta );

	if( G_IsDead( ent ) )
	{
		if( ent->deathTimeStamp + g_respawn_delay_min->integer <= level.time )
			client->resp.snap.buttons |= ucmd->buttons;
	}
	else if( client->ps.pmove.stats[PM_STAT_NOUSERCONTROL] <= 0 )
		client->resp.snap.buttons |= ucmd->buttons;

	// trigger the instashield
	if( GS_Instagib() && g_instashield->integer )
	{
		if( client->ps.pmove.pm_type == PM_NORMAL && pm.cmd.upmove < 0 &&
			client->resp.instashieldCharge == INSTA_SHIELD_MAX && 
			client->ps.inventory[POWERUP_SHELL] == 0 )
		{
			client->ps.inventory[POWERUP_SHELL] = client->resp.instashieldCharge;
			G_Sound( ent, CHAN_AUTO, trap_SoundIndex( GS_FindItemByTag( POWERUP_SHELL )->pickup_sound ), ATTN_NORM );
		}
	}	

	// 
	if( client->ps.pmove.pm_type == PM_NORMAL )
		client->level.stats.had_playtime = true;

	// generating plrkeys (optimized for net communication)
	ClientMakePlrkeys( client, ucmd );
}
Exemple #25
0
/*
* G_Damage
* targ		entity that is being damaged
* inflictor	entity that is causing the damage
* attacker	entity that caused the inflictor to damage targ
* example: targ=enemy, inflictor=rocket, attacker=player
*
* dir			direction of the attack
* point		point at which the damage is being inflicted
* normal		normal vector from that point
* damage		amount of damage being inflicted
* knockback	force to be applied against targ as a result of the damage
*
* dflags		these flags are used to control how T_Damage works
*/
void G_Damage( edict_t *targ, edict_t *inflictor, edict_t *attacker, const vec3_t pushdir, const vec3_t dmgdir, const vec3_t point, float damage, float knockback, float stun, int dflags, int mod )
{
	gclient_t *client;
	float take;
	float save;
	float asave;
	qboolean statDmg;

	if( !targ || !targ->takedamage )
		return;

	if( !attacker )
	{
		attacker = world;
		mod = MOD_TRIGGER_HURT;
	}

	meansOfDeath = mod;

	client = targ->r.client;

	// Cgg - race mode: players don't interact with one another
	if( GS_RaceGametype() )
	{
		if( attacker->r.client && targ->r.client && attacker != targ )
			return;
	}

	// push
	if( !( dflags & DAMAGE_NO_KNOCKBACK ) )
		G_KnockBackPush( targ, attacker, pushdir, knockback, dflags );

	// stun
	if( g_allow_stun->integer && !( dflags & (DAMAGE_NO_STUN|FL_GODMODE) )
		&& (int)stun > 0 && targ->r.client && targ->r.client->resp.takeStun &&
		!GS_IsTeamDamage( &targ->s, &attacker->s ) && ( targ != attacker ) )
	{
		if( dflags & DAMAGE_STUN_CLAMP )
		{
			if( targ->r.client->ps.pmove.stats[PM_STAT_STUN] < (int)stun )
				targ->r.client->ps.pmove.stats[PM_STAT_STUN] = (int)stun;
		}
		else
			targ->r.client->ps.pmove.stats[PM_STAT_STUN] += (int)stun;

		clamp( targ->r.client->ps.pmove.stats[PM_STAT_STUN], 0, MAX_STUN_TIME );
	}

	// dont count self-damage cause it just adds the same to both stats
	statDmg = ( attacker != targ ) && ( mod != MOD_TELEFRAG );

	// apply handicap on the damage given
	if( statDmg && attacker->r.client && !GS_Instagib() )
	{
		// handicap is a percentage value
		if( attacker->r.client->handicap != 0 )
			damage *= 1.0 - (attacker->r.client->handicap * 0.01f);
	}

	take = damage;
	save = 0;

	// check for cases where damage is protected
	if( !( dflags & DAMAGE_NO_PROTECTION ) )
	{
		// check for godmode
		if( targ->flags & FL_GODMODE )
		{
			take = 0;
			save = damage;
		}
		// never damage in timeout
		else if( GS_MatchPaused() )
		{
			take = save = 0;
		}
		// ca has self splash damage disabled
		else if( ( dflags & DAMAGE_RADIUS ) && attacker == targ && !GS_SelfDamage() )
		{
			take = save = 0;
		}
		// don't get damage from players in race
		else if( ( GS_RaceGametype() ) && attacker->r.client && targ->r.client &&
			( attacker->r.client != targ->r.client ) )
		{
			take = save = 0;
		}
		// team damage avoidance
		else if( GS_IsTeamDamage( &targ->s, &attacker->s ) && !G_Gametype_CanTeamDamage( dflags ) )
		{
			take = save = 0;
		}
		// apply warShell powerup protection
		else if( targ->r.client && targ->r.client->ps.inventory[POWERUP_SHELL] > 0 )
		{
			// warshell offers full protection in instagib
			if( GS_Instagib() )
			{
				take = 0;
				save = damage;
			}
			else
			{
				take = ( damage * 0.25f );
				save = damage - take;
			}
			// todo : add protection sound
		}
	}

	asave = G_CheckArmor( targ, take, dflags );
	take -= asave;

	//treat cheat/powerup savings the same as armor
	asave += save;

	// APPLY THE DAMAGES

	if( !take && !asave )
		return;

	// do the damage
	if( take <= 0 )
		return;

	// adding damage given/received to stats
	if( statDmg && attacker->r.client && !targ->deadflag && targ->movetype != MOVETYPE_PUSH && targ->s.type != ET_CORPSE )
	{
		attacker->r.client->level.stats.total_damage_given += take + asave;
		teamlist[attacker->s.team].stats.total_damage_given += take + asave;
		if( GS_IsTeamDamage( &targ->s, &attacker->s ) )
		{
			attacker->r.client->level.stats.total_teamdamage_given += take + asave;
			teamlist[attacker->s.team].stats.total_teamdamage_given += take + asave;
		}
	}

	G_Gametype_ScoreEvent( attacker->r.client, "dmg", va( "%i %f %i", targ->s.number, damage, attacker->s.number ) );

	if( statDmg && client )
	{
		client->level.stats.total_damage_received += take + asave;
		teamlist[targ->s.team].stats.total_damage_received += take + asave;
		if( GS_IsTeamDamage( &targ->s, &attacker->s ) )
		{
			client->level.stats.total_teamdamage_received += take + asave;
			teamlist[targ->s.team].stats.total_teamdamage_received += take + asave;
		}
	}

	// accumulate received damage for snapshot effects
	{
		vec3_t dorigin;

		if( inflictor == world && mod == MOD_FALLING ) // it's fall damage
			targ->snap.damage_fall += take + save;

		if( point[0] != 0.0f || point[1] != 0.0f || point[2] != 0.0f )
			VectorCopy( point, dorigin );
		else
			VectorSet( dorigin,
			targ->s.origin[0],
			targ->s.origin[1],
			targ->s.origin[2] + targ->viewheight );

		G_BlendFrameDamage( targ, take, &targ->snap.damage_taken, dorigin, dmgdir, targ->snap.damage_at, targ->snap.damage_dir );
		G_BlendFrameDamage( targ, save, &targ->snap.damage_saved, dorigin, dmgdir, targ->snap.damage_at, targ->snap.damage_dir );

		if( targ->r.client )
		{
			if( mod != MOD_FALLING && mod != MOD_TELEFRAG && mod != MOD_SUICIDE )
			{
				if( inflictor == world || attacker == world )
				{
					// for world inflicted damage use always 'frontal'
					G_ClientAddDamageIndicatorImpact( targ->r.client, take + save, NULL );
				}
				else if( dflags & DAMAGE_RADIUS )
				{
					// for splash hits the direction is from the inflictor origin
					G_ClientAddDamageIndicatorImpact( targ->r.client, take + save, pushdir );
				}
				else
				{	// for direct hits the direction is the projectile direction
					G_ClientAddDamageIndicatorImpact( targ->r.client, take + save, dmgdir );
				}
			}
		}
	}

	targ->health = targ->health - take;

	// add damage done to stats
	if( !GS_IsTeamDamage( &targ->s, &attacker->s ) && statDmg && G_ModToAmmo( mod ) != AMMO_NONE && client && attacker->r.client )
	{
		attacker->r.client->level.stats.accuracy_hits[G_ModToAmmo( mod )-AMMO_GUNBLADE]++;
		attacker->r.client->level.stats.accuracy_damage[G_ModToAmmo( mod )-AMMO_GUNBLADE] += damage;
		teamlist[attacker->s.team].stats.accuracy_hits[G_ModToAmmo( mod )-AMMO_GUNBLADE]++;
		teamlist[attacker->s.team].stats.accuracy_damage[G_ModToAmmo( mod )-AMMO_GUNBLADE] += damage;

		G_AwardPlayerHit( targ, attacker, mod );
	}

	// accumulate given damage for hit sounds
	if( ( take || asave ) && targ != attacker && client && !targ->deadflag )
	{
		if( attacker )
		{
			if( GS_IsTeamDamage( &targ->s, &attacker->s ) )
				attacker->snap.damageteam_given += take + asave; // we want to know how good our hit was, so saved also matters
			else
				attacker->snap.damage_given += take + asave;
		}
	}

	if( G_IsDead( targ ) )
	{
		if( client )
			targ->flags |= FL_NO_KNOCKBACK;
		G_Killed( targ, inflictor, attacker, HEALTH_TO_INT( take ), point, mod );
	}
	else 
	{
		G_CallPain( targ, attacker, knockback, take );
	}
}
Exemple #26
0
void W_Fire_Electrobolt_FullInstant( edict_t *self, vec3_t start, vec3_t angles, float maxdamage, float mindamage, int maxknockback, int minknockback, int stun, int range, int minDamageRange, 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;

#define FULL_DAMAGE_RANGE g_projectile_prestep->value

	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 );
	clamp_high( minDamageRange, range );

	if( minDamageRange <= FULL_DAMAGE_RANGE )
		minDamageRange = FULL_DAMAGE_RANGE + 1;

	if( range <= FULL_DAMAGE_RANGE + 1 )
		range = FULL_DAMAGE_RANGE + 1;

	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, dist;

			dist = DistanceFast( tr.endpos, start );
			if( dist <= FULL_DAMAGE_RANGE )
				frac = 0.0f;
			else
			{
				frac = ( dist - FULL_DAMAGE_RANGE ) / (float)( minDamageRange - FULL_DAMAGE_RANGE );
				clamp( frac, 0.0f, 1.0f );
			}

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

			//G_Printf( "mindamagerange %i frac %.1f damage %i\n", minDamageRange, 1.0f - frac, (int)damage );

			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 = FIRE_MODE_STRONG;
			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 = FIRE_MODE_STRONG;

#undef FULL_DAMAGE_RANGE
}
Exemple #27
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;
	}
}
Exemple #28
0
/*
* W_Fire_Instagun_Strong
*/
void W_Fire_Instagun( edict_t *self, vec3_t start, vec3_t angles, float damage, int knockback,
					 int stun, int radius, int range, int mod, int timeDelta )
{
	vec3_t from, end, dir;
	trace_t	tr;
	edict_t	*ignore, *event;
	int mask;
	qboolean missed = qtrue;
	int dmgflags = 0;

	if( GS_Instagib() )
		damage = 9999;

	AngleVectors( angles, dir, NULL, NULL );
	VectorMA( start, range, dir, end );
	VectorCopy( start, from );
	ignore = self;
	mask = MASK_SHOT;
	if( GS_RaceGametype() )
		mask = MASK_SOLID;
	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
		if( tr.ent == world->s.number 
			|| game.edicts[tr.ent].movetype == MOVETYPE_NONE 
			|| game.edicts[tr.ent].movetype == MOVETYPE_PUSH )
		{
			if( g_instajump->integer && self && self->r.client )
			{
				// create a temporary inflictor entity
				edict_t *inflictor;

				inflictor = G_Spawn();
				inflictor->s.solid = SOLID_NOT;
				inflictor->timeDelta = 0;
				VectorCopy( tr.endpos, inflictor->s.origin );
				inflictor->s.ownerNum = ENTNUM( self );
				inflictor->projectileInfo.maxDamage = 0;
				inflictor->projectileInfo.minDamage = 0;
				inflictor->projectileInfo.maxKnockback = knockback;
				inflictor->projectileInfo.minKnockback = 1;
				inflictor->projectileInfo.stun = 0;
				inflictor->projectileInfo.radius = radius;

				G_RadiusDamage( inflictor, self, &tr.plane, NULL, mod );

				G_FreeEdict( inflictor );
			}
			break;
		}

		// allow trail to go through SOLID_BBOX entities (players, gibs, etc)
		if( !ISBRUSHMODEL( game.edicts[tr.ent].s.modelindex ) )
			ignore = &game.edicts[tr.ent];

		if( ( &game.edicts[tr.ent] != self ) && ( game.edicts[tr.ent].takedamage ) )
		{
			G_Damage( &game.edicts[tr.ent], self, self, dir, dir, tr.endpos, damage, knockback, stun, dmgflags, mod );
			// spawn a impact event on each damaged ent
			event = G_SpawnEvent( EV_INSTA_EXPLOSION, DirToByte( tr.plane.normal ), tr.endpos );
			event->s.firemode = FIRE_MODE_STRONG;
			if( game.edicts[tr.ent].r.client )
				missed = qfalse;
		}
	}

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

	// send the weapon fire effect
	event = G_SpawnEvent( EV_INSTATRAIL, ENTNUM( self ), start );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorScale( dir, 1024, event->s.origin2 );
}
/*
* CG_DamageIndicatorAdd
*/
void CG_DamageIndicatorAdd( int damage, const vec3_t dir )
{
	int i;
	unsigned int damageTime;
	vec3_t playerAngles;
	mat3_t playerAxis;
// epsilons are 30 degrees
#define INDICATOR_EPSILON 0.5f
#define INDICATOR_EPSILON_UP 0.85f
#define TOP_BLEND 0
#define RIGHT_BLEND 1
#define BOTTOM_BLEND 2
#define LEFT_BLEND 3
	float blends[4];
	float forward, side;

	if( !cg_damage_indicator->integer )
		return;

	playerAngles[PITCH] = 0;
	playerAngles[YAW] = cg.predictedPlayerState.viewangles[YAW];
	playerAngles[ROLL] = 0;

	Matrix3_FromAngles( playerAngles, playerAxis );

	if( cg_damage_indicator_time->value < 0 )
		trap_Cvar_SetValue( "cg_damage_indicator_time", 0 );

	Vector4Set( blends, 0, 0, 0, 0 );
	damageTime = damage * cg_damage_indicator_time->value;

	// up and down go distributed equally to all blends and assumed when no dir is given
	if( !dir || VectorCompare( dir, vec3_origin ) || cg_damage_indicator->integer == 2 || GS_Instagib() ||
		( fabs( DotProduct( dir, &playerAxis[AXIS_UP] ) ) > INDICATOR_EPSILON_UP ) )
	{
		blends[RIGHT_BLEND] += damageTime;
		blends[LEFT_BLEND] += damageTime;
		blends[TOP_BLEND] += damageTime;
		blends[BOTTOM_BLEND] += damageTime;
	}
	else
	{
		side = DotProduct( dir, &playerAxis[AXIS_RIGHT] );
		if( side > INDICATOR_EPSILON )
			blends[LEFT_BLEND] += damageTime;
		else if( side < -INDICATOR_EPSILON )
			blends[RIGHT_BLEND] += damageTime;

		forward = DotProduct( dir, &playerAxis[AXIS_FORWARD] );
		if( forward > INDICATOR_EPSILON )
			blends[BOTTOM_BLEND] += damageTime;
		else if( forward < -INDICATOR_EPSILON )
			blends[TOP_BLEND] += damageTime;
	}

	for( i = 0; i < 4; i++ )
	{
		if( cg.damageBlends[i] < cg.time + blends[i] )
			cg.damageBlends[i] = cg.time + blends[i];
	}
#undef TOP_BLEND
#undef RIGHT_BLEND
#undef BOTTOM_BLEND
#undef LEFT_BLEND
#undef INDICATOR_EPSILON
#undef INDICATOR_EPSILON_UP
}