2024-03-28, 11:59 *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
Pages: 1 [2] 3
  Print  
Author Topic: Modifying the shotgun  (Read 37235 times)
0 Members and 1 Guest are viewing this topic.
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #20 on: 2016-03-11, 22:41 »

and  what I mean is

Logged

GET THAT GUY GET THAT GUY, PEW PEW PEW!
Phoenix
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #21 on: 2016-03-12, 13:23 »

One other thing I did notice is you have a gentity_t at the end of your arguments to CG_ShotgunPattern.  That should be an "int otherEntNum".  That shouldn't really affect the spread pattern itself but it may affect the drawing of impact marks.
Logged


I fly into the night, on wings of fire burning bright...
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #22 on: 2016-03-12, 22:46 »

/*
==================
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
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #23 on: 2016-03-13, 09:07 »

So... is it working ok?  Doom - Huh?
Logged


I fly into the night, on wings of fire burning bright...
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #24 on: 2016-03-13, 10:49 »

Oh I'm sorry... No it's still drawing only 2 pellets.
Logged

GET THAT GUY GET THAT GUY, PEW PEW PEW!
Phoenix
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #25 on: 2016-03-14, 00:26 »

So the rotation isn't working but the distance offset is, so it's returning 0 degrees from the sin and cos functions, and the up/down/left/right positioning is CrossProduct skewing the axis data.  The lack of rotation is acting like an integer is being returned from a divide operation when a float should be.  It may need a typecast in there.  I'll tinker with it tomorrow and see what's not working correctly.
Logged


I fly into the night, on wings of fire burning bright...
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #26 on: 2016-03-14, 15:05 »

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.
Quote
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
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #27 on: 2016-03-14, 23:02 »

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.   Slipgate - Tongue

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:

Code:
// 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:

Code:
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:

Code:
// 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

« Reply #28 on: 2016-03-14, 23:18 »

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

« Reply #29 on: 2016-03-15, 01:27 »

Quote from: g_weapon.c
/*
==================
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 );
}


Quote from: cg_weapons.c
/*
================
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 );
   }
}

Quote from: bg_public.h
#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

« Reply #30 on: 2016-03-15, 11:06 »

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
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #31 on: 2016-03-15, 17:24 »

You remembered the ( and ) in ShotgunPattern, but forgot them in CG_ShotgunPattern.  Slipgate - Smirk
Logged


I fly into the night, on wings of fire burning bright...
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #32 on: 2016-03-15, 17:32 »

Derp.... And after I picked at you about order of operations...
Logged

GET THAT GUY GET THAT GUY, PEW PEW PEW!
Phoenix
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #33 on: 2016-03-15, 17:39 »

Logged


I fly into the night, on wings of fire burning bright...
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #34 on: 2016-03-15, 17:54 »

Lmfao
Logged

GET THAT GUY GET THAT GUY, PEW PEW PEW!
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #35 on: 2016-03-15, 22:25 »

Doom - Thumbs Up! Doom - Thumbs Up! Doom - Thumbs Up!
Slipgate - Thumbs up! Slipgate - Thumbs up! Slipgate - Thumbs up!
Big Gun Big Gun Big Gun
Logged

GET THAT GUY GET THAT GUY, PEW PEW PEW!
Orbital-S2D
 

Shambler
*****
Posts: 100

RnR Boss

« Reply #36 on: 2016-03-15, 23:32 »

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
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #37 on: 2016-03-15, 23:51 »

ShotgunPellet is what actually does the damage, in this statement:

damage = DEFAULT_SHOTGUN_DAMAGE * s_quadFactor;

ShotgunPellet is called each iteration of the loop in ShotgunPattern.  It's definitely calling it... I'm going to see what's going on.
Logged


I fly into the night, on wings of fire burning bright...
Phoenix
Bird of Fire
 

Team Member
Elite (7.5k+)
*********
Posts: 8805

WWW
« Reply #38 on: 2016-03-16, 00:25 »

Ahh, I found the problem.  It's a leftover gib from the crossproduct stuff in ShotgunPattern.  Remark out the line I've noted below:

Code:
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!!!  Banging Head against Wall

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

« Reply #39 on: 2016-03-16, 00:26 »

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!
Pages: 1 [2] 3
  Print  
 
Jump to: