Git Repos / fte_dogmode / engine-patches / ironwail-0.7.0_dogmode-0.1.patch
Last update to this file was on 2023-10-13 at 12:38.
Show ironwail-0.7.0_dogmode-0.1.patch
diff -Nur ironwail-0.7.0-orig/Quake/sv_main.c ironwail-0.7.0-hacked/Quake/sv_main.c
--- ironwail-0.7.0-orig/Quake/sv_main.c 2023-03-17 10:53:47.000000000 -0700
+++ ironwail-0.7.0-hacked/Quake/sv_main.c 2023-04-23 18:59:23.484887000 -0700
@@ -35,6 +35,8 @@
static cvar_t sv_netsort = {"sv_netsort", "1", CVAR_NONE};
+void CEV_Callback_Dogmode (cvar_t *var); // this shouldn't be here CEV
+
//============================================================================
void SV_CalcStats(client_t *client, int *statsi, float *statsf, const char **statss)
@@ -146,6 +148,9 @@
extern cvar_t sv_maxvelocity;
extern cvar_t sv_gravity;
extern cvar_t sv_nostep;
+ // are you playing those dog maps again? CEV
+ extern cvar_t sv_dogmode;
+ extern cvar_t sv_q3airaccelerate;
extern cvar_t sv_freezenonclients;
extern cvar_t sv_friction;
extern cvar_t sv_edgefriction;
@@ -173,6 +178,9 @@
Cvar_RegisterVariable (&sv_idealpitchscale);
Cvar_RegisterVariable (&sv_aim);
Cvar_RegisterVariable (&sv_nostep);
+ Cvar_RegisterVariable (&sv_dogmode);
+ Cvar_SetCallback (&sv_dogmode, CEV_Callback_Dogmode);
+ Cvar_RegisterVariable (&sv_q3airaccelerate);
Cvar_RegisterVariable (&sv_freezenonclients);
Cvar_RegisterVariable (&pr_checkextension);
Cvar_RegisterVariable (&sv_altnoclip); //johnfitz
diff -Nur ironwail-0.7.0-orig/Quake/sv_phys.c ironwail-0.7.0-hacked/Quake/sv_phys.c
--- ironwail-0.7.0-orig/Quake/sv_phys.c 2023-03-17 10:53:47.000000000 -0700
+++ ironwail-0.7.0-hacked/Quake/sv_phys.c 2023-04-23 18:59:12.342461000 -0700
@@ -46,6 +46,7 @@
cvar_t sv_gravity = {"sv_gravity","800",CVAR_NOTIFY|CVAR_SERVERINFO};
cvar_t sv_maxvelocity = {"sv_maxvelocity","2000",CVAR_NONE};
cvar_t sv_nostep = {"sv_nostep","0",CVAR_NONE};
+cvar_t sv_dogmode = {"sv_dogmode","0",CVAR_NONE};
cvar_t sv_freezenonclients = {"sv_freezenonclients","0",CVAR_NONE};
@@ -795,6 +796,433 @@
/*
=====================
+CEV_Callback_Dogmode
+
+When dogmode is flipped on set a default q3airaccelerate value
+=====================
+*/
+void CEV_Callback_Dogmode (cvar_t *var)
+{
+ if (var->value)
+ // 0.275 feels right to me. the fact that it's a
+ // weird value like that probably means something
+ // has gone wrong somewhere. CEV
+ Cvar_SetValue ("sv_q3airaccelerate", 0.275);
+ else
+ Cvar_SetValue ("sv_q3airaccelerate", 0);
+}
+
+/*
+=====================
+VectorNormalize2
+
+Added by CEV to support SlideMove below. I'm sure there's an easy way
+to do this without implementing Normalize2 but here we are.
+=====================
+*/
+vec_t VectorNormalize2(const vec3_t in, vec3_t out)
+{
+ vec_t length, ilength;
+
+ length = sqrt (in[0]*in[0] + in[1]*in[1] + in[2]*in[2]);
+ if (length == 0)
+ {
+ VectorCopy (vec3_origin, out);
+ return 0;
+ }
+
+ ilength = 1.0/length;
+ out[0] = in[0]*ilength;
+ out[1] = in[1]*ilength;
+ out[2] = in[2]*ilength;
+
+ return length;
+}
+
+/*
+=====================
+CEV_SetOnGround
+
+Set onground flag & return true if player is now on ground
+=====================
+*/
+qboolean CEV_SetOnGround (edict_t *ent, trace_t *downtrace)
+{
+ if (downtrace->plane.normal[2] > 0.7)
+ {
+ // removed this check so that player can walk on monsters
+ // if (downtrace->ent->v.solid == SOLID_BSP)
+ // {
+ ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
+ ent->v.groundentity = EDICT_TO_PROG(downtrace->ent);
+ return true;
+ // }
+ }
+ else
+ {
+ ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
+ return false;
+ }
+}
+
+/*
+=====================
+CEV_SlideMove
+
+A backport of Quake 3's PM_SlideMove into Quake 1. Does not handle timers
+or gravity like Q3's version does.
+
+Returns the clipflags if the velocity was modified (similar to FlyMove)
+1 = floor
+2 = wall / step
+4 = dead stop
+8 = hit a non-axial plane
+If steptrace is not NULL, the trace of any vertical wall hit will be stored
+if groundtrace is not NULL, store the trace of last ground plane we encounter
+=====================
+*/
+#define Q3_OVERCLIP 1.001f
+#define Q3_STEPSIZE 18
+#define CEV_MAX_CLIP_PLANES 5
+extern cvar_t developer;
+int CEV_SlideMove (edict_t *ent, float time, trace_t *steptrace, trace_t *groundtrace)
+{
+ int bumpcount, numbumps;
+ vec3_t dir;
+ float d;
+ int numplanes;
+ vec3_t planes[CEV_MAX_CLIP_PLANES];
+ vec3_t clip_velocity;
+ int i, j, k;
+ trace_t trace;
+ vec3_t end;
+ float time_left;
+ int blocked;
+
+ time_left = time;
+ numplanes = 0;
+ numbumps = 4;
+ blocked = 0;
+
+ // never turn against original velocity
+ VectorNormalize2 (ent->v.velocity, planes[numplanes]);
+ numplanes++;
+
+ for (bumpcount=0; bumpcount < numbumps; bumpcount++)
+ {
+ VectorMA (ent->v.origin, time_left, ent->v.velocity, end);
+ trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
+
+ if (trace.allsolid)
+ {
+ // entity is trapped in another solid
+ if (developer.value)
+ Con_Printf ("CEV_SlideMove: entity trapped in another solid\n");
+ ent->v.velocity[2] = 0;
+ if (steptrace)
+ *steptrace = trace;
+ return 3;
+ }
+
+ if (trace.fraction > 0)
+ // covered some distance
+ VectorCopy (trace.endpos, ent->v.origin);
+
+ if (trace.fraction == 1)
+ // moved the entire distance
+ break;
+
+ if (trace.plane.normal[2] > 0.7)
+ {
+ // found the floor (?)
+ blocked |= 1;
+ if (groundtrace) *groundtrace = trace;
+ }
+
+ if (!trace.plane.normal[2])
+ // step or wall
+ blocked |= 2;
+
+ if (!trace.ent)
+ Sys_Error ("CEV_SlideMove: !trace.ent");
+
+ // run the impact function
+ SV_Impact (ent, trace.ent);
+ if (ent->free)
+ // removed by the impact function
+ break;
+
+ time_left -= time_left * trace.fraction;
+
+ // comment from Q3 source: if this is the same plane we
+ // hit before, nudge velocity out along it, which fixes
+ // some epsilon issues with non-axial planes
+ for (i = 0; i < numplanes; i++)
+ {
+ if (DotProduct (trace.plane.normal, planes[i]) > 0.99)
+ {
+ // this seems to happen fairly often on uneven
+ // ground or complicated geometry.
+ if (developer.value)
+ Con_Printf ("CEV_SlideMove: non-axial plane: %f\n", DotProduct (trace.plane.normal, planes[i]));
+ VectorAdd (trace.plane.normal, ent->v.velocity, ent->v.velocity);
+ // set a blocked flag so StepSlideMove knows
+ // to try the move again one stepheight up
+ blocked |= 8;
+ break;
+ }
+ }
+
+ // found a repeated plane
+ if (i < numplanes) continue;
+
+ if (numplanes >= CEV_MAX_CLIP_PLANES)
+ {
+ // this shouldn't really happen
+ if (developer.value)
+ Con_Printf ("CEV_SlideMove: numplanes >= MAX_CLIP_PLANES\n");
+ VectorCopy (vec3_origin, ent->v.velocity);
+ if (steptrace)
+ *steptrace = trace;
+ return 3;
+ }
+
+ VectorCopy (trace.plane.normal, planes[numplanes]);
+ numplanes++;
+
+ // modify velocity so it parallels all of the clip planes
+ // find a plane that it enters
+ for (i = 0; i < numplanes; i++)
+ {
+ if (DotProduct (ent->v.velocity, planes[i]) >= 0.1)
+ {
+ // move doesn't interact with the plane
+ // if (developer.value)
+ // Con_Printf ("CEV_SlideMove: into >= 0.1\n");
+ continue;
+ }
+
+ // slide along the plane
+ ClipVelocity (ent->v.velocity, planes[i], clip_velocity, Q3_OVERCLIP);
+
+ // is there a second plane that the new move enters?
+ for (j = 0; j < numplanes; j++)
+ {
+ if (j == i) continue;
+ if (DotProduct (clip_velocity, planes[j]) >= 0.1)
+ // move doesn't interact with the plane
+ continue;
+
+ // try clipping the move to the plane
+ ClipVelocity (clip_velocity, planes[j], clip_velocity, Q3_OVERCLIP);
+ // see if it goes back into the first clip plane
+ // this seems to happen fairly often
+ if ( DotProduct( clip_velocity, planes[i] ) >= 0 )
+ continue;
+
+ // slide the original velocity along the crease
+ CrossProduct (planes[i], planes[j], dir);
+ VectorNormalize (dir);
+ d = DotProduct (dir, ent->v.velocity);
+ VectorScale (dir, d, clip_velocity);
+
+ // see if there is a third plane the move enters
+ for (k = 0; k < numplanes; k++)
+ {
+ if (k == i || k == j) continue;
+ if (DotProduct(clip_velocity, planes[k]) >= 0.1)
+ // doesn't interact with plane
+ continue;
+ // stop at a triple plane interaction
+ VectorCopy (vec3_origin, ent->v.velocity);
+ if (developer.value)
+ Con_Printf ("CEV_SlideMove: Stopped at a triple plane interaction\n");
+ if (steptrace)
+ *steptrace = trace;
+ return 7;
+ }
+ }
+
+ // if we have fixed all interaction, try another move
+ VectorCopy (clip_velocity, ent->v.velocity);
+ break;
+ }
+
+ }
+
+ // if ((developer.value) && (bumpcount > 1))
+ // Con_Printf ("CEV_SlideMove: bumps, planes: %i, %i\n", bumpcount, numplanes);
+ if (steptrace)
+ *steptrace = trace;
+ return blocked;
+}
+
+/*
+=====================
+CEV_StepSlideMove
+
+Based on Quake 3's PM_StepSlideMove. First attempt a SlideMove; if we're
+blocked by a step or wall, then attempt a second SlideMove one STEPHEIGHT
+up from where we started. Revert to the first slide move if there's a
+problem with the second.
+
+This can definitely be refactored or cut down or simplified. I'm storing
+some traces and/or values that I probably don't need to be. This could
+also be folded into / merged with CEV_WalkMove as that latter function
+isn't doing much right now.
+
+Returns clipflags from the SlideMove.
+=====================
+*/
+int CEV_StepSlideMove (edict_t *ent, float time, qboolean gravity)
+{
+ vec3_t start_o, start_v;
+ vec3_t first_o, first_v;
+ trace_t trace, first_trace, second_trace, first_ground, second_ground;
+ vec3_t up, down;
+ float stepsize;
+ int first_clip, second_clip;
+
+ first_clip = second_clip = 0;
+
+ VectorCopy (ent->v.origin, start_o);
+ VectorCopy (ent->v.velocity, start_v);
+
+ first_clip = CEV_SlideMove (ent, time, &first_trace, &first_ground);
+
+ if (!(first_clip & 2) && !(first_clip & 8))
+ {
+ // we got where we wanted to go first try
+ CEV_SetOnGround(ent, &first_ground);
+ return first_clip;
+ }
+
+ if ((int)sv_player->v.flags & FL_WATERJUMP)
+ {
+ if (developer.value)
+ Con_Printf ("CEV_StepSlideMove: FL_WATERJUMP\n");
+ return first_clip;
+ }
+
+ if (ent->v.movetype != MOVETYPE_WALK)
+ // gibbed by a trigger
+ return first_clip;
+
+ if (sv_nostep.value)
+ {
+ CEV_SetOnGround(ent, &first_ground);
+ return first_clip;
+ }
+
+ VectorCopy (ent->v.origin, first_o);
+ VectorCopy (ent->v.velocity, first_v);
+
+ // test the player position if they were a stepheight higher
+ VectorCopy (start_o, up);
+ up[2] += Q3_STEPSIZE;
+ trace = SV_Move (start_o, ent->v.mins, ent->v.maxs, up, false, ent);
+ if (trace.allsolid)
+ {
+ // can't step up
+ if (developer.value)
+ Con_Printf ("CEV_StepSlideMove: can't step up\n");
+ first_clip |= 2;
+ VectorCopy (first_trace.endpos, ent->v.origin);
+ if (first_trace.fraction < 1.0)
+ ClipVelocity (ent->v.velocity, first_trace.plane.normal, ent->v.velocity, Q3_OVERCLIP);
+ // should this be trace or first_trace or first_ground?
+ CEV_SetOnGround(ent, &first_ground);
+ return first_clip;
+ }
+
+ stepsize = trace.endpos[2] - start_o[2];
+ // try slidemove from this position (in air)
+ VectorCopy (trace.endpos, ent->v.origin);
+ VectorCopy (start_v, ent->v.velocity);
+
+ second_clip = CEV_SlideMove (ent, time, &second_trace, &second_ground);
+
+ // push down the final amount
+ VectorCopy (ent->v.origin, down);
+ down[2] -= stepsize;
+ trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, down, false, ent);
+
+ if (trace.allsolid)
+ {
+ if (developer.value)
+ Con_Printf ("CEV_StepSlideMove: rejecting second slide position\n");
+ // I'm pretty sure the behavior here is wrong but it
+ // seems to work so...
+ VectorCopy (start_o, ent->v.origin);
+ // CEV_SetOnGround(ent, &trace);
+ return 3;
+ }
+
+ if (trace.plane.normal[2] > 0.7)
+ {
+ // we're on "good ground", accept the second slide move
+ VectorCopy (trace.endpos, ent->v.origin);
+ if (trace.fraction < 1.0)
+ ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, Q3_OVERCLIP);
+ CEV_SetOnGround (ent, &trace);
+ return second_clip;
+ }
+ else
+ {
+ // not on "good ground", revert to first slide move.
+ // See the similar section of SV_WalkMove.
+ if (developer.value)
+ Con_Printf ("CEV_StepSlideMove: reverting to first SlideMove\n");
+ VectorCopy (first_trace.endpos, ent->v.origin);
+ if (first_trace.fraction < 1.0)
+ ClipVelocity (ent->v.velocity, first_trace.plane.normal, ent->v.velocity, Q3_OVERCLIP);
+ CEV_SetOnGround (ent, &first_ground);
+ return first_clip;
+ }
+}
+
+/*
+=====================
+CEV_WalkMove
+
+Alternate WalkMove for use by players. At this point largely a wrapper
+around StepSlideMove.
+=====================
+*/
+void CEV_WalkMove (edict_t *ent)
+{
+ vec3_t start_o, start_v;
+ float stepsize;
+ int start_onground;
+ int clip;
+
+ VectorCopy (ent->v.origin, start_o);
+ VectorCopy (ent->v.velocity, start_v);
+ start_onground = (int)ent->v.flags & FL_ONGROUND;
+ ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
+
+ clip = CEV_StepSlideMove (ent, host_frametime, true);
+
+ // this is a complicated check.
+ // if we started in the air and we're now on the ground
+ // and we were moving upward at the start of the move
+ // and the move has resulted in a near complete loss of
+ // Z velocity then we've clipped to ground on a step up.
+ if (!start_onground && (int)ent->v.flags & FL_ONGROUND)
+ {
+ if (start_v[2] > ent->v.velocity[2])
+ if (ent->v.velocity[2] < 1)
+ {
+ stepsize = ent->v.origin[2] - start_o[2];
+ ent->v.flags = (int)ent->v.flags | FL_PARTIALGROUND;
+ if (developer.value)
+ Con_Printf ("CEV_WalkMove: clipped a step. size: %f\n", stepsize);
+ }
+ }
+}
+
+/*
+=====================
SV_WalkMove
Only used by players
@@ -937,7 +1365,11 @@
if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
SV_AddGravity (ent);
SV_CheckStuck (ent);
- SV_WalkMove (ent);
+ // TODO CEV
+ if (sv_dogmode.value)
+ CEV_WalkMove (ent);
+ else
+ SV_WalkMove (ent);
break;
case MOVETYPE_TOSS:
diff -Nur ironwail-0.7.0-orig/Quake/sv_user.c ironwail-0.7.0-hacked/Quake/sv_user.c
--- ironwail-0.7.0-orig/Quake/sv_user.c 2023-03-17 10:53:47.000000000 -0700
+++ ironwail-0.7.0-hacked/Quake/sv_user.c 2023-04-23 18:57:53.611293000 -0700
@@ -182,6 +182,66 @@
velocity[i] += accelspeed*wishdir[i];
}
+/*
+============
+CEV_Q3CmdScale
+
+Taken from Quake3's bg_pmove.c . I don't exactly know what this does,
+but it seems to be necessary (from my experiments / playtesting) for
+Quake 3 strafejumping to feel correct.
+
+Comment from Quake 3 source:
+Returns the scale factor to apply to cmd movements
+This allows the clients to use axial -127 to 127 values for all directions
+without getting a sqrt(2) distortion in speed.
+============
+*/
+static float CEV_Q3CmdScale (float speed, usercmd_t *cmd)
+{
+ int max;
+ float total;
+ float scale;
+
+ max = fabsf (cmd->forwardmove);
+ if (fabsf(cmd->sidemove ) > max) {
+ max = fabsf (cmd->sidemove);
+ }
+ if (fabsf(cmd->upmove) > max) {
+ max = fabsf(cmd->upmove);
+ }
+ if (!max) {
+ return 0;
+ }
+
+ total = sqrt (cmd->forwardmove * cmd->forwardmove
+ + cmd->sidemove * cmd->sidemove + cmd->upmove * cmd->upmove);
+ scale = speed * max / (127.0 * total);
+
+ return scale;
+}
+
+// Q3's pm_airaccelerate is 1.0; set to 0 here to disable by default
+cvar_t sv_q3airaccelerate = {"sv_q3airaccelerate", "0", CVAR_NONE};
+void CEV_Q3AirAccelerate (float wishspeed, vec3_t wishdir, usercmd_t *cmd)
+{
+ float addspeed, accelspeed, currentspeed, scale;
+
+ currentspeed = DotProduct (velocity, wishdir);
+ scale = CEV_Q3CmdScale (currentspeed, cmd);
+ addspeed = wishspeed - currentspeed;
+ if (addspeed <= 0)
+ return;
+ // Q3 applies scale to wishspeed but for whatever reason that
+ // doesn't feel right to me in Q1. So I'm applying it to the
+ // accel constant here. This is probably the wrong thing to do.
+ // CEV
+ accelspeed = sv_q3airaccelerate.value * scale;
+ accelspeed = accelspeed * host_frametime * wishspeed;
+ if (accelspeed > addspeed)
+ accelspeed = addspeed;
+ VectorMA (velocity, accelspeed, wishdir, velocity);
+}
+
void SV_AirAccelerate (float wishspeed, vec3_t wishveloc)
{
int i;
@@ -365,7 +425,15 @@
}
else
{ // not on ground, so little effect on velocity
- SV_AirAccelerate (wishspeed, wishvel);
+ // Q3 strafejumping when requesting both forward and side move
+ if ((sv_q3airaccelerate.value) && (fmove != 0) && (smove != 0))
+ {
+ CEV_Q3AirAccelerate (wishspeed, wishdir, &cmd);
+ }
+ else
+ {
+ SV_AirAccelerate (wishspeed, wishvel);
+ }
}
}
Return to the top of this page or return to the overview of this repo.
Log ironwail-0.7.0_dogmode-0.1.patch
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2023-10-13 | Import of an old patch to ironwail, no longer used | cev | +577 |
Return to the top of this page or return to the overview of this repo.