Пример #1
0
void weapon_supershotgun_fire (gentity_t *ent) {
	gentity_t		*tent;

	// send shotgun blast
	tent = G_TempEntity( g_muzzle, EV_SHOTGUN );
	VectorScale( forward, 4096, tent->s.origin2 );
	SnapVector( tent->s.origin2 );
	tent->s.eventParm = rand() & 255;		// seed for spread pattern
	tent->s.otherEntityNum = ent->s.number;

	ShotgunPattern( tent->s.origin, tent->s.origin2, tent->s.eventParm, ent );
}
Пример #2
0
/*
===============
CalcMuzzlePoint

set muzzle location relative to pivoting eye
===============
*/
void CalcMuzzlePoint ( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint ) {

	/* LQ3A */
	UNREFERENCED_PARAMETER(up);
	UNREFERENCED_PARAMETER(right);

	VectorCopy( ent->s.pos.trBase, muzzlePoint );
	muzzlePoint[2] += ent->client->ps.viewheight;
	VectorMA( muzzlePoint, 14, forward, muzzlePoint );
	// snap to integer coordinates for more efficient network bandwidth usage
	SnapVector( muzzlePoint );
}
/*
=================
launch_grenade

=================
*/
gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir )
{
  gentity_t *bolt;

  VectorNormalize( dir );

  bolt = G_Spawn( );
  bolt->classname = "grenade";
  bolt->nextthink = level.time + 5000;
  bolt->think = G_ExplodeMissile;
  bolt->s.eType = ET_MISSILE;
  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
  bolt->s.weapon = WP_GRENADE;
  bolt->s.eFlags = EF_BOUNCE_HALF;
  bolt->s.generic1 = WPM_PRIMARY; //weaponMode
  bolt->r.ownerNum = self->s.number;
  bolt->parent = self;
	if ( self->client->pers.classSelection != PCL_ALIEN_LEVEL4 )
	{
		bolt->damage = GRENADE_DAMAGE;
		bolt->splashDamage = GRENADE_DAMAGE;
		bolt->splashRadius = GRENADE_RANGE;
	}
	else
	{
		bolt->damage = 300;
		bolt->splashDamage = 500;
		bolt->splashRadius = 975;
	}
  bolt->methodOfDeath = MOD_GRENADE;
  bolt->splashMethodOfDeath = MOD_GRENADE;
  bolt->clipmask = MASK_SHOT;
  bolt->target_ent = NULL;
  bolt->r.mins[ 0 ] = bolt->r.mins[ 1 ] = bolt->r.mins[ 2 ] = -3.0f;
  bolt->r.maxs[ 0 ] = bolt->r.maxs[ 1 ] = bolt->r.maxs[ 2 ] = 3.0f;
  bolt->s.time = level.time;

  bolt->s.pos.trType = TR_GRAVITY;
  	if ( self->client->pers.classSelection == PCL_ALIEN_LEVEL4 )
	{
		bolt->s.pos.trType = TR_LINEAR_STOP;
		bolt->s.weapon = WP_LOCKBLOB_LAUNCHER;
	}
  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit on the very first frame
  VectorCopy( start, bolt->s.pos.trBase );
  VectorScale( dir, GRENADE_SPEED, bolt->s.pos.trDelta );
  SnapVector( bolt->s.pos.trDelta );      // save net bandwidth

  VectorCopy( start, bolt->r.currentOrigin );

  return bolt;
}
Пример #4
0
void TieBomberThink( gentity_t *self )
{
	// NOTE: Lerp2Angles will think this thinkfunc if the model is a misc_model_breakable. Watchout
	// for that in a script (try to just use ROFF's?).

	// Stop thinking, you're dead.
	if ( self->health <= 0 )
	{
		return;
	}

	// Needed every think...
	self->nextthink = level.time + FRAMETIME;

	gentity_t *player = &g_entities[0];
	vec3_t	playerDir;
	float	playerDist;
	
	//use player eyepoint
	VectorSubtract( player->currentOrigin, self->currentOrigin, playerDir );
	playerDist = VectorNormalize( playerDir );

	// Time to attack?
	if ( player->health > 0 && playerDist < MIN_PLAYER_DIST && self->attackDebounceTime < level.time )  
	{
		// Doesn't matter what model gets loaded here, as long as it exists.
		// It's only used as a point on to which the falling effect for the bomb
		// can be attached to (kinda inefficient, I know).
		char name1[200] = "models/players/gonk/model.glm";
		gentity_t *bomb = G_CreateObject( self, self->s.pos.trBase, self->s.apos.trBase, 0, 0, TR_GRAVITY, 0 );
		bomb->s.modelindex = G_ModelIndex( name1 );
		gi.G2API_InitGhoul2Model( bomb->ghoul2, name1, bomb->s.modelindex, NULL_HANDLE, NULL_HANDLE, 0, 0);
		bomb->s.radius = 50;
		bomb->s.eFlags |= EF_NODRAW;

		// Make the bombs go forward in the bombers direction a little.
		vec3_t	fwd, rt;
		AngleVectors( self->currentAngles, fwd, rt, NULL );
		rt[2] -= 0.5f;
		VectorMA( bomb->s.pos.trBase, -30.0, rt, bomb->s.pos.trBase );
		VectorScale( fwd, 300, bomb->s.pos.trDelta );
		SnapVector( bomb->s.pos.trDelta );		// save net bandwidth

		// Start the effect.
		G_PlayEffect( G_EffectIndex( "ships/tiebomber_bomb_falling" ), bomb->playerModel, gi.G2API_AddBolt( &bomb->ghoul2[0], "model_root" ), bomb->s.number, bomb->currentOrigin, 1000, qtrue );

		// Set the tie bomb to have a touch function, so when it hits the ground (or whatever), there's a nice 'boom'.
		bomb->e_TouchFunc = touchF_TouchTieBomb;

		self->attackDebounceTime = level.time + 1000;
	}
}
Пример #5
0
/*
=================
fire_grapple
=================
*/
gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir) {
	gentity_t	*hook;
//unlagged - grapple
	int hooktime;
//unlagged - grapple

	VectorNormalize (dir);

	hook = G_Spawn();
	hook->classname = "hook";
	hook->nextthink = level.time + 10000;
	hook->think = Weapon_HookFree;
	hook->s.eType = ET_MISSILE;
	hook->r.svFlags = SVF_USE_CURRENT_ORIGIN;
	hook->s.weapon = WP_GRAPPLING_HOOK;
	hook->r.ownerNum = self->s.number;
	hook->methodOfDeath = MOD_GRAPPLE;
	hook->clipmask = MASK_SHOT;
	hook->parent = self;
	hook->target_ent = NULL;

//unlagged - grapple
	// we might want this later
	hook->s.otherEntityNum = self->s.number;

	// setting the projectile base time back makes the hook's first
	// step larger

	if ( self->client ) {
		hooktime = self->client->pers.cmd.serverTime + 50;
	}
	else {
		hooktime = level.time - MISSILE_PRESTEP_TIME;
	}

	hook->s.pos.trTime = hooktime;
//unlagged - grapple

	hook->s.pos.trType = TR_LINEAR;
//unlagged - grapple
	//hook->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;		// move a bit on the very first frame
//unlagged - grapple
	hook->s.otherEntityNum = self->s.number; // use to match beam in client
	VectorCopy( start, hook->s.pos.trBase );
	VectorScale( dir, 800, hook->s.pos.trDelta );
	SnapVector( hook->s.pos.trDelta );			// save net bandwidth
	VectorCopy (start, hook->r.currentOrigin);

	self->client->hook = hook;

	return hook;
}
Пример #6
0
//----------------------------------------------------------------
static void turret_fire ( gentity_t *ent, vec3_t start, vec3_t dir )
//----------------------------------------------------------------
{
	vec3_t		org;
	gentity_t	*bolt;

	if ( (trap_PointContents( start, ent->s.number )&MASK_SHOT) )
	{
		return;
	}

	VectorMA( start, -START_DIS, dir, org ); // dumb....
	G_PlayEffectID( ent->genericValue13, org, dir );

	bolt = G_Spawn();
	
	//use a custom shot effect
	bolt->s.otherEntityNum2 = ent->genericValue14;
	//use a custom impact effect
	bolt->s.emplacedOwner = ent->genericValue15;

	bolt->classname = "turret_proj";
	bolt->nextthink = level.time + 10000;
	bolt->think = G_FreeEntity;
	bolt->s.eType = ET_MISSILE;
	bolt->s.weapon = WP_EMPLACED_GUN;
	bolt->r.ownerNum = ent->s.number;
	bolt->damage = ent->damage;
	bolt->alliedTeam = ent->alliedTeam;
	bolt->teamnodmg = ent->teamnodmg;
	//bolt->dflags = DAMAGE_NO_KNOCKBACK;// | DAMAGE_HEAVY_WEAP_CLASS;		// Don't push them around, or else we are constantly re-aiming
	bolt->splashDamage = ent->damage;
	bolt->splashRadius = 100;
	bolt->methodOfDeath = MOD_TARGET_LASER;
	//[BugFix16]
	bolt->splashMethodOfDeath = MOD_TARGET_LASER;
	//[/BugFix16]
	bolt->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
	//bolt->trigger_formation = qfalse;		// don't draw tail on first frame	

	VectorSet( bolt->r.maxs, 1.5, 1.5, 1.5 );
	VectorScale( bolt->r.maxs, -1, bolt->r.mins );
	bolt->s.pos.trType = TR_LINEAR;
	bolt->s.pos.trTime = level.time;
	VectorCopy( start, bolt->s.pos.trBase );
	VectorScale( dir, ent->mass, bolt->s.pos.trDelta );
	SnapVector( bolt->s.pos.trDelta );		// save net bandwidth
	VectorCopy( start, bolt->r.currentOrigin);

	bolt->parent = ent;
}
Пример #7
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();
}
Пример #8
0
/*
=================
fire_rocket
=================
*/
gentity_t *fire_rocket( gentity_t *self, vec3_t start, vec3_t dir ) {
	gentity_t   *bolt;

	VectorNormalize( dir );

	bolt = G_Spawn();
	bolt->classname = const_cast<char*>("rocket");
	bolt->nextthink = level.time + 20000;   // push it out a little
	bolt->think = G_ExplodeMissile;
	bolt->s.eType = ET_MISSILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN | SVF_BROADCAST;

	//DHM - Nerve :: Use the correct weapon in multiplayer
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		bolt->s.weapon = WP_ROCKET_LAUNCHER;
	} else {
		bolt->s.weapon = self->s.weapon;
	}

	bolt->r.ownerNum = self->s.number;
	bolt->parent = self;
	bolt->damage = G_GetWeaponDamage( WP_ROCKET_LAUNCHER ); // JPW NERVE
	bolt->splashDamage = G_GetWeaponDamage( WP_ROCKET_LAUNCHER ); // JPW NERVE
