Bounce Items on slopes


(Lanz) #1

I’ve been working on the G_BounceItem. I’m trying to add code for slopes or more exactly non axial faces, this isn’t supported in the code and I really need it for my mod.

Here’s the code as it looks like now:


int IsSlope(trace_t *trace) {
	// check for slope
	if ( trace->plane.normal[2] > 0 && (trace->plane.normal[0] != 0 || trace->plane.normal[1] != 0))  {
		return qtrue;
	} else {
		return qfalse;
	}
}

/*
================
G_BounceItem

================
*/
void G_BounceItem( gentity_t *ent, trace_t *trace ) {
	vec3_t	velocity;
	float	dot;
	int		hitTime;

	// reflect the velocity on the trace plane
	hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction;
	BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity, qfalse, ent->s.effect2Time );
	dot = DotProduct( velocity, trace->plane.normal );
	VectorMA( velocity, -2*dot, trace->plane.normal, ent->s.pos.trDelta );

	G_Printf("normal: %f %f %f trDelta: %f
", trace->plane.normal[0], trace->plane.normal[1], trace->plane.normal[2], ent->s.pos.trDelta[2]);
		
	if (IsSlope(trace) && ent->s.pos.trDelta[2] < 40 && ent->physicsRoll) {
		G_Printf("slope code
");
		VectorScale( ent->s.pos.trDelta, 1 + ent->physicsRoll, ent->s.pos.trDelta );
	} else {
		G_Printf("Bounce code
");

		// cut the velocity to keep from bouncing forever
		VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta );

		// check for stop
		if ( trace->plane.normal[2] > 0 && ent->s.pos.trDelta[2] < 40 ) {
			G_Printf("stop code
");
			trace->endpos[2] += 1.0;	// make sure it is off ground
			SnapVector( trace->endpos );
			G_SetOrigin( ent, trace->endpos );
			ent->s.groundEntityNum = trace->entityNum;
			return;
		}
	}
	
	VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin);
	VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
	ent->s.pos.trTime = level.time;
}

It works ok in some cases depending on the velocity and trajectory of the entity.

The problem is that it sometimes get stuck on slopes anyway because the “bounce code” decrease trDelta[2] and then thinks it’s time to stop. I’ve tried a lot of things but I think I’m stuck in the same thought process so I just don’t know how to fix it atm. Any sugestions is highly welcomed!

edit:
ent->physicsRoll is set to 0.1 and ent->physicsBounce is set to 0.65 when I test.


(Lanz) #2

Bah me == stupid, solved it here’s the code :slight_smile:


int IsSlope(trace_t *trace) {
	// check for slope	
	return ( trace->plane.normal[2] != 0 && (trace->plane.normal[0] != 0 || trace->plane.normal[1] != 0));
}

/*
================
G_BounceItem

================
*/
void G_BounceItem( gentity_t *ent, trace_t *trace ) {
	vec3_t	velocity, old;
	float	dot;
	int		hitTime;

	// reflect the velocity on the trace plane
	hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction;
	BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity, qfalse, ent->s.effect2Time );
	dot = DotProduct( velocity, trace->plane.normal );
	VectorMA( velocity, -2*dot, trace->plane.normal, ent->s.pos.trDelta );

	if (IsSlope(trace) && ent->s.pos.trDelta[2] < 40 && ent->physicsRoll) {
		VectorScale( ent->s.pos.trDelta, 1 + ent->physicsRoll, ent->s.pos.trDelta );
	} else {
		VectorCopy(ent->s.pos.trDelta, old);

		// cut the velocity to keep from bouncing forever
		VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta );

		VectorSubtract(old, ent->s.pos.trDelta, old);

		// check for stop, axial floor or low vector length and low velocity
		if (((trace->plane.normal[2] == 1 || VectorLength(old) < 20) && ent->s.pos.trDelta[2] < 40 ) ||
			(!ent->physicsRoll && trace->plane.normal[2] > 0 && ent->s.pos.trDelta[2] < 40 )){
			trace->endpos[2] += 1.0;	// make sure it is off ground
			SnapVector( trace->endpos );
			G_SetOrigin( ent, trace->endpos );
			ent->s.groundEntityNum = trace->entityNum;
			return;
		} 
	} 

	VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin);
	VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
	ent->s.pos.trTime = level.time;
}

edit: fixed a bug that made other entities bounce repeatedy that doesn’t use physicsRoll.


(pgh) #3

Everytime you post you always fix :slight_smile: maybe its an omen.


(sniser) #4

I played around with this and it’s sooo much better - is it okay to use this code?


(Lanz) #5

pgh:
Hehe, yeah maybe I post to fast instead of banging my head for an hour longer. But when I post I usually feel like I’m giving up, but I still try to solve it after posting lol. (/me takes a mental note: bang head longer before posting)

Sniser:
Sure go ahead, but I updated the code above so use that instead…


(pgh) #6

Any details about the mod your making Lanz? Presuming its for clan v clan play competetively? Need any clans to test with… Im sure some of our peeps might be up for it.


(Deprave) #7

Im Trying to hack yer code in here and well what is physicsRoll, i take it i need to add this to gentity_s struct in g_local.h? sorry for the dumb question


(Lanz) #8

Yup, add it as a float to gentity_s.


(Deprave) #9

Cool thanks a lot lanz works good