Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
and what I mean is
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
/* ================== ReQWave Shotgun Spread Thanks Phoenix Gen Arena This should match CG_ShotgunPattern ================== */ void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) { int i; float r, u; vec3_t end; vec3_t forward, right, up; int oldScore; qboolean hitClient = qfalse;
float range; // How far away from center we're placing our pellets. int interval; // How many times we're incrementing. float deg; // How many degrees we're rotating by. This should be half the total count.
interval = DEFAULT_SHOTGUN_COUNT; if (interval <= 0){ // I always sanity check for divide by zero when doing a divide by any variable. interval = 16; } deg = 360 / 0.5f * interval;
// derive the right and up vectors from the forward vector, because // the client won't have any other information VectorNormalize2( origin2, forward ); PerpendicularVector( right, forward ); CrossProduct( forward, right, up );
oldScore = ent->client->ps.persistant[PERS_SCORE];
// generate the "random" spread pattern for ( i = 0 ; i < interval ; i++ ) {
r = sin(DEG2RAD( (0.5f * deg) + (deg * i)) ); u = cos(DEG2RAD( (0.5f * deg ) + (deg * i)) );
if (i < interval * 0.5){ range = 0.5f * DEFAULT_SHOTGUN_SPREAD; } else { range = DEFAULT_SHOTGUN_SPREAD; }
r *= range * 16; u *= range * 16;
VectorMA( origin, 8192 *16, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); if( ShotgunPellet( origin, end, ent ) && !hitClient ) { hitClient = qtrue; ent->client->accuracy_hits++; } } }
/* ================ CG_ShotgunPattern ReQWave Thanks Phoenix Gen Arena Perform the same traces the server did to locate the hit splashes ================ */ static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, int otherEntNum ) { int i; float r, u; vec3_t end; vec3_t forward, right, up;
float range; // How far away from center we're placing our pellets. int interval; // How many times we're incrementing. float deg; // How many degrees we're rotating by. This should be half the total count.
interval = DEFAULT_SHOTGUN_COUNT; if (interval <= 0){ // I always sanity check for divide by zero when doing a divide by any variable. interval = 16; } deg = 360 / 0.5f * interval;
// derive the right and up vectors from the forward vector, because // the client won't have any other information VectorNormalize2( origin2, forward ); PerpendicularVector( right, forward ); CrossProduct( forward, right, up );
// generate the "random" spread pattern for ( i = 0 ; i < interval ; i++ ) {
r = sin(DEG2RAD( (0.5f * deg) + (deg * i)) ); u = cos(DEG2RAD( (0.5f * deg ) + (deg * i)) );
if (i < interval * 0.5){ range = 0.5f * DEFAULT_SHOTGUN_SPREAD; } else { range = DEFAULT_SHOTGUN_SPREAD; }
r *= range * 16; u *= range * 16;
VectorMA( origin, 8192 *16, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end);
CG_ShotgunPellet( origin, end, otherEntNum ); } }
bg_public.h
#define DEFAULT_SHOTGUN_SPREAD 700 #define DEFAULT_SHOTGUN_COUNT 16 (i tried 20 first)
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Phoenix
|
So... is it working ok?
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Oh I'm sorry... No it's still drawing only 2 pellets.
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Hmmm... Just an FYI I have been using a ioq3 based source. And I noticed team stats mod doesn't work. It won't show the armor or health of the teammates. Another coding friend said this. char *teamstat; if (cgs.clientinfo[cg.crosshairClientNum].health) { teamstat = va("Health: %i Armor: %i", cgs.clientinfo[ cg.crosshairClientNum ].health, cgs.clientinfo[ cg.crosshairClientNum ].armor);
w = CG_DrawStrlen(teamstat) * SMALLCHAR_WIDTH;
CG_DrawSmallString(320 - w / 2, 190, teamstat, color[3] * 0.5f); }
The code does not work because 'cgs.clientinfo[cg.crosshairClientNum].health' is always zero. If you comment out the 'if' statement then the health and armor values are displayed but they are always shown as zero regardless of which player you point the crosshair to.
It seems that in this version of ioquake3 the required information is not sent to the cgame module. Actually, it does not have to know the health and armor values of other players for correct operation. The comment in 'cg_local.h' before the definition of the 'clientinfo_t' structure says that you get this info only for teammates, but apparently that is not true.
BTW the above code snippet is sloppy because the 'if' statement should also check if the other player is a teammate of the local client, so that displaying junk info (zero health/armor) for enemy team members is avoided.
The way I found out was the following:
1. Tried to print the static string 'foobar' instead of the content of 'teamstate' --> nothing 2. Tried to use CG_DrawBigString (to see if CG_DrawSmallString did not work for some reason) --> nothing 3. Commented out the 'if' statement --> got health and armor shown as zero
It was then obvious that the clause of the 'if' was always false, so nothing was displayed. Searched the cgame sources to see if 'cgs.clientinfo[cg.crosshairClientNum].health' is ever updated, but it is done only for the local client. This kind of experimenting is very useful when you want to locate the source of a bug. Also 'Com_Printf' can be very useful to dump the current values of variables at different points in the code. I don't know if this may help with the shotgun pattern at all but because of changes like this I maybe changing my base source...
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Phoenix
|
It's not the ioquake3 source for the shotgun issue. It's me forgetting how to math. Here's the fix for the shotgun pattern. Change this line in both ShotgunPattern and CG_ShotgunPattern:
deg = 360 / 0.5f * interval;
to this:
deg = 360.0f / (0.5f * interval);
That will fix the 2 pellet issue. The reason is order of operations. It was doing this:
when interval = 12
360 / 0.5 = 720 720 * 12 = 8640
When what we wanted was this:
0.5 * 12 = 6
360 / 6 = 60.
That's all because I forgot the ( and ). I'm great at hacking functions together, but I tend to screw up the math a lot.
Now you will notice that by using 12 pellets the pattern will flip due to PerpendicularVector and CrossProduct being implemented crappy. If you use 16 pellets it's not noticeable. If you decide you want to ditch the PerpendicularVector and CrossProduct so your pattern is always consistent, then here's how to get around that.
The shotgun code sends the forward vector along with the event to the client. What we're going to do is replace the forward vector with the player's viewangles instead. Why Id didn't do this to begin with is beyond me, but it works. What we'll do is derive the forward, right, and up vectors from the angle vector on the client just like the server does so it will match up perfectly and without flipping our right and up vectors around when we look in different directions.
In g_weapon.c, make this change to ShotgunPattern:
// Phoenix - remarking this out. The static forward, right, and up vectors are already derived from // ent->client->ps.viewangles in the FireWeapon function, so we don't need to recalculate them.
// derive the right and up vectors from the forward vector, because // the client won't have any other information // VectorNormalize2( origin2, forward ); // PerpendicularVector( right, forward ); // CrossProduct( forward, right, up );
Next, again in g_weapon.c, look at weapon_supershotgun_fire and make this change:void weapon_supershotgun_fire (gentity_t *ent) { gentity_t *tent;
// send shotgun blast tent = G_TempEntity( muzzle, EV_SHOTGUN ); // Phoenix - remarking this out. // VectorScale( forward, 4096, tent->s.origin2 );
// Phoenix - Send the view angles with the event instead of the forward vector. We can derive the // forward, right, and up vectors from that on the client. VectorCopy(ent->client->ps.viewangles, tent->s.origin2); // Phoenix - remarking this out. We don't want to snap this - it needs to be precise. // SnapVector( tent->s.origin2 ); tent->s.eventParm = rand() & 255; // seed for spread pattern tent->s.otherEntityNum = ent->s.number;
ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent ); }
In cg_weapons.c, make this change to CG_ShotgunPattern:// Phoenix - remark all this stuff out. We're not using it anymore.
// derive the right and up vectors from the forward vector, because // the client won't have any other information // VectorNormalize2( origin2, forward ); // PerpendicularVector( right, forward ); // CrossProduct( forward, right, up );
// Phoenix - we sent our angles in the origin2 vector, so we'll just derive them from that like the server does. // This will prevent the pattern from flipping so we can use asymmetrical spreads if we want.
AngleVectors (origin2, forward, right, up);
Now your shotgun pattern shouldn't flip around. You can use 12 pellets and it will be consistent wherever you look.
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
PEMDAS
Haha I'll let you know how it works
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
/* ================== ReQWave Shotgun Spread Thanks Phoenix Gen Arena This should match CG_ShotgunPattern ================== */ void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) { int i; float r, u; vec3_t end; vec3_t forward, right, up; int oldScore; qboolean hitClient = qfalse;
float range; // How far away from center we're placing our pellets. int interval; // How many times we're incrementing. float deg; // How many degrees we're rotating by. This should be half the total count.
interval = DEFAULT_SHOTGUN_COUNT; if (interval <= 0){ // I always sanity check for divide by zero when doing a divide by any variable. interval = 16; } deg = 360 / (0.5f * interval);
// Phoenix - remarking this out. The static forward, right, and up vectors are already derived from // ent->client->ps.viewangles in the FireWeapon function, so we don't need to recalculate them. // derive the right and up vectors from the forward vector, because // the client won't have any other information //VectorNormalize2( origin2, forward ); //PerpendicularVector( right, forward ); //CrossProduct( forward, right, up );
oldScore = ent->client->ps.persistant[PERS_SCORE];
// generate the "random" spread pattern for ( i = 0 ; i < interval ; i++ ) {
r = sin(DEG2RAD( (0.5f * deg) + (deg * i)) ); u = cos(DEG2RAD( (0.5f * deg ) + (deg * i)) );
if (i < interval * 0.5){ range = 0.5f * DEFAULT_SHOTGUN_SPREAD; } else { range = DEFAULT_SHOTGUN_SPREAD; }
r *= range * 16; u *= range * 16;
VectorMA( origin, 8192 *16, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); if( ShotgunPellet( origin, end, ent ) && !hitClient ) { hitClient = qtrue; ent->client->accuracy_hits++; } } }
/*void weapon_supershotgun_fire(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;
ShotgunPattern(tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent); } */
//ReQWave Phoenix Shotgun Spread void weapon_supershotgun_fire (gentity_t *ent) { gentity_t *tent;
// send shotgun blast tent = G_TempEntity( muzzle, EV_SHOTGUN ); // Phoenix - remarking this out. // VectorScale( forward, 4096, tent->s.origin2 );
// Phoenix - Send the view angles with the event instead of the forward vector. We can derive the // forward, right, and up vectors from that on the client. VectorCopy(ent->client->ps.viewangles, tent->s.origin2); // Phoenix - remarking this out. We don't want to snap this - it needs to be precise. // SnapVector( tent->s.origin2 ); tent->s.eventParm = rand() & 255; // seed for spread pattern tent->s.otherEntityNum = ent->s.number;
ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent ); }
/* ================ CG_ShotgunPattern ReQWave Thanks Phoenix Gen Arena Perform the same traces the server did to locate the hit splashes ================ */ static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, int otherEntNum ) { int i; float r, u; vec3_t end; vec3_t forward, right, up;
float range; // How far away from center we're placing our pellets. int interval; // How many times we're incrementing. float deg; // How many degrees we're rotating by. This should be half the total count.
interval = DEFAULT_SHOTGUN_COUNT; if (interval <= 0){ // I always sanity check for divide by zero when doing a divide by any variable. interval = 16; } deg = 360 / 0.5f * interval;
// Phoenix - remark all this stuff out. We're not using it anymore.
// derive the right and up vectors from the forward vector, because // the client won't have any other information // VectorNormalize2( origin2, forward ); // PerpendicularVector( right, forward ); // CrossProduct( forward, right, up );
// Phoenix - we sent our angles in the origin2 vector, so we'll just derive them from that like the server does. // This will prevent the pattern from flipping so we can use asymmetrical spreads if we want.
AngleVectors (origin2, forward, right, up);
// generate the "random" spread pattern for ( i = 0 ; i < interval ; i++ ) {
r = sin(DEG2RAD( (0.5f * deg) + (deg * i)) ); u = cos(DEG2RAD( (0.5f * deg ) + (deg * i)) );
if (i < interval * 0.5){ range = 0.5f * DEFAULT_SHOTGUN_SPREAD; } else { range = DEFAULT_SHOTGUN_SPREAD; }
r *= range * 16; u *= range * 16;
VectorMA( origin, 8192 *16, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end);
CG_ShotgunPellet( origin, end, otherEntNum ); } } #define DEFAULT_SHOTGUN_SPREAD 700 #define DEFAULT_SHOTGUN_COUNT 16 I attached the VM
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Now the pellets don't flip around the center of the screen but it's still only two.
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Phoenix
|
You remembered the ( and ) in ShotgunPattern, but forgot them in CG_ShotgunPattern.
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Derp.... And after I picked at you about order of operations...
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Phoenix
|
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
Lmfao
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
In an interesting turn of events the pattern works great but shotgun does no damage,
I tried to change the default shotgun damage from 10 to 5.5. i though that if that was a decimal maybe it was wrong. so i changed it to a whole number. 6 and still had no damage. i changed it to 10 and still had no damage. i scaned over the modifications too the code and best i can tell the code is sound. so what actually causes the shotgun damage?
this part looks the same between the orig and the mod if (ShotgunPellet(origin, end, ent) && !hitClient) { hitClient = qtrue; ent->client->accuracy_hits++; }
I dont know why it wouldnt work. maybe im looking in the wrong spot
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|
Phoenix
|
Ahh, I found the problem. It's a leftover gib from the crossproduct stuff in ShotgunPattern. Remark out the line I've noted below:void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) { int i; float r, u; vec3_t end; // Phoenix - We don't need these local vectors overriding the static vectors or we'll lose our angle data. // vec3_t forward, right, up; int oldScore; qboolean hitClient = qfalse; The forward, right, and up vectors here are local to the function, but at the very beginning of g_weapon.c you'll see the same variable names as static vec3_t. Static vars are "global" vars within that file that retain their data between functions, as opposed to local vars within the function that are not accessible to other functions unless passed in an argument. The static vars are derived from the player's view angles in FireWeaon. Using the same variable names for both global and local variables is BAD PROGRAMMING TECHNIQUE!!! BAD DUFFY!! BAD, BAD DUFFY!! SHAME ON YOU!!! So remark that line out and the damage traces will work properly. Do NOT remark the line out in CG_ShotgunPattern because the ones used there are local; there's no static versions in that file so CG_ShotgunPattern is coded properly.
|
|
|
Logged
|
I fly into the night, on wings of fire burning bright...
|
|
|
Orbital-S2D
Shambler
Posts: 100
RnR Boss
|
it seems you have to aim high and point-blank to hit. also in the face
here is a vm
|
|
|
Logged
|
GET THAT GUY GET THAT GUY, PEW PEW PEW!
|
|
|
|