// JPW NERVE
	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		bolt->splashRadius = G_GetWeaponDamage( WP_ROCKET_LAUNCHER );
	} else {
		bolt->splashRadius = 120;
	}
// jpw
	bolt->methodOfDeath = MOD_ROCKET;
	bolt->splashMethodOfDeath = MOD_ROCKET_SPLASH;
//	bolt->clipmask = MASK_SHOT;
	bolt->clipmask = MASK_MISSILESHOT;

	bolt->s.pos.trType = TR_LINEAR;
	bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;     // move a bit on the very first frame
	VectorCopy( start, bolt->s.pos.trBase );
// JPW NERVE
	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		VectorScale( dir,2500,bolt->s.pos.trDelta );
	} else {
		VectorScale( dir, 900, bolt->s.pos.trDelta );
	}
// jpw
	SnapVector( bolt->s.pos.trDelta );          // save net bandwidth
	VectorCopy( start, bolt->r.currentOrigin );

	return bolt;
}
Пример #9
0
void shotgunFire( gentity_t *ent )
{
    gentity_t    *tent;

    // send shotgun blast
    tent = G_TempEntity( muzzle, EV_SHOTGUN );
    VectorScale( forward, 4096, tent->s.origin2 );
    SnapVector( tent->s.origin2 );
    tent->s.eventParm = rand() & 255;    // seed for spread pattern
    tent->s.otherEntityNum = ent->s.number;
    G_UnlaggedOn( muzzle, 8192 * 16 );
    ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent );
    G_UnlaggedOff();
}
Пример #10
0
static int _vec3_snap(lua_State *L)
{
	luavec3_t a;

	_et_gentity_setluavec3(L, &a);
	lua_pop(L, 1);

	SnapVector(a);

	_et_gentity_getluavec3(L, a);
	G_LuaSetVec3Class(L);

	return 1;
}
Пример #11
0
gentity_t *
plant_mine(gentity_t *self, vec3_t start, vec3_t dir)
{
  gentity_t *bolt;

  VectorNormalize(dir);

  bolt = G_Spawn();
  bolt->classname = "mine";
  bolt->nextthink = level.time + 2000;
  bolt->think = G_minethink;
  bolt->s.eType = ET_MISSILE;
  bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
  bolt->s.weapon = WP_MINE;
  bolt->s.eFlags = EF_BOUNCE_HALF;
  bolt->s.generic1 = WPM_PRIMARY; //weaponMode
  bolt->r.ownerNum = self->s.number;
  bolt->parent = self;
 if(g_survival.integer)
 {
	 bolt->damage = MINE_DAMAGE;
	 bolt->splashDamage = MINE_DAMAGE;
 } else {
	 bolt->damage = (1.25 * MINE_DAMAGE);
	 bolt->splashDamage = (1.25 * MINE_DAMAGE);
 }
  bolt->splashRadius = MINE_RANGE;
  bolt->methodOfDeath = MOD_MINE;
  bolt->splashMethodOfDeath = MOD_MINE;
  bolt->clipmask = MASK_DEADSOLID;
  bolt->target_ent = NULL;
  bolt->r.mins[0] = bolt->r.mins[1] = -5.0f;
  bolt->r.mins[2] = 0.0f;
  bolt->r.maxs[0] = bolt->r.maxs[1] = 5.0f;
  bolt->r.maxs[2] = 2.0f;
  bolt->s.time = level.time;

  bolt->biteam = bolt->s.modelindex2 = BIT_HUMANS;
  bolt->use = G_itemUse;

  bolt->s.pos.trType = TR_GRAVITY;
  bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
  VectorCopy( start, bolt->s.pos.trBase );
  VectorScale( dir, GRENADE_SPEED/3, bolt->s.pos.trDelta );
  SnapVector( bolt->s.pos.trDelta ); // save net bandwidth

  VectorCopy( start, bolt->r.currentOrigin );
  return bolt;
}
Пример #12
0
gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up ) {
	gentity_t   *bolt;
	vec3_t dir;
	vec3_t end;
	float r, u, scale;

	bolt = G_Spawn();
	bolt->classname = const_cast<char*>("nail");
	bolt->nextthink = level.time + 10000;
	bolt->think = G_ExplodeMissile;
	bolt->s.eType = ET_MISSILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
//	bolt->s.weapon = WP_NAILGUN;
	bolt->s.weapon = WP_VENOM_FULL;
	bolt->r.ownerNum = self->s.number;
	bolt->parent = self;
	bolt->damage = G_GetWeaponDamage( WP_VENOM_FULL );
//	bolt->methodOfDeath = MOD_NAIL;
	bolt->methodOfDeath = MOD_VENOM_FULL;
	bolt->clipmask = MASK_SHOT;
	bolt->target_ent = NULL;

	bolt->s.pos.trType = TR_LINEAR;
	bolt->s.pos.trTime = level.time;
	VectorCopy( start, bolt->s.pos.trBase );

	r = random() * M_PI * 2.0f;
	u = c::sin( r ) * crandom() * NAILGUN_SPREAD * 16;
	r = c::cos( r ) * crandom() * NAILGUN_SPREAD * 16;
	VectorMA( start, 8192 * 16, forward, end );
	VectorMA( end, r, right, end );
	VectorMA( end, u, up, end );
	VectorSubtract( end, start, dir );
	VectorNormalize( dir );

// JPW NERVE
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		scale = 555 + random() * 1800;
	} else {
		scale = 1200 + random() * 2500;
	}
// jpw
	VectorScale( dir, scale, bolt->s.pos.trDelta );
	SnapVector( bolt->s.pos.trDelta );

	VectorCopy( start, bolt->r.currentOrigin );

	return bolt;
}
Пример #13
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();
}
Пример #14
0
//----------------------------------------------------------------
static void turret_fire ( gentity_t *ent, vec3_t start, vec3_t dir )
//----------------------------------------------------------------
{
	vec3_t		org;
	gentity_t	*bolt;

	if ( (trap_PointContents( start, ent->s.number )&MASK_SHOT) )
	{
		return;
	}

	VectorMA( start, -START_DIS, dir, org ); // dumb....
	G_PlayEffectID( ent->genericValue13, org, dir );

	bolt = G_Spawn();
	
	//use a custom shot effect
	bolt->s.otherEntityNum2 = ent->genericValue14;
	//use a custom impact effect
	bolt->s.emplacedOwner = ent->genericValue15;

	bolt->classname = "turret_proj";
	bolt->nextthink = level.time + 10000;
	bolt->think = G_FreeEntity;
	bolt->s.eType = ET_MISSILE;
	bolt->s.weapon = WP_EMPLACED_GUN;
	bolt->r.ownerNum = ent->s.number;
	bolt->damage = ent->damage;
	bolt->alliedTeam = ent->alliedTeam;
	bolt->teamnodmg = ent->teamnodmg;
	bolt->splashDamage = ent->damage;
	bolt->splashRadius = 100;
	bolt->methodOfDeath = MOD_TARGET_LASER;
	bolt->splashMethodOfDeath = MOD_TARGET_LASER;
	bolt->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;

	VectorSet( bolt->r.maxs, 1.5, 1.5, 1.5 );
	VectorScale( bolt->r.maxs, -1, bolt->r.mins );
	bolt->s.pos.trType = TR_LINEAR;
	bolt->s.pos.trTime = level.time;
	VectorCopy( start, bolt->s.pos.trBase );
	VectorScale( dir, ent->mass, bolt->s.pos.trDelta );
	SnapVector( bolt->s.pos.trDelta );		// save net bandwidth
	VectorCopy( start, bolt->r.currentOrigin);

	bolt->parent = ent;
}
Пример #15
0
static gentity_t *FireLcannonHelper( gentity_t *self, vec3_t start, vec3_t dir,
                                     int damage, int radius, int speed )
{
	// TODO: Tidy up this and lcannonFire

	gentity_t *m;
	int       nextthink;
	float     charge;

	// explode in front of player when overcharged
	if ( damage == LCANNON_DAMAGE )
	{
		nextthink = level.time;
	}
	else
	{
		nextthink = level.time + 10000;
	}

	if ( self->s.generic1 == WPM_PRIMARY )
	{
		m = G_SpawnMissile( MIS_LCANNON, self, start, dir, NULL, G_ExplodeMissile, nextthink );

		// some values are set in the code
		m->damage       = damage;
		m->splashDamage = damage / 2;
		m->splashRadius = radius;
		VectorScale( dir, speed, m->s.pos.trDelta );
		SnapVector( m->s.pos.trDelta ); // save net bandwidth

		// pass the missile charge through
		charge = ( float )( damage - LCANNON_SECONDARY_DAMAGE ) / LCANNON_DAMAGE;

		m->s.torsoAnim = charge * 255;

		if ( m->s.torsoAnim < 0 )
		{
			m->s.torsoAnim = 0;
		}
	}
	else
	{
		m = G_SpawnMissile( MIS_LCANNON2, self, start, dir, NULL, G_ExplodeMissile, nextthink );
	}

	return m;
}
Пример #16
0
gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up ) {
	gentity_t	*bolt;
	vec3_t		dir;
	vec3_t		end;
	float		r, u, scale;

	bolt = G_Spawn();
	bolt->classname = "nail";
	bolt->nextthink = level.time + 10000;
	bolt->think = G_ExplodeMissile;
	bolt->s.eType = ET_MISSILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
	bolt->s.weapon = WP_NAILGUN;
	bolt->r.ownerNum = self->s.number;
	bolt->parent = self;
	bolt->damage = 20;
	bolt->methodOfDeath = MOD_NAIL;
	bolt->clipmask = MASK_SHOT;
	bolt->target_ent = NULL;

	bolt->s.pos.trType = TR_LINEAR;
	bolt->s.pos.trTime = level.time;
	VectorCopy( start, bolt->s.pos.trBase );

	r = random() * M_PI * 2.0f;
	u = sin(r) * crandom() * NAILGUN_SPREAD * 16;
	r = cos(r) * crandom() * NAILGUN_SPREAD * 16;
	VectorMA( start, 8192 * 16, forward, end);
	VectorMA (end, r, right, end);
	VectorMA (end, u, up, end);
	VectorSubtract( end, start, dir );
	VectorNormalize( dir );

	scale = 555 + random() * 1800;
	VectorScale( dir, scale, bolt->s.pos.trDelta );
	SnapVector( bolt->s.pos.trDelta );

	VectorCopy( start, bolt->r.currentOrigin );

	if ( self->player ) {
		bolt->s.team = self->player->sess.sessionTeam;
	} else {
		bolt->s.team = TEAM_FREE;
	}

	return bolt;
}	
Пример #17
0
/*
=================
fire_railsphere
=================
*/
gentity_t      *fire_railsphere(gentity_t * self, vec3_t start, vec3_t dir)
{
	gentity_t      *bolt;
	vec3_t          mins = { -16, -16, -16 };
	vec3_t          maxs = { 16, 16, 16 };

	VectorNormalize(dir);

	bolt = G_Spawn();
	bolt->classname = "rocket";
	bolt->nextthink = level.time + 15000;
//	bolt->think = RailSphereDamage;
//	bolt->think = G_ExplodeMissile;
	bolt->think = G_FreeEntity;	// FIXME
	bolt->s.eType = ET_PROJECTILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
	bolt->s.weapon = WP_RAILGUN;
	bolt->r.ownerNum = self->s.number;
	bolt->parent = self;
	bolt->damage = 75;
	bolt->splashDamage = 50;
	bolt->splashRadius = 120;
	bolt->methodOfDeath = MOD_RAILGUN_SPLASH;
	bolt->splashMethodOfDeath = MOD_RAILGUN_SPLASH;
	bolt->clipmask = MASK_SHOT;
	bolt->target_ent = NULL;

	// make the sphere shootable
	bolt->r.contents = CONTENTS_SHOOTABLE;
	VectorCopy(mins, bolt->r.mins);
	VectorCopy(maxs, bolt->r.maxs);
	bolt->takedamage = qtrue;
	bolt->health = 25;
	bolt->die = RailSphere_Die;

	bolt->s.pos.trType = TR_LINEAR;
	VectorScale(dir, 400, bolt->s.pos.trDelta);

	bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;	// move a bit on the very first frame
	VectorCopy(start, bolt->s.pos.trBase);

	SnapVector(bolt->s.pos.trDelta);	// save net bandwidth
	VectorCopy(start, bolt->r.currentOrigin);

	return bolt;
}
Пример #18
0
void DropPortalSource(gentity_t * player)
{
	gentity_t      *ent;
	gentity_t      *destination;
	vec3_t          snapped;

	// create the portal source
	ent = G_Spawn();
	ent->s.modelindex = G_ModelIndex("models/powerups/teleporter/tele_enter.md3");

	VectorCopy(player->s.pos.trBase, snapped);
	SnapVector(snapped);
	G_SetOrigin(ent, snapped);
	VectorCopy(player->r.mins, ent->r.mins);
	VectorCopy(player->r.maxs, ent->r.maxs);

	ent->classname = "hi_portal source";
	ent->s.pos.trType = TR_STATIONARY;

	ent->r.contents = CONTENTS_CORPSE | CONTENTS_TRIGGER;
	ent->takedamage = qtrue;
	ent->health = 200;
	ent->die = PortalDie;

	trap_LinkEntity(ent);

	ent->count = player->client->portalID;
	player->client->portalID = 0;

//  ent->spawnflags = player->client->ps.persistant[PERS_TEAM];

	ent->nextthink = level.time + 1000;
	ent->think = PortalEnable;

	// find the destination
	destination = NULL;
	while((destination = G_Find(destination, FOFS(classname), "hi_portal destination")) != NULL)
	{
		if(destination->count == ent->count)
		{
			VectorCopy(destination->s.pos.trBase, ent->pos1);
			break;
		}
	}

}
Пример #19
0
gentity_t      *fire_gravnail(gentity_t * self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up)
{
	gentity_t      *bolt;
	vec3_t          dir;
	vec3_t          end;
	float           r, u, scale;

	bolt = G_Spawn();
	bolt->classname = "nail";
	bolt->nextthink = level.time + 500;
	bolt->think = G_FreeEntity;
	bolt->s.eType = ET_PROJECTILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
	bolt->s.weapon = WP_FLAK_CANNON;
//	bolt->s.eFlags = EF_BOUNCE_HALF;
	bolt->r.ownerNum = self->s.number;
	bolt->parent = self;
	bolt->damage = 20;
	bolt->methodOfDeath = MOD_NAIL;
	bolt->clipmask = MASK_SHOT;
	bolt->target_ent = NULL;

//	bolt->s.pos.trType = TR_GRAVITY;
	bolt->s.pos.trType = TR_LINEAR;
	bolt->s.pos.trAcceleration = g_gravity.value;
	bolt->s.pos.trTime = level.time;
	VectorCopy(start, bolt->s.pos.trBase);

	r = random() * M_PI * 2.0f;
	u = sin(r) * crandom() * NAILGUN_SPREAD * 16;
	r = cos(r) * crandom() * NAILGUN_SPREAD * 16;
	VectorMA(start, 8192 * 16, forward, end);
	VectorMA(end, r, right, end);
	VectorMA(end, u, up, end);
	VectorSubtract(end, start, dir);
	VectorNormalize(dir);

	scale = 555 + random() * 1800;
	VectorScale(dir, scale, bolt->s.pos.trDelta);
	SnapVector(bolt->s.pos.trDelta);

	VectorCopy(start, bolt->r.currentOrigin);

	return bolt;
}
Пример #20
0
/*
================
G_Bounce

================
*/
static void G_Bounce( gentity_t *ent, trace_t *trace )
{
  vec3_t    velocity;
  float     dot;
  int       hitTime;
  float     minNormal;
  bool  invert = false;

  // reflect the velocity on the trace plane
  hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction;
  BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity );
  dot = DotProduct( velocity, trace->plane.normal );
  VectorMA( velocity, -2*dot, trace->plane.normal, ent->s.pos.trDelta );

  if( ent->s.eType == ET_BUILDABLE )
  {
    minNormal = BG_FindMinNormalForBuildable( ent->s.modelindex );
    invert = BG_FindInvertNormalForBuildable( ent->s.modelindex );
  }
  else
    minNormal = 0.707f;

  // cut the velocity to keep from bouncing forever
  if( ( trace->plane.normal[ 2 ] >= minNormal ||
      ( invert && trace->plane.normal[ 2 ] <= -minNormal ) ) &&
      trace->entityNum == ENTITYNUM_WORLD )
    VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta );
  else
    VectorScale( ent->s.pos.trDelta, 0.3f, ent->s.pos.trDelta );

  if( VectorLength( ent->s.pos.trDelta ) < 10 )
  {
    VectorMA( trace->endpos, 0.5, trace->plane.normal, trace->endpos ); // make sure it is off ground
    SnapVector( trace->endpos );
    G_SetOrigin( ent, trace->endpos );
    ent->s.groundEntityNum = trace->entityNum;
    VectorCopy( trace->plane.normal, ent->s.origin2 );
    VectorSet( ent->s.pos.trDelta, 0.0f, 0.0f, 0.0f );
    return;
  }

  VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
  VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin);
  ent->s.pos.trTime = level.time;
}
Пример #21
0
static void RocketThink( gentity_t *self )
{
	vec3_t currentDir, targetDir, newDir, rotAxis;
	float  rotAngle;

	if ( level.time > self->timestamp )
	{
		self->think     = G_ExplodeMissile;
		self->nextthink = level.time;

		return;
	}

	self->nextthink = level.time + ROCKET_TURN_PERIOD;

	// Calculate current and target direction.
	VectorNormalize2( self->s.pos.trDelta, currentDir );
	VectorSubtract( self->target->r.currentOrigin, self->r.currentOrigin, targetDir );
	VectorNormalize( targetDir );

	// Don't turn anymore after the target was passed.
	if ( DotProduct( currentDir, targetDir ) < 0 )
	{
		return;
	}

	// Calculate new direction. Use a fixed turning angle.
	CrossProduct( currentDir, targetDir, rotAxis );
	rotAngle = RAD2DEG( acos( DotProduct( currentDir, targetDir ) ) );
	RotatePointAroundVector( newDir, rotAxis, currentDir,
	                         Math::Clamp( rotAngle, -ROCKET_TURN_ANGLE, ROCKET_TURN_ANGLE ) );

	// Check if new direction is safe. Turn anyway if old direction is unsafe, too.
	if ( !G_RocketpodSafeShot( ENTITYNUM_NONE, self->r.currentOrigin, newDir ) &&
	     G_RocketpodSafeShot( ENTITYNUM_NONE, self->r.currentOrigin, currentDir ) )
	{
		return;
	}

	// Update trajectory.
	VectorScale( newDir, BG_Missile( self->s.modelindex )->speed, self->s.pos.trDelta );
	SnapVector( self->s.pos.trDelta );
	VectorCopy( self->r.currentOrigin, self->s.pos.trBase ); // TODO: Snap this, too?
	self->s.pos.trTime = level.time;
}
Пример #22
0
/*
=======================================================================================================================================
G_TempEntity

Spawns an event entity that will be auto-removed. The origin will be snapped to save net bandwidth, so care must be taken if the origin
is right on a surface (snap towards start vector first).
=======================================================================================================================================
*/
gentity_t *G_TempEntity(vec3_t origin, int event) {
	gentity_t *e;
	vec3_t snapped;

	e = G_Spawn();
	e->s.eType = ET_EVENTS + event;
	e->classname = "tempEntity";
	e->eventTime = level.time;
	e->freeAfterEvent = qtrue;

	VectorCopy(origin, snapped);
	SnapVector(snapped); // save network bandwidth
	G_SetOrigin(e, snapped);
	// find cluster for PVS
	trap_LinkEntity(e);

	return e;
}
Пример #23
0
/*
================
Modified by Elder

dropWeapon XRAY FMJ
================
*/
gentity_t *dropWeapon(gentity_t * ent, gitem_t * item, float angle, int xr_flags)
{
	vec3_t velocity;
	vec3_t angles;
	vec3_t origin;

	//int           throwheight;
	vec3_t mins, maxs;
	trace_t tr;

	VectorCopy(ent->s.pos.trBase, origin);
	VectorCopy(ent->s.apos.trBase, angles);
	angles[YAW] += angle;
	angles[PITCH] = -55;	// always at a 55 degree above horizontal angle

	AngleVectors(angles, velocity, NULL, NULL);

	// set aiming directions
	//AngleVectors (ent->client->ps.viewangles, velocity, NULL, NULL);

	//Elder: don't toss from the head, but from the "waist"
	origin[2] += 10;	// (ent->client->ps.viewheight / 2);
	VectorMA(origin, 5, velocity, origin);	// 14 34 10

	// Set temporary bounding box for trace
	VectorSet(mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS);
	VectorSet(maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS);

	// NiceAss: Check if the new location starts in a solid.
	// FIXME: Use trap_point or whatever?
	trap_Trace(&tr, origin, mins, maxs, origin, ent->s.number, MASK_SOLID);
	if (tr.startsolid == qtrue)
		VectorMA(origin, -7, velocity, origin);	// -5 won't work (hint: it should work). Only -7 or less will..

	// snap to integer coordinates for more efficient network bandwidth usage
	SnapVector(origin);

	// less vertical velocity
	//velocity[2] += 0.2f;
	//velocity[2] = 20;
	VectorNormalize(velocity);
	VectorScale(velocity, 5, velocity);
	return LaunchItem(item, origin, velocity, xr_flags);
}
Пример #24
0
/*
============
G_StoreHistory

Keep track of where the client's been
============
*/
void G_StoreHistory( gentity_t *ent ) {
	int		head, frametime;

	frametime = level.time - level.previousTime;

	ent->client->historyHead++;
	if ( ent->client->historyHead >= NUM_CLIENT_HISTORY ) {
		ent->client->historyHead = 0;
	}

	head = ent->client->historyHead;

	// store all the collision-detection info and the time
	VectorCopy( ent->r.mins, ent->client->history[head].mins );
	VectorCopy( ent->r.maxs, ent->client->history[head].maxs );
	VectorCopy( ent->s.pos.trBase, ent->client->history[head].currentOrigin );
	SnapVector( ent->client->history[head].currentOrigin );
	ent->client->history[head].leveltime = level.time;
}
Пример #25
0
/*
=================
fire_prox
=================
*/
gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t dir ) {
	gentity_t	*bolt;

	VectorNormalize (dir);

	bolt = G_Spawn();
	bolt->classname = "prox mine";
	bolt->nextthink = level.time + 3000;
	bolt->think = G_ExplodeMissile;
	bolt->s.eType = ET_MISSILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
	bolt->s.weapon = WP_PROX_LAUNCHER;
	bolt->s.eFlags = 0;
	bolt->r.ownerNum = self->s.number;
//unlagged - projectile nudge
	// we'll need this for nudging projectiles later
	bolt->s.otherEntityNum = self->s.number;
//unlagged - projectile nudge
	bolt->parent = self;
	bolt->damage = 0;
	bolt->splashDamage = 100;
	bolt->splashRadius = 150;
	bolt->methodOfDeath = MOD_PROXIMITY_MINE;
	bolt->splashMethodOfDeath = MOD_PROXIMITY_MINE;
	bolt->clipmask = MASK_SHOT;
	bolt->target_ent = NULL;
	// count is used to check if the prox mine left the player bbox
	// if count == 1 then the prox mine left the player bbox and can attack to it
	bolt->count = 0;

	//FIXME: we prolly wanna abuse another field
	bolt->s.generic1 = self->client->sess.sessionTeam;

	bolt->s.pos.trType = TR_GRAVITY;
	bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;		// move a bit on the very first frame
	VectorCopy( start, bolt->s.pos.trBase );
	VectorScale( dir, 700, bolt->s.pos.trDelta );
	SnapVector( bolt->s.pos.trDelta );			// save net bandwidth

	VectorCopy (start, bolt->r.currentOrigin);

	return bolt;
}
Пример #26
0
/*
================
G_ExplodeMissile

Explode a missile without an impact
================
*/
void G_ExplodeMissile( gentity_t *ent ) {
	vec3_t		dir;
	vec3_t		origin;

	BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
	SnapVector( origin );
	G_SetOrigin( ent, origin );

	// we don't have a valid direction, so just point straight up
	dir[0] = dir[1] = 0;
	dir[2] = 1;

	ent->s.eType = ET_GENERAL;
	G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) );

	ent->freeAfterEvent = qtrue;

	ent->takedamage = qfalse;
	// splash damage
	if ( ent->splashDamage ) {
		//NOTE: vehicle missiles don't have an ent->parent set, so check that here and set it
		if ( ent->s.eType == ET_MISSILE//missile
			&& (ent->s.eFlags&EF_JETPACK_ACTIVE)//vehicle missile
			&& ent->r.ownerNum < MAX_CLIENTS )//valid client owner
		{//set my parent to my owner for purposes of damage credit...
			ent->parent = &g_entities[ent->r.ownerNum];
		}
		if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, 
				ent, ent->splashMethodOfDeath ) ) 
		{
			if (ent->parent)
			{
				g_entities[ent->parent->s.number].client->accuracy_hits++;
			}
			else if (ent->activator)
			{
				g_entities[ent->activator->s.number].client->accuracy_hits++;
			}
		}
	}

	trap_LinkEntity( ent );
}
Пример #27
0
/*
================
DropWeapon
RPG-X
Marcin 03/12/2008
================
*/
gentity_t *DropWeapon( gentity_t *ent, gitem_t *item, float angle, int flags, char *txt ) {
	vec3_t	velocity;
	vec3_t	origin;

	VectorCopy( ent->s.pos.trBase, origin );

	// set aiming directions
	AngleVectors (ent->client->ps.viewangles, velocity, NULL, NULL);

	origin[2] += ent->client->ps.viewheight + 10;
	VectorMA( origin, 14, velocity, origin );
	// snap to integer coordinates for more efficient network bandwidth usage
	SnapVector( origin );

	// extra vertical velocity
	velocity[2] += 0.2;
	VectorNormalize( velocity );
	return LaunchItem( item, ent, origin, velocity, flags, txt );
}
Пример #28
0
/*
================
AHive_ReturnToHive

Adjust the trajectory to point towards the hive
================
*/
void AHive_ReturnToHive( gentity_t *self )
{
    vec3_t  dir;
    trace_t tr;

    if( !self->parent )
    {
        G_Printf( S_COLOR_YELLOW "WARNING: AHive_ReturnToHive called with no self->parent\n" );
        return;
    }

    trap_UnlinkEntity( self->parent );
    trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs,
                self->parent->r.currentOrigin, self->r.ownerNum, self->clipmask );
    trap_LinkEntity( self->parent );

    if( tr.fraction < 1.0f )
    {
        //if can't see hive then disperse
        VectorCopy( self->r.currentOrigin, self->s.pos.trBase );
        self->s.pos.trType = TR_STATIONARY;
        self->s.pos.trTime = level.time;

        self->think = G_ExplodeMissile;
        self->nextthink = level.time + 2000;
        self->parent->active = qfalse; //allow the parent to start again
    }
    else
    {
        VectorSubtract( self->parent->r.currentOrigin, self->r.currentOrigin, dir );
        VectorNormalize( dir );

        //change direction towards the hive
        VectorScale( dir, HIVE_SPEED, self->s.pos.trDelta );
        SnapVector( self->s.pos.trDelta );      // save net bandwidth
        VectorCopy( self->r.currentOrigin, self->s.pos.trBase );
        self->s.pos.trTime = level.time;

        self->think = G_ExplodeMissile;
        self->nextthink = level.time + 15000;
    }
}
Пример #29
0
gentity_t *fire_molotov (gentity_t *self, vec3_t start, vec3_t dir, int speed) {
	gentity_t	*bolt;

	VectorNormalize (dir);

	bolt = G_Spawn();
	bolt->classname = "molotov";

	bolt->s.eType = ET_MISSILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
	bolt->r.svFlags |= SVF_BROADCAST;
	bolt->s.weapon = WP_MOLOTOV;
	bolt->r.ownerNum = self->s.number;
//unlagged - projectile nudge
	// we'll need this for nudging projectiles later
	bolt->s.otherEntityNum = self->s.number;
//unlagged - projectile nudge
	bolt->parent = self;
	bolt->damage = 7;
	bolt->splashDamage = 0;
	bolt->splashRadius = 0;
	bolt->methodOfDeath = MOD_MOLOTOV;
	bolt->splashMethodOfDeath = MOD_MOLOTOV;
	bolt->clipmask = MASK_SHOT;

	bolt->s.pos.trType = TR_GRAVITY;
	bolt->s.pos.trTime = level.time + MISSILE_PRESTEP_TIME;		// move a bit on the very first frame
	VectorCopy( start, bolt->s.pos.trBase );
	VectorScale( dir, speed, bolt->s.pos.trDelta );
	SnapVector( bolt->s.pos.trDelta );			// save net bandwidth

	VectorCopy (start, bolt->r.currentOrigin);

	if(self->client){
		if(self->client->ps.stats[STAT_WP_MODE] < 0)
			bolt->s.apos.trDelta[0] = self->client->ps.stats[STAT_WP_MODE];
		else
			bolt->s.apos.trDelta[0] = 0;
	}

	return bolt;
}
Пример #30
0
/*
==============
fire_mortar
	dir is a non-normalized direction/power vector
==============
*/
gentity_t *fire_mortar( gentity_t *self, vec3_t start, vec3_t dir ) {
	gentity_t   *bolt;

//	VectorNormalize (dir);

	if ( self->spawnflags ) {
		gentity_t   *tent;
		tent = G_TempEntity( self->s.pos.trBase, EV_MORTAREFX );
		tent->s.density = self->spawnflags; // send smoke and muzzle flash flags
		VectorCopy( self->s.pos.trBase, tent->s.origin );
		VectorCopy( self->s.apos.trBase, tent->s.angles );
	}

	bolt = G_Spawn();
	bolt->classname = const_cast<char*>("mortar");
	bolt->nextthink = level.time + 20000;   // push it out a little
	bolt->think = G_ExplodeMissile;
	bolt->s.eType = ET_MISSILE;

	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN | SVF_BROADCAST;   // broadcast sound.  not multiplayer friendly, but for mortars it should be okay
	// bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;

	bolt->s.weapon = WP_MORTAR;
	bolt->r.ownerNum = self->s.number;
	bolt->parent = self;
	bolt->damage = G_GetWeaponDamage( WP_MORTAR ); // JPW NERVE
	bolt->splashDamage = G_GetWeaponDamage( WP_MORTAR ); // JPW NERVE
	bolt->splashRadius = 120;
	bolt->methodOfDeath = MOD_MORTAR;
	bolt->splashMethodOfDeath = MOD_MORTAR_SPLASH;
	bolt->clipmask = MASK_MISSILESHOT;

	bolt->s.pos.trType = TR_GRAVITY;
	bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;     // move a bit on the very first frame
	VectorCopy( start, bolt->s.pos.trBase );
//	VectorScale( dir, 900, bolt->s.pos.trDelta );
	VectorCopy( dir, bolt->s.pos.trDelta );
	SnapVector( bolt->s.pos.trDelta );          // save net bandwidth
	VectorCopy( start, bolt->r.currentOrigin );

	return bolt;
}