MAGSEC4
Created By: Marius
eMail: lordshoel@yahoo.com
Difficulty Scale: Easy


After playing the awesome Perfect Dark on Nintendo 64, I got to thinking that the MagSec4 pistol would be rather cool in a mod. This tutorial is the result of that idea. A powerful pistol doing 45 damage while being inaccurate. This tutorial sees the basic nailgun replaced with the MagSec4. So lets go... First download the zip file Magsec.zip which conatins 3 models to be placed in the Progs folder. Please note that for this tutorial I have used the Colt 45 Mdl from Special Forces mod due to the absence of a good enough model and my crap model making skills. If anyone whats to make some models based on Perfect Dark please, please, please contact me!

Step 1.

Create a new file called Magsec.qc into the file past the following code:

/*
==============================================================================

MAGSEC4 PISTOL WITH BULLET CASE EJECTION

==============================================================================
*/

void(float damage) spawn_touchblood;		//Prototype

//================================
//	CASE EJECTION
//================================
void () case_touch = 
{
   if (other.classname == "door") return ;
  
   sound (self,CHAN_WEAPON,"weapons/tink1.wav",1,ATTN_NORM);
	
};

void (vector org, vector dir) eject_case = 
{
   	local float r;
   	local string temp;
   	r = random();

	newmis = spawn ();
	newmis.owner = self;
   	newmis.movetype = MOVETYPE_BOUNCE;
   	newmis.solid = SOLID_BBOX;
   	newmis.angles = vectoangles (dir);
   	newmis.classname = "Bullet Casing";
   	newmis.touch = case_touch;
      newmis.think = SUB_Remove;
     	newmis.nextthink = (time + 3);
   	setmodel (newmis,"progs/case.mdl");
	setsize (newmis,VEC_ORIGIN,VEC_ORIGIN);
   	setorigin (newmis,org);
   	
	
   	if ((r < 0.100) && (r >= MSG_BROADCAST))  
	{
		newmis.velocity = (((v_forward * 20.000) + (v_right * 60.000)) + (v_up * 80.000));
	}
	if ((r < 0.200) && (r >= 0.100)) 
	{
	      newmis.velocity = (((v_forward * SVC_INTERMISSION) + (v_right * 65.000)) + (v_up * 90.000));
   	}
   	if ((r < 0.300) && (r >= 0.200)) 
	{
	      newmis.velocity = (((v_forward * 25.000) + (v_right * 70.000)) + (v_up * 100.000));
   	}
   	if ((r < 0.400) && (r >= 0.300)) 
	{
		newmis.velocity = (((v_forward * 15.000) + (v_right * 75.000)) + (v_up * 110.000));
	}
   	if ((r < 0.500) && (r >= 0.400))  
	{
	      newmis.velocity = (((v_forward * 25.000) + (v_right * 80.000)) + (v_up * 130.000));
	}	
	if ((r < 0.600) && (r >= 0.500))
	{
	      newmis.velocity = (((v_forward * 20.000) + (v_right * 85.000)) + (v_up * 150.000));
	}
	if ((r < 0.700) && (r >= 0.600))
	{
	      newmis.velocity = (((v_forward * TE_LAVASPLASH) + (v_right * 90.000)) + (v_up * 120.000));
	}
   	if ((r < 0.800) && (r >= 0.700)) 
	{
	      newmis.velocity = (((v_forward * 20.000) + (v_right * 100.000)) + (v_up * 200.000));
	}
	if ((r < 0.900) && (r >= 0.800))  
	{
	      newmis.velocity = (((v_forward * SVC_INTERMISSION) + (v_right * 110.000)) + (v_up * 130.000));
	}
	if ((r <= 2) && (r >= 0.900)) 
	{
	      newmis.velocity = (((v_forward * 25.000) + (v_right * 105.000)) + (v_up * 175.000));
	}
};

//================================
//	MAGSEC4 FIRING
//================================

