Skip to content

Fix shotgun pattern origin in g_weapon.c#78

Open
scoqx wants to merge 1 commit into
ec-:masterfrom
scoqx:patch-1
Open

Fix shotgun pattern origin in g_weapon.c#78
scoqx wants to merge 1 commit into
ec-:masterfrom
scoqx:patch-1

Conversation

@scoqx

@scoqx scoqx commented Jul 1, 2026

Copy link
Copy Markdown

Make server-side start point the same as client's prediction

CG_ShotgunPattern( es->pos.trBase, es->origin2, es->eventParm, es->otherEntityNum );

@WofWca WofWca left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! Indeed the pattern is off. Sometimes it's possible to get the "blood" effect but no damage (especially easy to reproduce if you set fixed seed, tent->s.eventParm = 255):

Image

However, see my comment.

I suspect that this piece of code is also affected? Although it's only about Team Arena.

tent = G_TempEntity( muzzle, EV_LIGHTNINGBOLT );

Comment thread code/game/g_weapon.c
Comment on lines 372 to +379
tent = G_TempEntity( muzzle, EV_SHOTGUN );
VectorScale( forward, 4096.0, tent->s.origin2 );

SnapVector( tent->s.origin2 );
tent->s.eventParm = rand() & 255; // seed for spread pattern
tent->s.otherEntityNum = ent->s.number;

ShotgunPattern( muzzle_origin, tent->s.origin2, tent->s.eventParm, ent );
ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent );

@WofWca WofWca Jul 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to make the client-side stuff match the server side, rather than the other way around. The latter actually changes gameplay, the former does not. So, keep ShotgunPattern as is and instead change the origin of G_TempEntity to muzzle_origin.

Suggested change
ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent );
tent = G_TempEntity( muzzle_origin, EV_SHOTGUN );
VectorScale( forward, 4096.0, tent->s.origin2 );
SnapVector( tent->s.origin2 );
tent->s.eventParm = rand() & 255; // seed for spread pattern
tent->s.otherEntityNum = ent->s.number;
ShotgunPattern( muzzle_origin, tent->s.origin2, tent->s.eventParm, ent );

See the following comment. Looks like muzzle_origin is a better match for hitscan traces. Also it's used for all other weapons.

static vec3_t muzzle;
static vec3_t muzzle_origin; // for hitscan weapon trace

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, but my suggestion, however, would still result in a bit of inaccuracy, due to snapping:

baseq3a/code/game/g_utils.c

Lines 478 to 490 in 5a4ab3a

gentity_t *G_TempEntity( vec3_t origin, int event ) {
gentity_t *e;
vec3_t snapped;
e = G_Spawn();
e->s.eType = ET_EVENTS + event;
e->classname = "tempEntity";
e->eventTime = level.time;
e->freeAfterEvent = qtrue;
VectorCopy( origin, snapped );
SnapVector( snapped ); // save network bandwidth

But I think it's acceptable.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to make the client-side stuff match the server side, rather than the other way around. The latter actually changes gameplay, the former does not. So, keep ShotgunPattern as is and instead change the origin of G_TempEntity to muzzle_origin.

See the following comment. Looks like muzzle_origin is a better match for hitscan traces. Also it's used for all other weapons.

static vec3_t muzzle;
static vec3_t muzzle_origin; // for hitscan weapon trace

I believe it's better to make the server match the client in this case. For over 20 years, everyone has been using the client-side implementation (even OSP 1.03, which was confirmed via decompilation). Forcing everyone to update their clients is not the right approach here.

Every mod I have checked contains this exact same fix (or bug). They all share one thing in common: the client calculates it from s.pos.trBase rather than muzzle. Therefore, I believe the correct approach is to fix the server-side code

@WofWca WofWca Jul 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forcing everyone to update their clients is not the right approach here.

I'm not suggesting to touch client code. I am saying that we need to change the origin of the EV_SHOTGUN temp entity to match the origin passed to ShotgunPattern, and not the other way around (changing the origin passed to ShotgunPattern to match the origin of the temp entity).

Every mod I have checked contains this exact same fix (or bug)

That's how things are in the original Quake III source code. See my comment below, https://github.com/ec-/baseq3a/pull/78#issuecomment-4854832943

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forcing everyone to update their clients is not the right approach here.

I'm not suggesting to touch client code. I am saying that we need to change the origin of the EV_SHOTGUN temp entity to match the origin passed to ShotgunPattern, and not the other way around (changing the origin passed to ShotgunPattern to match the origin of the temp entity).

Every mod I have checked contains this exact same fix (or bug)

That's how things are in the original Quake III source code. See my comment below, https://github.com/ec-/baseq3a/pull/78#issuecomment-4854832943

Sorry my bad

@WofWca

WofWca commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Doing more digging: muzzle_origin has been introduced in 9a7c907, so this commit would partially revert that (unless you apply my suggestion).

@scoqx

scoqx commented Jul 1, 2026

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants