[page=Introduction]
First, I'm assuming you have some prior knowledge as to how to set up your code in a directory to be able to compile a progs.dat'
So lets begin!
[page=The code]
Open up your weapons.qc and towards the top scroll down to
void() W_FireAxe =
{
local vector source;
local vector org;makevectors (self.v_angle);
source = self.origin + '0 0 16';
traceline (source, source + v_forward*64, FALSE, self);
if (trace_fraction == 1.0)
return;org = trace_endpos - v_forward*4;
if (trace_ent.takedamage)
{
trace_ent.axhitme = 1;
SpawnBlood (org, '0 0 0', 20);
T_Damage (trace_ent, self, self, 20);
}
else
{ // hit wall
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
};
This is the code for the axe, it makes an invisible line from the player's origin forward roughly 64 units. We`ll be essentially copying this code and modifying it to make a rifle that can shoot 3000 units.
copy the entire thing and paste it right under, now edit it as follows
void() W_Rifle =
{
local vector source;
local vector org;makevectors (self.v_angle);
source = self.origin + '0 0 16';
traceline (source, source + v_forward*3000 + v_right* 10 * random() * 10 + v_up *
10 * random() * 10 + v_right * -14, FALSE, self);sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
//The super nailgun sound added to each shotorg = trace_endpos - v_forward*4;
if (trace_ent.takedamage)
{SpawnBlood (org, '0 0 0', 20);
T_Damage (trace_ent, self, self, 20);
}
else
{ // hit wallWriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_SPIKE);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
};
To break it down:
traceline (source, source + v_forward*3000 + v_right* 10 * random() * 10 + v_up*
10 * random() * 10 + v_right * -14, FALSE, self);
This is the main new addition, this makes the traceline go 3000 units forward. Then with some random figures to multiply together every shot will be slightly off from directly where the crosshair is. Play with it how you like, the bigger the numbers the more inaccurate the weapon.
WriteByte (MSG_BROADCAST, TE_SPIKE);
Changing TE_GUNSHOT to TE_SPIKE makes it so the impact to a nondamagable object instead of just creating a small greyish puff of smoke it creates a spark and will load ricochet sounds upon impact
Now, scroll very far down in weapons.qc to about 2/3rds down the page to:
void() W_Attack =
{
local float r;if (!W_CheckNoAmmo ())
return;makevectors (self.v_angle); // calculate forward angle for velocity
self.show_hostile = time + 1; // wake monsters upif (self.weapon == IT_AXE)
{
sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
r = random();
if (r < 0.25)
player_axe1 ();
else if (r<0.5)
player_axeb1 ();
else if (r<0.75)
player_axec1 ();
else
player_axed1 ();
self.attack_finished = time + 0.5;
}
else if (self.weapon == IT_SHOTGUN)
{
player_shot1 ();
W_FireShotgun ();
self.attack_finished = time + 0.5;
}
specifically within W_Attack:
else if (self.weapon == IT_SHOTGUN)
{
player_shot1 ();
W_FireShotgun ();
self.attack_finished = time + 0.5;
}
As is before we edit it
* W_FireShotgun void which will load basically the default Quake1 shotgun firing.
* player_shot1 which is the player/weapon animation frames
* self.attack_finished which controls the difference of time between each shot.
change it to look as so
else if (self.weapon == IT_SHOTGUN)
{
player_shot1 ();
W_Rifle ();
self.attack_finished = time + 0.12;
}
Now, save weapons.qc and compile. Copy your progs.dat into your mod's directory and enjoy.
In conclusion, you've created a automatic semi accurate gun, which replaces the shotgun and has infinite ammo, stay tuned for the next tutorial to make it use ammo and how to implement accuracy difference depending on your movement.
Well done