void() magsec4_touch =
{
	if (other == self.owner)return;

	if (other.solid == SOLID_TRIGGER)return;	// trigger field, do nothing

	if (pointcontents(self.origin) == CONTENT_SKY)
	{
		remove(self);
		return;
	}
	
	if (other.takedamage)
	{
		spawn_touchblood (45);
		T_Damage (other, self, self.owner, 45);
	}
	else
	{
		WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
		WriteByte (MSG_BROADCAST, TE_SPIKE);
		WriteCoord (MSG_BROADCAST, self.origin_x);
		WriteCoord (MSG_BROADCAST, self.origin_y);
		WriteCoord (MSG_BROADCAST, self.origin_z);
	}

	remove(self);

};

void (vector org) LaunchProjectile =
{
      local vector dir, spd;

      dir = aim (self, 100000);
	spd = dir*1000;

	newmis = spawn ();
	newmis.owner = self;
	newmis.movetype = MOVETYPE_FLYMISSILE;

	newmis.solid = SOLID_BBOX;
	newmis.classname = "bullet";
	newmis.velocity = dir * 1000;

	newmis.angles = vectoangles (newmis.velocity);
      setmodel (newmis, "progs/bullet.mdl");
	setsize (newmis, '0 0 0','0 0 0');
 	setorigin (newmis, org);
	newmis.touch = magsec4_touch; 
	newmis.nextthink = time + 5;
	newmis.think = SUB_Remove;
};

void() W_FireMagsec =
{
	local vector	dir, org, case;
	local entity	old;
	
	makevectors(self.v_angle);
	case = aim (self,10000);

	self.currentammo = self.ammo_nails = self.ammo_nails - 1;

	sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);

	if (random() < 0.1) org = self.origin + '0 0 20'+(v_right * -2);
	else if (random() < 0.2) org = self.origin + '0 0 16'+(v_right * 3);
	else if (random() < 0.3) org = self.origin + '0 0 12'+(v_right * -1);
	else if (random() < 0.4) org = self.origin + '0 0 16'+(v_right * 1);
	else if (random() < 0.5) org = self.origin + '0 0 18'+(v_right * -4);
	else if (random() < 0.6) org = self.origin + '0 0 14'+(v_right * 4);
	else if (random() < 0.7) org = self.origin + '0 0 13'+(v_right * -3);
	else if (random() < 0.8) org = self.origin + '0 0 17'+(v_right * 2);
	else if (random() < 0.9) org = self.origin + '0 0 20'+(v_right * 1);
	else org = self.origin + '0 0 16';

	LaunchProjectile(org); 

	eject_case (((self.origin + (v_forward * 12)) + (v_up * 13)),case);

	self.punchangle_x = -2;
};

Step 2.

Once you have created Magsec.qc open up Weapons.qc and find W_Preacache and add the following to the bottom of the function:

	precache_model ("progs/bullet.mdl");	// Bullet
	precache_model ("progs/case.mdl");		// Bullet Case
	precache_model ("progs/v_magsec.mdl");	// Magsec Pistol Model
Save and go onto Step 3.
Step 3.

Still in Weapons.qc scroll down to W_SetCurrentAmmo and find the following:

	else if (self.weapon == IT_NAILGUN) 
	{
		self.currentammo = self.ammo_nails;
		self.weaponmodel = "progs/v_nail.mdl";
		self.weaponframe = 0;
		self.items = self.items | IT_NAILS;
	}
Replace the above with what follows:

	else if (self.weapon == IT_NAILGUN) //Magsec
	{
		self.currentammo = self.ammo_nails;
		self.weaponmodel = "progs/v_magsec.mdl";
		self.weaponframe = 0;
		self.items = self.items | IT_NAILS;
	}

Step 4.

Now scroll down to W_Attack and find the statement:

	else if (self.weapon == IT_NAILGUN)
Once found replace the contents of its brakects with the following code:

		player_shot1 ();
		W_FireMagsec ();
		self.attack_finished = time + 0.25;
Thats all that need modifying in Weapons.qc
Step 5.

Once you have saved everything compile. You now have a Powerful but inaccurate weapon which Ejects a shell while fireing at a reasonable rate. The following people should be given credit: The creators of Perfect Dark, Kryten for his Projectile code, and last but not least the coder behind the Bullet Case Ejection, sorry I don't know your name. Thank you all! Marius