Only enable DP_SV_ROTATINGBMODEL when its actually enabled. This is to resolve issues in multiple maps/mods so they behave like they do with the inferior engines they were tested against. Warnings will be printed for any maps or mods that appear to be trying to use it without checking for it first. Resolves https://github.com/Shpoike/Quakespasm/issues/75

This commit is contained in:
Shpoike 2022-08-23 10:10:17 +01:00
parent b947fab72e
commit b3bec67cb1
5 changed files with 80 additions and 54 deletions

View file

@ -802,6 +802,7 @@ static void CL_LoadCSProgs(void)
qcvm->extglobals.servercommandframe = NULL;
}
qcvm->rotatingbmodel = true; //csqc always assumes this is enabled.
qcvm->GetModel = PR_CSQC_GetModel;
//set a few globals, if they exist
if (qcvm->extglobals.maxclients)

View file

@ -7624,8 +7624,8 @@ qboolean PR_CanPrecacheAnyTime(unsigned int prot, unsigned int pext1, unsigned i
}
qboolean PR_CanPushRotate(unsigned int prot, unsigned int pext1, unsigned int pext2)
{
qcvm->brokenpushrotate = false;
return !qcvm->brokenpushrotate;
qcvm->rotatingbmodel = true;
return qcvm->rotatingbmodel;
}
qboolean PR_Can_EF_Red_Blue(unsigned int prot, unsigned int pext1, unsigned int pext2)
{
@ -8067,13 +8067,11 @@ void PR_EnableExtensions(ddef_t *pr_globaldefs)
{
qcvm->builtins[99] = PF_checkextension;
qcvm->brokenpushrotate = true;
qcvm->brokenbouncemissile = true;
qcvm->brokeneffects = true;
}
if (!pr_checkextension.value && qcvm == &sv.qcvm)
{
qcvm->brokenpushrotate = true;
Con_DPrintf("not enabling qc extensions\n");
return;
}

View file

@ -375,10 +375,12 @@ struct qcvm_s
void *cursorhandle; //video code.
qboolean nogameaccess; //simplecsqc isn't allowed to poke properties of the actual game (to prevent cheats when there's no restrictions on what it can access)
qboolean brokenbouncemissile; //2021 rerelease redefined it, breaking any mod that depends on it.
qboolean brokenpushrotate; //2021 rerelease fucks over avelocity on movetype_push.
qboolean rotatingbmodel; //2021 rerelease fucks over avelocity on movetype_push. broken by lots of other defective maps too.
qboolean brokeneffects; //2021 rerelease redefined EF_RED and EF_BLUE.
qboolean precacheanytime; //mod queried for support. this is used to spam warnings to anyone that doesn't bother checking for it first. this annoyance is to reduce compat issues.
qboolean warned_rotatingbmodel; //to enable warnings if the map looks like it this extension should have been enabled.
//was static inside pr_edict
char *strings;
int stringssize;

View file

@ -682,13 +682,21 @@ void SV_PushMove (edict_t *pusher, float movetime)
int mark; //johnfitz
float solid_backup;
if ((pusher->v.avelocity[0] || pusher->v.avelocity[1] || pusher->v.avelocity[2]) && !qcvm->brokenpushrotate)
{ //spike -- added this block for proper rotations
mark = Hunk_LowMark ();
if (SV_PushMoveAngles (pusher, movetime))
pusher->v.ltime += movetime;
Hunk_FreeToLowMark (mark);
return;
if ((pusher->v.avelocity[0] || pusher->v.avelocity[1] || pusher->v.avelocity[2]))
{
if (qcvm->rotatingbmodel)
{ //spike -- added this block for proper rotations
mark = Hunk_LowMark ();
if (SV_PushMoveAngles (pusher, movetime))
pusher->v.ltime += movetime;
Hunk_FreeToLowMark (mark);
return;
}
if (!qcvm->warned_rotatingbmodel)
{
Con_Warning("MOVETYPE_PUSH(\"%s\") has avelocity, but DP_SV_ROTATINGBMODEL is not enabled\n", PR_GetString(pusher->v.classname));
qcvm->warned_rotatingbmodel = true;
}
}
if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])

View file

