示例#1
0
void bulletFire( gentity_t *ent, float spread, int damage, int mod )
{
	trace_t   tr;
	vec3_t    end;
	float     r;
	float     u;
	gentity_t *tent;
	gentity_t *traceEnt;

	r = random() * M_PI * 2.0f;
	u = sin( r ) * crandom() * spread * 16;
	r = cos( r ) * crandom() * spread * 16;
	VectorMA( muzzle, 8192 * 16, forward, end );
	VectorMA( end, r, right, end );
	VectorMA( end, u, up, end );

	// don't use unlagged if this is not a client (e.g. turret)
	if ( ent->client )
	{
		G_UnlaggedOn( ent, muzzle, 8192 * 16 );
		trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT );
		G_UnlaggedOff();
	}
	else
	{
		trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT );
	}

	if ( tr.surfaceFlags & SURF_NOIMPACT )
	{
		return;
	}

	traceEnt = &g_entities[ tr.entityNum ];

	// snap the endpos to integers, but nudged towards the line
	SnapVectorTowards( tr.endpos, muzzle );

	// send bullet impact
	if ( traceEnt->takedamage &&
	     ( traceEnt->s.eType == ET_PLAYER ||
	       traceEnt->s.eType == ET_BUILDABLE ) )
	{
		tent = G_NewTempEntity( tr.endpos, EV_BULLET_HIT_FLESH );
		tent->s.eventParm = traceEnt->s.number;
	}
	else
	{
		tent = G_NewTempEntity( tr.endpos, EV_BULLET_HIT_WALL );
		tent->s.eventParm = DirToByte( tr.plane.normal );
	}

	tent->s.otherEntityNum = ent->s.number;

	if ( traceEnt->takedamage )
	{
		G_Damage( traceEnt, ent, ent, forward, tr.endpos,
		          damage, 0, mod );
	}
}
示例#2
0
static void SendRangedHitEvent( gentity_t *attacker, gentity_t *target, trace_t *tr )
{
	gentity_t *event;

	// snap the endpos to integers, but nudged towards the line
	G_SnapVectorTowards( tr->endpos, muzzle );

	if ( target->takedamage && ( target->s.eType == ET_BUILDABLE || target->s.eType == ET_PLAYER ) )
	{
		event = G_NewTempEntity( tr->endpos, EV_WEAPON_HIT_ENTITY );
	}
	else
	{
		event = G_NewTempEntity( tr->endpos, EV_WEAPON_HIT_ENVIRONMENT );
	}

	// normal
	event->s.eventParm = DirToByte( tr->plane.normal );

	// victim
	event->s.otherEntityNum = target->s.number;

	// attacker
	event->s.otherEntityNum2 = attacker->s.number;

	// weapon
	event->s.weapon = attacker->s.weapon;

	// weapon mode
	event->s.generic1 = attacker->s.generic1;
}
示例#3
0
/*
=============
G_Sound
=============
*/
void G_Sound( gentity_t *ent, int channel, int soundIndex )
{
	gentity_t *te;

	te = G_NewTempEntity( ent->r.currentOrigin, EV_GENERAL_SOUND );
	te->s.eventParm = soundIndex;
}
示例#4
0
void painSawFire( gentity_t *ent )
{
	trace_t   tr;
	vec3_t    temp;
	gentity_t *tent, *traceEnt;

	G_WideTrace( &tr, ent, PAINSAW_RANGE, PAINSAW_WIDTH, PAINSAW_HEIGHT,
	             &traceEnt );

	if ( !traceEnt || !traceEnt->takedamage )
	{
		return;
	}

	// hack to line up particle system with weapon model
	tr.endpos[ 2 ] -= 5.0f;

	// send blood impact
	if ( traceEnt->s.eType == ET_PLAYER || traceEnt->s.eType == ET_BUILDABLE )
	{
		BloodSpurt( ent, traceEnt, &tr );
	}
	else
	{
		VectorCopy( tr.endpos, temp );
		tent = G_NewTempEntity( temp, EV_MISSILE_MISS );
		tent->s.eventParm = DirToByte( tr.plane.normal );
		tent->s.weapon = ent->s.weapon;
		tent->s.generic1 = ent->s.generic1; //weaponMode
	}

	G_Damage( traceEnt, ent, ent, forward, tr.endpos, PAINSAW_DAMAGE, DAMAGE_NO_KNOCKBACK, MOD_PAINSAW );
}
示例#5
0
/*
===============
WideBloodSpurt

Calculates the position of a blood spurt for wide traces and generates an event
===============
*/
static void WideBloodSpurt( gentity_t *attacker, gentity_t *victim, trace_t *tr )
{
	gentity_t *tent;
	vec3_t    normal, origin;
	float     mag, radius;

	if ( !attacker->client )
	{
		return;
	}

	if ( victim->health <= 0 )
	{
		return;
	}

	if ( tr )
	{
		VectorSubtract( tr->endpos, victim->s.origin, normal );
	}
	else
	{
		VectorSubtract( attacker->client->ps.origin,
		                victim->s.origin, normal );
	}

	// Normalize the horizontal components of the vector difference to the
	// "radius" of the bounding box
	mag = sqrt( normal[ 0 ] * normal[ 0 ] + normal[ 1 ] * normal[ 1 ] );
	radius = victim->r.maxs[ 0 ] * 1.21f;

	if ( mag > radius )
	{
		normal[ 0 ] = normal[ 0 ] / mag * radius;
		normal[ 1 ] = normal[ 1 ] / mag * radius;
	}

	// Clamp origin to be within bounding box vertically
	if ( normal[ 2 ] > victim->r.maxs[ 2 ] )
	{
		normal[ 2 ] = victim->r.maxs[ 2 ];
	}

	if ( normal[ 2 ] < victim->r.mins[ 2 ] )
	{
		normal[ 2 ] = victim->r.mins[ 2 ];
	}

	VectorAdd( victim->s.origin, normal, origin );
	VectorNegate( normal, normal );
	VectorNormalize( normal );

	// Create the blood spurt effect entity
	tent = G_NewTempEntity( origin, EV_MISSILE_HIT );
	tent->s.eventParm = DirToByte( normal );
	tent->s.otherEntityNum = victim->s.number;
	tent->s.weapon = attacker->s.weapon;
	tent->s.generic1 = attacker->s.generic1; // weaponMode
}
示例#6
0
/*
===============
G_BroadcastEvent

Sends an event to every client
===============
*/
void G_BroadcastEvent( int event, int eventParm )
{
	gentity_t *ent;

	ent = G_NewTempEntity( vec3_origin, event );
	ent->s.eventParm = eventParm;
	ent->r.svFlags = SVF_BROADCAST; // send to everyone
}
示例#7
0
static void NotifyClientOfHit( gentity_t *attacker )
{
	gentity_t *event;

	if ( !attacker->client )
	{
		return;
	}

	event = G_NewTempEntity( attacker->s.origin, EV_HIT );
	event->r.svFlags = SVF_SINGLECLIENT;
	event->r.singleClient = attacker->client->ps.clientNum;
}
示例#8
0
void shotgunFire( gentity_t *ent )
{
	gentity_t *tent;

	// send shotgun blast
	tent = G_NewTempEntity( muzzle, EV_SHOTGUN );
	VectorScale( forward, 4096, tent->s.origin2 );
	SnapVector( tent->s.origin2 );
	tent->s.eventParm = rand() / ( RAND_MAX / 0x100 + 1 ); // seed for spread pattern
	tent->s.otherEntityNum = ent->s.number;
	G_UnlaggedOn( ent, muzzle, SHOTGUN_RANGE );
	ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent );
	G_UnlaggedOff();
}
示例#9
0
/*
===========
ClientDisconnect

Called when a player drops from the server.
Will not be called between levels.

This should NOT be called directly by any game logic,
call trap_DropClient(), which will call this and do
server system housekeeping.
============
*/
void ClientDisconnect( int clientNum )
{
	gentity_t *ent;
	gentity_t *tent;
	int       i;

	ent = g_entities + clientNum;

	if ( !ent->client || ent->client->pers.connected == CON_DISCONNECTED )
	{
		return;
	}

	G_LeaveTeam( ent );
	G_namelog_disconnect( ent->client );
	G_Vote( ent, TEAM_NONE, false );

	// stop any following clients
	for ( i = 0; i < level.maxclients; i++ )
	{
		// remove any /ignore settings for this clientNum
		Com_ClientListRemove( &level.clients[ i ].sess.ignoreList, clientNum );
	}

	// send effect if they were completely connected
	if ( ent->client->pers.connected == CON_CONNECTED &&
	     ent->client->sess.spectatorState == SPECTATOR_NOT )
	{
		tent = G_NewTempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT );
		tent->s.clientNum = ent->s.clientNum;
	}

	G_LogPrintf( "ClientDisconnect: %i [%s] (%s) \"%s^7\"", clientNum,
	             ent->client->pers.ip.str, ent->client->pers.guid, ent->client->pers.netname );

	ent->client->pers.connected = CON_DISCONNECTED;
	ent->client->sess.spectatorState = SPECTATOR_NOT;
	ent->client->ps.persistant[ PERS_SPECSTATE ] = SPECTATOR_NOT;

	G_FreeEntity(ent);
	ent->classname = "disconnected";
	ent->client = level.clients + clientNum;

	trap_SetConfigstring( CS_PLAYERS + clientNum, "" );

	CalculateRanks();

	Beacon::PropagateAll();
}
示例#10
0
static void FireShotgun( gentity_t *self )
{
	gentity_t *tent;

	// instead of an EV_WEAPON_HIT_* event, send this so client can generate the same spread pattern
	tent = G_NewTempEntity( muzzle, EV_SHOTGUN );
	VectorScale( forward, 4096, tent->s.origin2 );
	SnapVector( tent->s.origin2 );
	tent->s.eventParm = rand() / ( RAND_MAX / 0x100 + 1 ); // seed for spread pattern
	tent->s.otherEntityNum = self->s.number;

	// caclulate the pattern and do the damage
	G_UnlaggedOn( self, muzzle, SHOTGUN_RANGE );
	ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, self );
	G_UnlaggedOff();
}
示例#11
0
/*
===============
G_BroadcastEvent

Sends an event to every client
===============
*/
void G_BroadcastEvent( int event, int eventParm, team_t team )
{
	gentity_t *ent;

	ent = G_NewTempEntity( vec3_origin, event );
	ent->s.eventParm = eventParm;

	if ( team )
	{
		G_TeamToClientmask( team, &ent->r.loMask, &ent->r.hiMask );
		ent->r.svFlags = SVF_BROADCAST | SVF_CLIENTMASK;
	}
	else
	{
		ent->r.svFlags = SVF_BROADCAST;
	}
}
示例#12
0
static void FireTesla( gentity_t *self )
{
	trace_t   tr;
	vec3_t    origin, target;
	gentity_t *tent;

	if ( !self->target )
	{
		return;
	}

	// Move the muzzle from the entity origin up a bit to fire over turrets
	VectorMA( muzzle, self->r.maxs[ 2 ], self->s.origin2, origin );

	// Don't aim for the center, aim at the top of the bounding box
	VectorCopy( self->target->s.origin, target );
	target[ 2 ] += self->target->r.maxs[ 2 ];

	// Trace to the target entity
	trap_Trace( &tr, origin, NULL, NULL, target, self->s.number, MASK_SHOT );

	if ( tr.entityNum != self->target->s.number )
	{
		return;
	}

	// Client side firing effect
	self->s.eFlags |= EF_FIRING;

	// Deal damage
	if ( self->target->takedamage )
	{
		vec3_t dir;

		VectorSubtract( target, origin, dir );
		VectorNormalize( dir );
		G_Damage( self->target, self, self, dir, tr.endpos,
		          TESLAGEN_DMG, 0, MOD_TESLAGEN );
	}

	// Send tesla zap trail
	tent = G_NewTempEntity( tr.endpos, EV_TESLATRAIL );
	tent->s.generic1 = self->s.number; // src
	tent->s.clientNum = self->target->s.number; // dest
}
示例#13
0
void massDriverFire( gentity_t *ent )
{
	trace_t   tr;
	vec3_t    end;
	gentity_t *tent;
	gentity_t *traceEnt;

	VectorMA( muzzle, 8192.0f * 16.0f, forward, end );

	G_UnlaggedOn( ent, muzzle, 8192.0f * 16.0f );
	trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT );
	G_UnlaggedOff();

	if ( tr.surfaceFlags & SURF_NOIMPACT )
	{
		return;
	}

	traceEnt = &g_entities[ tr.entityNum ];

	// snap the endpos to integers, but nudged towards the line
	SnapVectorTowards( tr.endpos, muzzle );

	// send impact
	if ( traceEnt->takedamage &&
	     ( traceEnt->s.eType == ET_BUILDABLE ||
	       traceEnt->s.eType == ET_PLAYER ) )
	{
		BloodSpurt( ent, traceEnt, &tr );
	}
	else
	{
		tent = G_NewTempEntity( tr.endpos, EV_MISSILE_MISS );
		tent->s.eventParm = DirToByte( tr.plane.normal );
		tent->s.weapon = ent->s.weapon;
		tent->s.generic1 = ent->s.generic1; //weaponMode
	}

	if ( traceEnt->takedamage )
	{
		G_Damage( traceEnt, ent, ent, forward, tr.endpos,
		          MDRIVER_DMG, 0, MOD_MDRIVER );
	}
}
示例#14
0
/*
===============
BloodSpurt

Generates a blood spurt event for traces with accurate end points
===============
*/
static void BloodSpurt( gentity_t *attacker, gentity_t *victim, trace_t *tr )
{
	gentity_t *tent;

	if ( !attacker->client )
	{
		return;
	}

	if ( victim->health <= 0 )
	{
		return;
	}

	tent = G_NewTempEntity( tr->endpos, EV_MISSILE_HIT );
	tent->s.otherEntityNum = victim->s.number;
	tent->s.eventParm = DirToByte( tr->plane.normal );
	tent->s.weapon = attacker->s.weapon;
	tent->s.generic1 = attacker->s.generic1; // weaponMode
}
示例#15
0
static void SendMeleeHitEvent( gentity_t *attacker, gentity_t *target, trace_t *tr )
{
	gentity_t *event;
	vec3_t    normal, origin;
	float     mag, radius;

	if ( !attacker->client )
	{
		return;
	}

	if ( target->health <= 0 )
	{
		return;
	}

	if ( tr )
	{
		VectorSubtract( tr->endpos, target->s.origin, normal );
	}
	else
	{
		VectorSubtract( attacker->client->ps.origin, target->s.origin, normal );
	}

	// Normalize the horizontal components of the vector difference to the "radius" of the bounding box
	mag = sqrt( normal[ 0 ] * normal[ 0 ] + normal[ 1 ] * normal[ 1 ] );
	radius = target->r.maxs[ 0 ] * 1.21f;

	if ( mag > radius )
	{
		normal[ 0 ] = normal[ 0 ] / mag * radius;
		normal[ 1 ] = normal[ 1 ] / mag * radius;
	}

	// Clamp origin to be within bounding box vertically
	if ( normal[ 2 ] > target->r.maxs[ 2 ] )
	{
		normal[ 2 ] = target->r.maxs[ 2 ];
	}

	if ( normal[ 2 ] < target->r.mins[ 2 ] )
	{
		normal[ 2 ] = target->r.mins[ 2 ];
	}

	VectorAdd( target->s.origin, normal, origin );
	VectorNegate( normal, normal );
	VectorNormalize( normal );

	event = G_NewTempEntity( origin, EV_WEAPON_HIT_ENTITY );

	// normal
	event->s.eventParm = DirToByte( normal );

	// victim
	event->s.otherEntityNum = target->s.number;

	// attacker
	event->s.otherEntityNum2 = attacker->s.number;

	// weapon
	event->s.weapon = attacker->s.weapon;

	// weapon mode
	event->s.generic1 = attacker->s.generic1;
}
示例#16
0
/**
 * Awards momentum to a team.
 *
 * Will notify the client hwo earned it if given, otherwise the whole team, with
 *an event.
 */
