Physics: Fix grenade bouncing down slopes

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Physics: Fix grenade bouncing down slopes

Post by Baker »

Grenades in Quake don't bounce down slopes and in multiplayer often they get stuck and vibrate annoyingly in places. DarkPlaces has sv_gameplayfix_grenadebouncedownslopes which repairs this and R00k implemented this in Qrack and a custom ProQuake server long ago. This is adapted from Qrack's implementation.

Implementing

1. Create a cvar called sv_gameplayfix_grenadebouncedownslopes and register it. A value of 0 is original Quake behavior obviously.
2. Open sv_physics.c and find this:

Code: Select all

// stop if on ground
	if (trace.plane.normal[2] > 0.7)
	{
		if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE)
		{
			ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
			ent->v.groundentity = EDICT_TO_PROG(trace.ent);
			VectorCopy (vec3_origin, ent->v.velocity);
			VectorCopy (vec3_origin, ent->v.avelocity);
		}
	}
And replace with:

Code: Select all

// stop if on ground
	if (trace.plane.normal[2] > 0.7)
	{
		int stop_moving = false;
		if (sv_gameplayfix_grenadebouncedownslopes.value)
		{
			if (DotProduct(trace.plane.normal, ent->v.velocity) < 60)
				stop_moving = true;
		}
		else
		{
			if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE) 
				stop_moving = true;
		}

		if (stop_moving)
		{
			ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
			ent->v.groundentity = EDICT_TO_PROG(trace.ent);
			VectorCopy (vec3_origin, ent->v.velocity);
			VectorCopy (vec3_origin, ent->v.avelocity);
		}
	}
Disclaimer: I'm not Mr. Physics but have interest in this feature mostly because I find grenades getting stuck in multiplayer annoying and like R00k's fix.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Post by r00k »

Looking in to whats there currently, I find

Code: Select all

	VectorScale (ent->v.velocity, host_frametime, move);
	trace = SV_PushEntity (ent, move);
	if (trace.fraction == 1)
		return;
	if (ent->free)
		return;

	if (ent->v.movetype == MOVETYPE_BOUNCE)
		backoff = 1.5;
	else if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE)
		backoff = 2.0;
	else
		backoff = 1;

	ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff);

// stop if on ground
	//R00k: fixed by LordHavoc
	d = DotProduct(trace.plane.normal, ent->v.velocity);
	if (trace.plane.normal[2] > 0.5 && fabs(d) < 15)//R00k changed so dm6 grenade ramp doesnt stick as much..
	{
		ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
		ent->v.groundentity = EDICT_TO_PROG(trace.ent);
		ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff + (trace.plane.normal[2]));
	}
	else
		ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
	
I havent tested this with gibs, though i feel they should roll like normal
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Post by Baker »

r00k wrote://R00k changed so dm6 grenade ramp doesnt stick as much..
That was where I was doing my testing ... And I kind of felt that the grenades should more reliably bounce. I see you messed with that. hehe :D
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Post Reply