@ -439,29 +439,34 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
return;
// set the abs box
if ((ent->v.solid == SOLID_BSP||ent->v.solid == SOLID_EXT_BSPTRIGGER) && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) && !qcvm->brokenpushrotate)
{ // expand for rotation the lame way. hopefully there's an origin brush in there.
int i;
float v1,v2;
vec3_t max;
//q2 method
for (i=0 ; i<3 ; i++)
{
v1 = fabs(ent->v.mins[i]);
v2 = fabs(ent->v.maxs[i]);
max[i] = q_max(v1,v2);
}
v1 = sqrt(DotProduct(max,max));
for (i=0 ; i<3 ; i++)
{
ent->v.absmin[i] = ent->v.origin[i] - v1;
ent->v.absmax[i] = ent->v.origin[i] + v1;
}
}
else
VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
if ((ent->v.solid == SOLID_BSP||ent->v.solid == SOLID_EXT_BSPTRIGGER) && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
if (qcvm->rotatingbmodel)
{ // expand for rotation the lame way. hopefully there's an origin brush in there.
int i;
float v1,v2;
vec3_t max;
//q2 method
for (i=0 ; i<3 ; i++)
{
v1 = fabs(ent->v.mins[i]);
v2 = fabs(ent->v.maxs[i]);
max[i] = q_max(v1,v2);
}
v1 = sqrt(DotProduct(max,max));
for (i=0 ; i<3 ; i++)
{
ent->v.absmin[i] = ent->v.origin[i] - v1;
ent->v.absmax[i] = ent->v.origin[i] + v1;
}
}
else if (!qcvm->warned_rotatingbmodel)
{
Con_Warning("%s(\"%s\") has angles set, but DP_SV_ROTATINGBMODEL is not enabled\n", (ent->v.solid == SOLID_EXT_BSPTRIGGER)?"SOLID_BSPTRIGGER":"SOLID_BSP", PR_GetString(ent->v.classname));
qcvm->warned_rotatingbmodel = true;
}
}
//
@ -971,27 +976,39 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
VectorSubtract (end, offset, end_l);
// trace a line through the apropriate clipping hull
if ((ent->v.solid == SOLID_BSP || ent->v.solid == SOLID_EXT_BSPTRIGGER) && (ent->v.angles[0]||ent->v.angles[1]||ent->v.angles[2]) && !qcvm->brokenpushrotate && qcvm->edicts != ent) //don't rotate the world entity's collisions (its not networked, and some maps are buggy, resulting in screwed collisions)
if ((ent->v.solid == SOLID_BSP || ent->v.solid == SOLID_EXT_BSPTRIGGER) && (ent->v.angles[0]||ent->v.angles[1]||ent->v.angles[2]) && qcvm->edicts != ent) //don't rotate the world entity's collisions (its not networked, and some maps are buggy, resulting in screwed collisions)
{
if (qcvm->rotatingbmodel)
{
#define DotProductTranspose(v,m,a) ((v)[0]*(m)[0][a] + (v)[1]*(m)[1][a] + (v)[2]*(m)[2][a])
vec3_t axis[3], start_r, end_r, tmp;
AngleVectors(ent->v.angles, axis[0], axis[1], axis[2]);
VectorInverse(axis[1]);
start_r[0] = DotProduct(start_l, axis[0]);
start_r[1] = DotProduct(start_l, axis[1]);
start_r[2] = DotProduct(start_l, axis[2]);
end_r[0] = DotProduct(end_l, axis[0]);
end_r[1] = DotProduct(end_l, axis[1]);
end_r[2] = DotProduct(end_l, axis[2]);
SV_RecursiveHullCheck (hull, start_r, end_r, &trace, hitcontents);
VectorCopy(trace.endpos, tmp);
trace.endpos[0] = DotProductTranspose(tmp,axis,0);
trace.endpos[1] = DotProductTranspose(tmp,axis,1);
trace.endpos[2] = DotProductTranspose(tmp,axis,2);
VectorCopy(trace.plane.normal, tmp);
trace.plane.normal[0] = DotProductTranspose(tmp,axis,0);
trace.plane.normal[1] = DotProductTranspose(tmp,axis,1);
trace.plane.normal[2] = DotProductTranspose(tmp,axis,2);
vec3_t axis[3], start_r, end_r, tmp;
AngleVectors(ent->v.angles, axis[0], axis[1], axis[2]);
VectorInverse(axis[1]);
start_r[0] = DotProduct(start_l, axis[0]);
start_r[1] = DotProduct(start_l, axis[1]);
start_r[2] = DotProduct(start_l, axis[2]);
end_r[0] = DotProduct(end_l, axis[0]);
end_r[1] = DotProduct(end_l, axis[1]);
end_r[2] = DotProduct(end_l, axis[2]);
SV_RecursiveHullCheck (hull, start_r, end_r, &trace, hitcontents);
VectorCopy(trace.endpos, tmp);
trace.endpos[0] = DotProductTranspose(tmp,axis,0);
trace.endpos[1] = DotProductTranspose(tmp,axis,1);
trace.endpos[2] = DotProductTranspose(tmp,axis,2);
VectorCopy(trace.plane.normal, tmp);
trace.plane.normal[0] = DotProductTranspose(tmp,axis,0);
trace.plane.normal[1] = DotProductTranspose(tmp,axis,1);
trace.plane.normal[2] = DotProductTranspose(tmp,axis,2);
}
else
{
if (!qcvm->warned_rotatingbmodel)
{
Con_Warning("%s(\"%s\") has angles set, but DP_SV_ROTATINGBMODEL is not enabled\n", (ent->v.solid == SOLID_EXT_BSPTRIGGER)?"SOLID_BSPTRIGGER":"SOLID_BSP", PR_GetString(ent->v.classname));
qcvm->warned_rotatingbmodel = true;
}
SV_RecursiveHullCheck (hull, start_l, end_l, &trace, hitcontents);
}
}
else
SV_RecursiveHullCheck (hull, start_l, end_l, &trace, hitcontents);
@ -1206,7 +1223,7 @@ static void World_ClipToNetwork ( moveclip_t *clip )
VectorSubtract (clip->end, offset, end_l);
// trace a line through the apropriate clipping hull
if (touch->netstate.solidsize == ES_SOLID_BSP && (touch->angles[0]||touch->angles[1]||touch->angles[2]) && !qcvm->brokenpushrotate) //don't rotate the world entity's collisions (its not networked, and some maps are buggy, resulting in screwed collisions)
if (touch->netstate.solidsize == ES_SOLID_BSP && (touch->angles[0]||touch->angles[1]||touch->angles[2]) && qcvm->rotatingbmodel) //don't rotate the world entity's collisions (its not networked, and some maps are buggy, resulting in screwed collisions)
{
#define DotProductTranspose(v,m,a) ((v)[0]*(m)[0][a] + (v)[1]*(m)[1][a] + (v)[2]*(m)[2][a])
vec3_t axis[3], start_r, end_r, tmp;