static float AddMomentum(momentum_t type, team_t team, float amount, gentity_t* source, bool skipChangeHook) {
    gentity_t* event = nullptr;
    gclient_t* client;
    char* clientName;

    if (team <= TEAM_NONE || team >= NUM_TEAMS) {
        return 0.0f;
    }

    // apply modifier
    amount *= MomentumMod(type);

    // limit a team's total
    if (level.team[team].momentum + amount > MOMENTUM_MAX) {
        amount = MOMENTUM_MAX - level.team[team].momentum;
    }

    if (amount != 0.0f) {
        // add momentum to team
        level.team[team].momentum += amount;

        // run change hook if requested
        if (!skipChangeHook) {
            MomentumChanged();
        }

        // notify source
        if (source) {
            client = source->client;

            if (client && client->pers.team == team) {
                event = G_NewTempEntity(client->ps.origin, EV_MOMENTUM);
                event->r.svFlags = SVF_SINGLECLIENT;
                event->r.singleClient = client->ps.clientNum;
            }
        } else {
            event = G_NewTempEntity(vec3_origin, EV_MOMENTUM);
            event->r.svFlags = (SVF_BROADCAST | SVF_CLIENTMASK);
            G_TeamToClientmask(team, &(event->r.loMask), &(event->r.hiMask));
        }
        if (event) {
            // TODO: Use more bits for momentum value
            event->s.eventParm = 0;
            event->s.otherEntityNum = 0;
            event->s.otherEntityNum2 = (int) (fabs(amount) * 10.0f + 0.5f);
            event->s.groundEntityNum = amount < 0.0f ? true : false;
        }

        // notify legacy stage sensors
        NotifyLegacyStageSensors(team, amount);
    }

    if (g_debugMomentum.integer > 0) {
        if (source && source->client) {
            clientName = source->client->pers.netname;
        } else {
            clientName = "no source";
        }

        Com_Printf("Momentum: %.2f to %s (%s by %s for %s)\n", amount, BG_TeamNamePlural(team), amount < 0.0f ? "lost" : "earned", clientName, MomentumTypeToReason(type));
    }

    return amount;
}
示例#17
0
/*
==================
player_die
==================
*/
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int meansOfDeath )
{
	gentity_t *ent;
	int       anim;
	int       killer;
	int       i;
	const char *killerName, *obit;

	if ( self->client->ps.pm_type == PM_DEAD )
	{
		return;
	}

	if ( level.intermissiontime )
	{
		return;
	}

	self->client->ps.pm_type = PM_DEAD;
	self->suicideTime = 0;

	if ( attacker )
	{
		killer = attacker->s.number;

		if ( attacker->client )
		{
			killerName = attacker->client->pers.netname;
		}
		else
		{
			killerName = "<world>";
		}
	}
	else
	{
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if ( meansOfDeath < 0 || meansOfDeath >= ARRAY_LEN( modNames ) )
	{
		// fall back on the number
		obit = va( "%d", meansOfDeath );
	}
	else
	{
		obit = modNames[ meansOfDeath ];
	}

	G_LogPrintf( "Die: %d %d %s: %s" S_COLOR_WHITE " killed %s\n",
	             killer,
	             ( int )( self - g_entities ),
	             obit,
	             killerName,
	             self->client->pers.netname );

	// deactivate all upgrades
	for ( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
	{
		BG_DeactivateUpgrade( i, self->client->ps.stats );
	}

	// broadcast the death event to everyone
	ent = G_NewTempEntity( self->r.currentOrigin, EV_OBITUARY );
	ent->s.eventParm = meansOfDeath;
	ent->s.otherEntityNum = self->s.number;
	ent->s.otherEntityNum2 = killer;
	ent->r.svFlags = SVF_BROADCAST; // send to everyone

	if ( attacker && attacker->client )
	{
		if ( ( attacker == self || OnSameTeam( self, attacker ) ) )
		{
			//punish team kills and suicides
			if ( attacker->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS )
			{
				G_AddCreditToClient( attacker->client, -ALIEN_TK_SUICIDE_PENALTY, qtrue );
				G_AddCreditsToScore( attacker, -ALIEN_TK_SUICIDE_PENALTY );
			}
			else if ( attacker->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS )
			{
				G_AddCreditToClient( attacker->client, -HUMAN_TK_SUICIDE_PENALTY, qtrue );
				G_AddCreditsToScore( attacker, -HUMAN_TK_SUICIDE_PENALTY );
			}
		}
		else if ( g_showKillerHP.integer )
		{
			trap_SendServerCommand( self - g_entities, va( "print_tr %s %s %3i", QQ( N_("Your killer, $1$^7, had $2$ HP.\n") ),
			                        Quote( killerName ),
			                        attacker->health ) );
		}
	}
	else if ( attacker->s.eType != ET_BUILDABLE )
	{
		if ( self->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS )
		{
			G_AddCreditsToScore( self, -ALIEN_TK_SUICIDE_PENALTY );
		}
		else if ( self->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS )
		{
			G_AddCreditsToScore( self, -HUMAN_TK_SUICIDE_PENALTY );
		}
	}

	// give credits for killing this player
	G_RewardAttackers( self );

	ScoreboardMessage( self );  // show scores

	// send updated scores to any clients that are following this one,
	// or they would get stale scoreboards
	for ( i = 0; i < level.maxclients; i++ )
	{
		gclient_t *client;

		client = &level.clients[ i ];

		if ( client->pers.connected != CON_CONNECTED )
		{
			continue;
		}

		if ( client->sess.spectatorState == SPECTATOR_NOT )
		{
			continue;
		}

		if ( client->sess.spectatorClient == self->s.number )
		{
			ScoreboardMessage( g_entities + i );
		}
	}

	VectorCopy( self->s.origin, self->client->pers.lastDeathLocation );

	self->takedamage = qfalse; // can still be gibbed

	self->s.weapon = WP_NONE;
	if ( self->client->noclip )
	{
		self->client->cliprcontents = CONTENTS_CORPSE;
	}
	else
	{
		self->r.contents = CONTENTS_CORPSE;
	}

	self->s.angles[ PITCH ] = 0;
	self->s.angles[ ROLL ] = 0;
	self->s.angles[ YAW ] = self->s.apos.trBase[ YAW ];
	LookAtKiller( self, inflictor, attacker );

	VectorCopy( self->s.angles, self->client->ps.viewangles );

	self->s.loopSound = 0;

	self->r.maxs[ 2 ] = -8;

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	self->client->respawnTime = level.time + 1700;

	// clear misc
	memset( self->client->ps.misc, 0, sizeof( self->client->ps.misc ) );

	{
		static int i;

		if ( !( self->client->ps.persistant[ PERS_STATE ] & PS_NONSEGMODEL ) )
		{
			switch ( i )
			{
				case 0:
					anim = BOTH_DEATH1;
					break;

				case 1:
					anim = BOTH_DEATH2;
					break;

				case 2:
				default:
					anim = BOTH_DEATH3;
					break;
			}
		}
		else
		{
			switch ( i )
			{
				case 0:
					anim = NSPA_DEATH1;
					break;

				case 1:
					anim = NSPA_DEATH2;
					break;

				case 2:
				default:
					anim = NSPA_DEATH3;
					break;
			}
		}

		self->client->ps.legsAnim =
		  ( ( self->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;

		if ( !( self->client->ps.persistant[ PERS_STATE ] & PS_NONSEGMODEL ) )
		{
			self->client->ps.torsoAnim =
			  ( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
		}

		// use own entityid if killed by non-client to prevent uint8_t overflow
		G_AddEvent( self, EV_DEATH1 + i,
		            ( killer < MAX_CLIENTS ) ? killer : self - g_entities );

		// globally cycle through the different death animations
		i = ( i + 1 ) % 3;
	}

	trap_LinkEntity( self );

	self->client->pers.infoChangeTime = level.time;
}
示例#18
0
void ReactorComponent::CreateTeslaTrail(Entity& target) {
	gentity_t* trail = G_NewTempEntity(entity.oldEnt->s.origin, EV_TESLATRAIL);
	trail->s.generic1  = entity.oldEnt->s.number; // Source.
	trail->s.clientNum = target.oldEnt->s.number; // Destination.
}