[page=Introduction]
I'm assuming you've done Part 1 of this rifle tutorial, if you haven't this tutorial will not be implementable directly into your code without some optomizations
Lets begin!
[page=The Code]
open up weapons.qc again and find our code
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 shot
org = trace_endpos - v_forward*4;
if (trace_ent.takedamage)
{
SpawnBlood (org, '0 0 0', 20);
T_Damage (trace_ent, self, self, 20);
}
else
{ // hit wall
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_SPIKE);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
};
We are now going to implement accuracy based on movement
void() W_Rifle =
{
local vector source;
local vector org;makevectors (self.v_angle);
source = self.origin + '0 0 16';if (!self.velocity_x || !self.velocity_y)
{
traceline (source, source + v_forward*3000 + v_right* 10 * random() * 10 + v_up* 10 *
random() * 10 + v_right * -14, FALSE, self);
}if (self.velocity_x || self.velocity_y)
{
traceline (source, source + v_forward*3000 + v_right* 15 * random() * 14 + v_up* 17 *
random() * 16 + v_right * -20, 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);
}
};
Now, to explain what we replaced the previous traceline function with
if (!self.velocity_x || !self.velocity_y)
{
traceline (source, source + v_forward*3000 + v_right* 10 * random() * 10 + v_up* 10 *
random() * 10 + v_right * -14, FALSE, self);
}
This was our previous traceline function, just within a if statement, basically it says in regular terms if the client (self) is not moving on the x or y axis (on the ground in any which way) use this traceline function and proceed on to what it hits and whether or not to deal out damage or just impact a wall.
if (self.velocity_x || self.velocity_y)
{
traceline (source, source + v_forward*3000 + v_right* 15 * random() * 14 + v_up* 17 *
random() * 16 + v_right * -20, FALSE, self);
}
This, very similar to the previous if statement states that if there is any form of movement (notice the lack of ! before each self.velocity) that the this traceline function should be used instead of the previous one. The difference in the traceline function is the numbers are generally greater and will cause a more inaccurate shot
Next, we want to implement it so it uses a shell still for each shot. Proceed to paste:
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
right after:
org = trace_endpos - v_forward*4;
This will now make it similar to the default Quake1 shotgun of uses 1 ammo shell per shot. Simple enough right? Now save and compile your code and paste your progs.dat into your mod directory. Enjoy!
In conclusion, we have added to our previous rifle code movement specific accuracy and the use of an ammo shell per shot. Stay tuned for next tutorial'