Esempio n. 1
0
//QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8)
//Spawns an explosion temporary entity when used.
//
//"delay"		wait this long before going off
//"dmg"		how much radius damage should be done, defaults to 0
static void target_explosion_explode( edict_t *self )
{
	float save;
	int radius;
	edict_t *event;

	G_RadiusDamage( self, self->activator, NULL, NULL, MOD_EXPLOSIVE );

	if( ( self->projectileInfo.radius * 1/8 ) > 255 )
	{
		radius = ( self->projectileInfo.radius * 1/16 ) & 0xFF;
		if( radius < 1 )
			radius = 1;
		event = G_SpawnEvent( EV_EXPLOSION2, radius, self->s.origin );
	}
	else
	{
		radius = ( self->projectileInfo.radius * 1/8 ) & 0xFF;
		if( radius < 1 )
			radius = 1;
		event = G_SpawnEvent( EV_EXPLOSION1, radius, self->s.origin );
	}

	save = self->delay;
	self->delay = 0;
	G_UseTargets( self, self->activator );
	self->delay = save;
}
Esempio n. 2
0
//==========================================
// AITools_DrawPath
// Draws the current path (floods as hell also)
//==========================================
void AITools_DrawPath( edict_t *self, int node_to )
{
	static unsigned int drawnpath_timeout;
	int count = 0;
	int pos = 0;

	//don't draw it every frame (flood)
	if( level.time < drawnpath_timeout )
		return;

	drawnpath_timeout = level.time + 4 * game.snapFrameTime;

	if( self->ai->path.goalNode != node_to )
		return;

	pos = self->ai->path.numNodes;

	// Now set up and display the path
	while( self->ai->path.nodes[pos] != node_to && count < 32 && pos > 0 )
	{
		edict_t	*event;

		event = G_SpawnEvent( EV_GREEN_LASER, 0, nodes[self->ai->path.nodes[pos]].origin );
		event->r.svflags = SVF_TRANSMITORIGIN2;
		VectorCopy( nodes[self->ai->path.nodes[pos-1]].origin, event->s.origin2 );
		G_SetBoundsForSpanEntity( event, 8 );
		GClip_LinkEntity( event );

		pos--;
		count++;
	}
}
Esempio n. 3
0
//==========================================
// AITools_DrawLine
// Just so I don't hate to write the event every time
//==========================================
void AITools_DrawLine( vec3_t origin, vec3_t dest )
{
	edict_t	*event;

	event = G_SpawnEvent( EV_GREEN_LASER, 0, origin );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorCopy( dest, event->s.origin2 );
}
Esempio n. 4
0
/*
* W_Touch_Rocket
*/
static void W_Touch_Rocket( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags ) {
	int mod_splash;
	vec3_t dir;
	int hitType;

	if( surfFlags & SURF_NOIMPACT ) {
		G_FreeEdict( ent );
		return;
	}

	hitType = G_Projectile_HitStyle( ent, other );
	if( hitType == PROJECTILE_TOUCH_NOT ) {
		return;
	}

	if( other->takedamage ) {
		int directHitDamage = ent->projectileInfo.maxDamage;

		VectorNormalize2( ent->velocity, dir );

		if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) { // use hybrid direction from splash and projectile

			G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta );
		} else {
			VectorNormalize2( ent->velocity, dir );

			if( hitType == PROJECTILE_TOUCH_DIRECTAIRHIT ) {
				directHitDamage += DIRECTAIRTHIT_DAMAGE_BONUS;
			} else if( hitType == PROJECTILE_TOUCH_DIRECTHIT ) {
				directHitDamage += DIRECTHIT_DAMAGE_BONUS;
			}
		}

		G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, directHitDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style );
	}

	if( ent->s.effects & EF_STRONG_WEAPON ) {
		mod_splash = MOD_ROCKET_SPLASH_S;
	} else {
		mod_splash = MOD_ROCKET_SPLASH_W;
	}

	G_RadiusDamage( ent, ent->r.owner, plane, other, mod_splash );

	// spawn the explosion
	if( !( surfFlags & SURF_NOIMPACT ) ) {
		edict_t *event;
		vec3_t explosion_origin;

		VectorMA( ent->s.origin, -0.02, ent->velocity, explosion_origin );
		event = G_SpawnEvent( EV_ROCKET_EXPLOSION, DirToByte( plane ? plane->normal : NULL ), explosion_origin );
		event->s.firemode = ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;
		event->s.weapon = ( ( ent->projectileInfo.radius * 1 / 8 ) > 255 ) ? 255 : ( ent->projectileInfo.radius * 1 / 8 );
	}

	// free the rocket at next frame
	G_FreeEdict( ent );
}
Esempio n. 5
0
//==========================================
// AITools_DrawLine
// Just so I don't hate to write the event every time
//==========================================
void AITools_DrawLine( vec3_t origin, vec3_t dest )
{
	edict_t	*event;

	event = G_SpawnEvent( EV_GREEN_LASER, 0, origin );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorCopy( dest, event->s.origin2 );
	G_SetBoundsForSpanEntity( event, 8 );
	GClip_LinkEntity( event );
}
Esempio n. 6
0
//==========================================
// AITools_DrawColorLine
// Just so I don't hate to write the event every time
//==========================================
void AITools_DrawColorLine( vec3_t origin, vec3_t dest, int color, int parm )
{
	edict_t	*event;

	event = G_SpawnEvent( EV_PNODE, parm, origin );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorCopy( dest, event->s.origin2 );

	event->s.colorRGBA = color;
}
Esempio n. 7
0
//==========================================
// AITools_DrawColorLine
// Just so I don't hate to write the event every time
//==========================================
void AITools_DrawColorLine( vec3_t origin, vec3_t dest, int color, int parm )
{
	edict_t	*event;

	event = G_SpawnEvent( EV_PNODE, parm, origin );
	event->s.colorRGBA = color;
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorCopy( dest, event->s.origin2 );
	G_SetBoundsForSpanEntity( event, 8 );
	GClip_LinkEntity( event );
}
Esempio n. 8
0
/*
* W_Touch_Bolt
*/
static void W_Touch_Bolt( edict_t *self, edict_t *other, cplane_t *plane, int surfFlags )
{
	edict_t *event;
	qboolean missed = qtrue;
	int hitType;

	if( surfFlags & SURF_NOIMPACT )
	{
		G_FreeEdict( self );
		return;
	}

	if( other == self->enemy )
		return;

	hitType = G_Projectile_HitStyle( self, other );
	if( hitType == PROJECTILE_TOUCH_NOT )
		return;

	if( other->takedamage )
	{
		vec3_t invdir;
		G_Damage( other, self, self->r.owner, self->velocity, self->velocity, self->s.origin, self->projectileInfo.maxDamage, self->projectileInfo.maxKnockback, self->projectileInfo.stun, 0, MOD_ELECTROBOLT_W );
		VectorNormalize2( self->velocity, invdir );
		VectorScale( invdir, -1, invdir );
		event = G_SpawnEvent( EV_BOLT_EXPLOSION, DirToByte( invdir ), self->s.origin );
		event->s.firemode = FIRE_MODE_WEAK;
		if( other->r.client ) missed = qfalse;
	}
	else if( !( surfFlags & SURF_NOIMPACT ) )
	{   
		// add explosion event
		event = G_SpawnEvent( EV_BOLT_EXPLOSION, DirToByte( plane ? plane->normal : NULL ), self->s.origin );
		event->s.firemode = FIRE_MODE_WEAK;
	}

	if( missed && self->r.client )
		G_AwardPlayerMissedElectrobolt( self->r.owner, MOD_ELECTROBOLT_W ); // hit something that isnt a player

	G_FreeEdict( self );
}
Esempio n. 9
0
static void W_Plasma_Explosion( edict_t *ent, edict_t *ignore, cplane_t *plane, int surfFlags ) {
	edict_t *event;
	int radius = ( ( ent->projectileInfo.radius * 1 / 8 ) > 127 ) ? 127 : ( ent->projectileInfo.radius * 1 / 8 );

	event = G_SpawnEvent( EV_PLASMA_EXPLOSION, DirToByte( plane ? plane->normal : NULL ), ent->s.origin );
	event->s.firemode = ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;
	event->s.weapon = radius & 127;

	G_RadiusDamage( ent, ent->r.owner, plane, ignore, ent->style );

	G_FreeEdict( ent );
}
Esempio n. 10
0
/*
* W_Touch_GunbladeBlast
*/
static void W_Touch_GunbladeBlast( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags )
{
	vec3_t dir;
	int hitType;

	if( surfFlags & SURF_NOIMPACT )
	{
		G_FreeEdict( ent );
		return;
	}

	hitType = G_Projectile_HitStyle( ent, other );
	if( hitType == PROJECTILE_TOUCH_NOT )
		return;

	if( other->takedamage )
	{
		VectorNormalize2( ent->velocity, dir );

		if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) // use hybrid direction from splash and projectile
		{
			G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta );
		}
		else
		{
			VectorNormalize2( ent->velocity, dir );
		}

		G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, ent->projectileInfo.maxDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style );
	}

	G_RadiusDamage( ent, ent->r.owner, plane, other, MOD_GUNBLADE_S );

	// add explosion event
	if( ( !other->takedamage || ISBRUSHMODEL( other->s.modelindex ) ) )
	{
		edict_t *event;

		event = G_SpawnEvent( EV_GUNBLADEBLAST_IMPACT, DirToByte( plane ? plane->normal : NULL ), ent->s.origin );
		event->s.weapon = ( ( ent->projectileInfo.radius * 1/8 ) > 127 ) ? 127 : ( ent->projectileInfo.radius * 1/8 );
		event->s.skinnum = ( ( ent->projectileInfo.maxKnockback * 1/8 ) > 255 ) ? 255 : ( ent->projectileInfo.maxKnockback * 1/8 );
	}

	// free at next frame
	G_FreeEdict( ent );
}
Esempio n. 11
0
void ThrowSmallPileOfGibs( edict_t *self, int damage )
{
	vec3_t origin;
	edict_t	*event;
	int contents;
	int i;

	contents = G_PointContents( self->s.origin );
	if( contents & CONTENTS_NODROP )
		return;

	for( i = 0; i < 3; i++ )
		origin[i] = self->s.origin[i] + ( 0.5f * ( self->r.maxs[i] + self->r.mins[i] ) ) + 24;

	event = G_SpawnEvent( EV_SPOG, damage, origin );
	event->r.svflags |= SVF_TRANSMITORIGIN2;
	VectorCopy( self->velocity, event->s.origin2 );
}
Esempio n. 12
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 ) )
			{
			}
		}
	}
}
Esempio n. 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 );
}
Esempio n. 14
0
/*
* W_Grenade_ExplodeDir
*/
static void W_Grenade_ExplodeDir( edict_t *ent, vec3_t normal ) {
	vec3_t origin;
	int radius;
	edict_t *event;
	vec3_t up = { 0, 0, 1 };
	vec_t *dir = normal ? normal : up;

	G_RadiusDamage( ent,
					ent->r.owner,
					NULL,
					ent->enemy,
					( ent->s.effects & EF_STRONG_WEAPON ) ? MOD_GRENADE_SPLASH_S : MOD_GRENADE_SPLASH_W
					);

	radius = ( ( ent->projectileInfo.radius * 1 / 8 ) > 127 ) ? 127 : ( ent->projectileInfo.radius * 1 / 8 );
	VectorMA( ent->s.origin, -0.02, ent->velocity, origin );
	event = G_SpawnEvent( EV_GRENADE_EXPLOSION, ( dir ? DirToByte( dir ) : 0 ), ent->s.origin );
	event->s.firemode = ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;
	event->s.weapon = radius;

	G_FreeEdict( ent );
}
Esempio n. 15
0
void G_BOTvsay_f( edict_t *ent, const char *msg, bool team )
{
	edict_t	*event = NULL;
	g_vsays_t *vsay;
	const char *text = NULL;

	if( !( ent->r.svflags & SVF_FAKECLIENT ) )
		return;

	if( ent->r.client && ( ent->r.client->muted & 2 ) )
		return;

	for( vsay = g_vsays; vsay->name; vsay++ )
	{
		if( !Q_stricmp( msg, vsay->name ) )
		{
			event = G_SpawnEvent( EV_VSAY, vsay->id, NULL );
			text = vsay->message;
			break;
		}
	}

	if( event && text )
	{
		event->r.svflags |= SVF_BROADCAST; // force sending even when not in PVS
		event->s.ownerNum = ent->s.number;
		if( team )
		{
			event->s.team = ent->s.team;
			event->r.svflags |= SVF_ONLYTEAM; // send only to clients with the same ->s.team value
		}

		if( team )
			G_Say_Team( ent, va( "(v) %s", text ), false );
		else
			G_ChatMsg( NULL, ent, false, "(v) %s", text );
	}
}
Esempio n. 16
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 );
}
Esempio n. 17
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 );
}
Esempio n. 18
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 ) ) {
			}
		}
	}
}
Esempio n. 19
0
/*
* G_vsay_f
*/
static void G_vsay_f( edict_t *ent, bool team )
{
	edict_t	*event = NULL;
	g_vsays_t *vsay;
	const char *text = NULL;
	char *msg = trap_Cmd_Argv( 1 );

	if( ent->r.client && ent->r.client->muted & 2 )
		return;

	if( ( !GS_TeamBasedGametype() || GS_InvidualGameType() ) && ent->s.team != TEAM_SPECTATOR )
		team = false;

	if( !( ent->r.svflags & SVF_FAKECLIENT ) )
	{                                      // ignore flood checks on bots
		if( ent->r.client->level.last_vsay > game.realtime - 500 )
			return; // ignore silently vsays in that come in rapid succession
		ent->r.client->level.last_vsay = game.realtime;

		if( CheckFlood( ent, false ) )
			return;
	}

	for( vsay = g_vsays; vsay->name; vsay++ )
	{
		if( !Q_stricmp( msg, vsay->name ) )
		{
			event = G_SpawnEvent( EV_VSAY, vsay->id, NULL );
			text = vsay->message;
			break;
		}
	}

	if( event && text )
	{
		char saystring[256];

		event->r.svflags |= SVF_BROADCAST; // force sending even when not in PVS
		event->s.ownerNum = ent->s.number;
		if( team )
		{
			event->s.team = ent->s.team;
			event->r.svflags |= SVF_ONLYTEAM; // send only to clients with the same ->s.team value
		}

		if( trap_Cmd_Argc() > 2 )
		{
			int i;

			saystring[0] = 0;
			for( i = 2; i < trap_Cmd_Argc(); i++ )
			{
				Q_strncatz( saystring, trap_Cmd_Argv( i ), sizeof( saystring ) );
				Q_strncatz( saystring, " ", sizeof( saystring ) );
			}
			text = saystring;
		}

		if( team )
			G_Say_Team( ent, va( "(v) %s", text ), false );
		else
			G_ChatMsg( NULL, ent, false, "(v) %s", text );
		return;
	}

	// unknown token, print help
	{
		char string[MAX_STRING_CHARS];

		// print information
		string[0] = 0;
		if( msg && msg[0] != '\0' )
			Q_strncatz( string, va( "%sUnknown vsay token%s \"%s\"\n", S_COLOR_YELLOW, S_COLOR_WHITE, msg ), sizeof( string ) );
		Q_strncatz( string, va( "%svsays:%s\n", S_COLOR_YELLOW, S_COLOR_WHITE ), sizeof( string ) );
		for( vsay = g_vsays; vsay->name; vsay++ )
		{
			if( strlen( vsay->name ) + strlen( string ) < sizeof( string ) - 6 )
			{
				Q_strncatz( string, va( "%s ", vsay->name ), sizeof( string ) );
			}
		}
		Q_strncatz( string, "\n", sizeof( string ) );
		G_PrintMsg( ent, string );
	}
}
Esempio n. 20
0
/*
* G_EdictsAddSnapEffects
* add effects based on accumulated info along the server frame
*/
static void G_SnapEntities( void )
{
	edict_t *ent;
	int i;
	vec3_t dir, origin;

	for( i = 0, ent = &game.edicts[0]; i < game.numentities; i++, ent++ )
	{
		if( !ent->r.inuse || ( ent->r.svflags & SVF_NOCLIENT ) )
			continue;

		if( ent->s.type == ET_PARTICLES ) // particles use a special configuration
		{
			ent->s.frame = ent->particlesInfo.speed;
			ent->s.modelindex = ent->particlesInfo.shaderIndex;
			ent->s.modelindex2 = ent->particlesInfo.spread;
			ent->s.counterNum = ent->particlesInfo.time;
			ent->s.weapon = ent->particlesInfo.frequency;

			ent->s.effects = ent->particlesInfo.size & 0xFF;
			if( ent->particlesInfo.spherical )
				ent->s.effects |= ( 1<<8 );
			if( ent->particlesInfo.bounce )
				ent->s.effects |= ( 1<<9 );
			if( ent->particlesInfo.gravity )
				ent->s.effects |= ( 1<<10 );
			if( ent->particlesInfo.expandEffect )
				ent->s.effects |= ( 1<<11 );
			if( ent->particlesInfo.shrinkEffect )
				ent->s.effects |= ( 1<<11 );

			GClip_LinkEntity( ent );

			continue;
		}

		if( ent->s.type == ET_PLAYER || ent->s.type == ET_CORPSE )
		{
			// this is pretty hackish. We exploit the fact that 0.5 servers *do not* transmit
			// origin2/old_origin for ET_PLAYER/ET_CORPSE entities, and we use it for sending the player velocity
			if( !G_ISGHOSTING( ent ) )
			{
				ent->r.svflags |= SVF_TRANSMITORIGIN2;
				VectorCopy( ent->velocity, ent->s.origin2 );
			}
			else
				ent->r.svflags &= ~SVF_TRANSMITORIGIN2;
		}

		if( ISEVENTENTITY( ent ) || G_ISGHOSTING( ent ) || !ent->takedamage )
			continue;

		// types which can have accumulated damage effects
		if( ( ent->s.type == ET_GENERIC || ent->s.type == ET_PLAYER || ent->s.type == ET_CORPSE ) ) // doors don't bleed
		{
			// Until we get a proper damage saved effect, we accumulate both into the blood fx
			// so, at least, we don't send 2 entities where we can send one
			ent->snap.damage_taken += ent->snap.damage_saved;
			//ent->snap.damage_saved = 0;

			//spawn accumulated damage
			if( ent->snap.damage_taken && !( ent->flags & FL_GODMODE ) && HEALTH_TO_INT( ent->health ) > 0 )
			{
				edict_t *event;
				float damage = ent->snap.damage_taken;
				if( damage > 120 )
					damage = 120;

				VectorCopy( ent->snap.damage_dir, dir );
				VectorNormalize( dir );
				VectorAdd( ent->s.origin, ent->snap.damage_at, origin );

				if( ent->s.type == ET_PLAYER || ent->s.type == ET_CORPSE )
				{
					event = G_SpawnEvent( EV_BLOOD, DirToByte( dir ), origin );
					event->s.damage = HEALTH_TO_INT( damage );
					event->s.ownerNum = i; // set owner

					// ET_PLAYERS can also spawn sound events
					if( ent->s.type == ET_PLAYER )
					{
						// play an apropriate pain sound
						if( level.time >= ent->pain_debounce_time )
						{
							// see if it should pain for a FALL or for damage received
							if( ent->snap.damage_fall )
							{
								ent->pain_debounce_time = level.time + 200;
							}
							else if( !G_IsDead( ent ) )
							{
								if( ent->r.client->ps.inventory[POWERUP_SHELL] > 0 )
									G_AddEvent( ent, EV_PAIN, PAIN_WARSHELL, true );
								else if( ent->health <= 20 )
									G_AddEvent( ent, EV_PAIN, PAIN_20, true );
								else if( ent->health <= 35 )
									G_AddEvent( ent, EV_PAIN, PAIN_30, true );
								else if( ent->health <= 60 )
									G_AddEvent( ent, EV_PAIN, PAIN_60, true );
								else
									G_AddEvent( ent, EV_PAIN, PAIN_100, true );

								ent->pain_debounce_time = level.time + 400;
							}
						}
					}
				}
				else
				{
					event = G_SpawnEvent( EV_SPARKS, DirToByte( dir ), origin );
					event->s.damage = HEALTH_TO_INT( damage );
				}
			}
		}
	}
}
Esempio n. 21
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 );
}
Esempio n. 22
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
}
Esempio n. 23
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. 24
0
//QUAKED target_laser (0 .5 0) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FAT
//When triggered, fires a laser.  You can either set a target or a direction.
//-------- KEYS --------
//angles: alternate "pitch, yaw, roll" angles method of aiming laser (default 0 0 0).
//target : point this to a target_position entity to set the laser's aiming direction.
//targetname : the activating trigger points to this.
//notsingle : when set to 1, entity will not spawn in Single Player mode
//notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
//notduel : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes. (jal: todo)
//notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
//notctf : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes. (jal: todo)
//-------- SPAWNFLAGS --------
//START_ON : when set, the laser will start on in the game.
//RED :
//GREEN : BLUE :
//YELLOW :
//ORANGE :
//FAT :
static void target_laser_think( edict_t *self )
{
	edict_t	*ignore;
	vec3_t start;
	vec3_t end;
	trace_t	tr;
	vec3_t point;
	vec3_t last_movedir;
	int count;

	// our lifetime has expired
	if( self->delay && ( self->wait * 1000 < level.time ) )
	{
		if( self->r.owner && self->r.owner->use )
			G_CallUse( self->r.owner, self, self->activator );

		G_FreeEdict( self );
		return;
	}

	if( self->spawnflags & 0x80000000 )
		count = 8;
	else
		count = 4;

	if( self->enemy )
	{
		VectorCopy( self->moveinfo.movedir, last_movedir );
		VectorMA( self->enemy->r.absmin, 0.5, self->enemy->r.size, point );
		VectorSubtract( point, self->s.origin, self->moveinfo.movedir );
		VectorNormalize( self->moveinfo.movedir );
		if( !VectorCompare( self->moveinfo.movedir, last_movedir ) )
			self->spawnflags |= 0x80000000;
	}

	ignore = self;
	VectorCopy( self->s.origin, start );
	VectorMA( start, 2048, self->moveinfo.movedir, end );
	VectorClear( tr.endpos ); // shut up compiler
	while( 1 )
	{
		G_Trace( &tr, start, NULL, NULL, end, ignore, MASK_SHOT );
		if( tr.fraction == 1 )
			break;

		// hurt it if we can
		if( ( game.edicts[tr.ent].takedamage ) && !( game.edicts[tr.ent].flags & FL_IMMUNE_LASER ) )
		{
			if( game.edicts[tr.ent].r.client && self->activator->r.client )
			{
				if( !GS_TeamBasedGametype() ||
					game.edicts[tr.ent].s.team != self->activator->s.team )
					G_Damage( &game.edicts[tr.ent], self, self->activator, self->moveinfo.movedir, self->moveinfo.movedir, tr.endpos, self->dmg, 1, 0, 0, self->count );
			}
			else
			{
				G_Damage( &game.edicts[tr.ent], self, self->activator, self->moveinfo.movedir, self->moveinfo.movedir, tr.endpos, self->dmg, 1, 0, 0, self->count );
			}
		}

		// if we hit something that's not a monster or player or is immune to lasers, we're done
		if( !game.edicts[tr.ent].r.client )
		{
			if( self->spawnflags & 0x80000000 )
			{
				edict_t *event;

				self->spawnflags &= ~0x80000000;

				event = G_SpawnEvent( EV_LASER_SPARKS, DirToByte( tr.plane.normal ), tr.endpos );
				event->s.eventCount = count;
				event->s.colorRGBA = self->s.colorRGBA;
			}
			break;
		}

		ignore = &game.edicts[tr.ent];
		VectorCopy( tr.endpos, start );
	}

	VectorCopy( tr.endpos, self->s.origin2 );
	G_SetBoundsForSpanEntity( self, 8 );

	GClip_LinkEntity( self );

	self->nextThink = level.time + 1;
}
Esempio n. 25
0
//QUAKED target_temp_entity (1 0 0) (-8 -8 -8) (8 8 8)
//Fire an origin based temp entity event to the clients.
//"style"		type byte
static void Use_Target_Tent( edict_t *ent, edict_t *other, edict_t *activator )
{
	G_SpawnEvent( ent->style, 0, ent->s.origin );
}