Misc tweaks and fixes.

This commit is contained in:
Shpoike 2024-03-01 08:07:58 +00:00
parent 84adac8434
commit 169c47b30d
12 changed files with 154 additions and 63 deletions

View file

@ -215,7 +215,7 @@ static int MSG_ReadSize16 (sizebuf_t *sb)
{ {
int solid = (((ssolid>>7) & 0x1F8) - 32+32768)<<16; /*up can be negative*/ int solid = (((ssolid>>7) & 0x1F8) - 32+32768)<<16; /*up can be negative*/
solid|= ((ssolid & 0x1F)<<3); solid|= ((ssolid & 0x1F)<<3);
solid|= ((ssolid & 0x3E0)<<10); solid|= ((ssolid & 0x3E0)<<6);
return solid; return solid;
} }
} }
@ -1426,10 +1426,6 @@ static void CL_ParseServerInfo (void)
str = MSG_ReadString (); str = MSG_ReadString ();
q_strlcpy (cl.levelname, str, sizeof(cl.levelname)); q_strlcpy (cl.levelname, str, sizeof(cl.levelname));
// seperate the printfs so the server message can have a color
Con_Printf ("\n%s\n", Con_Quakebar(40)); //johnfitz
Con_Printf ("%c%s\n", 2, str);
//johnfitz -- tell user which protocol this is //johnfitz -- tell user which protocol this is
if (developer.value) if (developer.value)
{ {
@ -1474,6 +1470,10 @@ static void CL_ParseServerInfo (void)
Con_Printf ("Using protocol %s", protname); Con_Printf ("Using protocol %s", protname);
Con_Printf ("\n"); Con_Printf ("\n");
// seperate the printfs so the server message can have a color
Con_Printf ("\n%s\n", Con_Quakebar(40)); //johnfitz
Con_Printf ("%c%s\n", 2, str);
// first we go through and touch all of the precache data that still // first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't // happens to be in the cache, so precaching something else doesn't
// needlessly purge it // needlessly purge it

View file

@ -932,6 +932,7 @@ static const arg_completion_type_t arg_completion_types[] =
{ "map ", &extralevels }, { "map ", &extralevels },
{ "changelevel ", &extralevels }, { "changelevel ", &extralevels },
{ "game ", &modlist }, { "game ", &modlist },
{ "gamedir ", &modlist },
{ "record ", &demolist }, { "record ", &demolist },
{ "playdemo ", &demolist }, { "playdemo ", &demolist },
{ "timedemo ", &demolist } { "timedemo ", &demolist }

View file

@ -763,7 +763,7 @@ void R_ShowBoundingBoxes (void)
int i; int i;
qcvm_t *oldvm; //in case we ever draw a scene from within csqc. qcvm_t *oldvm; //in case we ever draw a scene from within csqc.
if (!r_showbboxes.value || cl.maxclients > 1 || !r_drawentities.value || !sv.active) if (!r_showbboxes.value || cl.maxclients > 1 || !r_drawentities.value)
return; return;
glDisable (GL_DEPTH_TEST); glDisable (GL_DEPTH_TEST);
@ -773,38 +773,79 @@ void R_ShowBoundingBoxes (void)
glDisable (GL_CULL_FACE); glDisable (GL_CULL_FACE);
glColor3f (1,1,1); glColor3f (1,1,1);
oldvm = qcvm; if (r_showbboxes.value == 2 || !sv.active)
PR_SwitchQCVM(NULL);
PR_SwitchQCVM(&sv.qcvm);
for (i=1, ed=NEXT_EDICT(qcvm->edicts) ; i<qcvm->num_edicts ; i++, ed=NEXT_EDICT(ed))
{ {
if (ed == sv_player || ed->free) entity_t *e;
continue; //don't draw player's own bbox or freed edicts for (i = 0; i < cl_numvisedicts; i++)
{ //only the visible ents...
e = cl_visedicts[i];
// if (r_showbboxes.value != 2) if (e->eflags & EFLAGS_VIEWMODEL)
// if (!SV_VisibleToClient (sv_player, ed, sv.worldmodel)) continue; //no point, probably outside the level. misleading.
// continue; //don't draw if not in pvs if (e->netstate.solidsize == ES_SOLID_BSP && e->model)
{ // explicit hulls in the BSP model. also accept non-bmodels too, probably bugs but their boxes will at least be approximate.
if (ed->v.mins[0] == ed->v.maxs[0] && ed->v.mins[1] == ed->v.maxs[1] && ed->v.mins[2] == ed->v.maxs[2]) VectorAdd(e->origin, e->model->mins, mins);
{ VectorAdd(e->origin, e->model->maxs, maxs);
//point entity R_EmitWireBox (mins, maxs);
R_EmitWirePoint (ed->v.origin); }
} else if (e->netstate.solidsize == ES_SOLID_NOT)
else { //we're actually using collision data here, so there'll be quite a few such ents unfortunately. we can just draw them as points, shouldn't be ambigous as points are normally nonsolid anyway.
{ if (e->model && e->model->type == mod_brush)
//box entity { //bmodels are just painful with their origin so far from their geometry (because origins are irrelevant). lie and show the middle of the geometry. should probably skip this if its a rotator.
if ((ed->v.solid == SOLID_BSP || ed->v.solid == SOLID_EXT_BSPTRIGGER) && (ed->v.angles[0]||ed->v.angles[1]||ed->v.angles[2]) && pr_checkextension.value) VectorMA(e->origin, 0.5, e->model->mins, mins);
R_EmitWireBox (ed->v.absmin, ed->v.absmax); VectorMA(mins, 0.5, e->model->maxs, mins);
R_EmitWirePoint (mins);
}
else
R_EmitWirePoint (e->origin);
}
else else
{ {
VectorAdd (ed->v.mins, ed->v.origin, mins); maxs[0] = maxs[1] = e->netstate.solidsize & 255;
VectorAdd (ed->v.maxs, ed->v.origin, maxs); mins[0] = mins[1] = -maxs[0];
mins[2] = -(int)((e->netstate.solidsize >>8) & 255);
maxs[2] = (int)((e->netstate.solidsize>>16) & 65535) - 32768;
VectorAdd(e->origin, mins, mins);
VectorAdd(e->origin, maxs, maxs);
R_EmitWireBox (mins, maxs); R_EmitWireBox (mins, maxs);
} }
} }
} }
PR_SwitchQCVM(NULL); else
PR_SwitchQCVM(oldvm); {
oldvm = qcvm;
PR_SwitchQCVM(NULL);
PR_SwitchQCVM(&sv.qcvm);
for (i=1, ed=NEXT_EDICT(qcvm->edicts) ; i<qcvm->num_edicts ; i++, ed=NEXT_EDICT(ed))
{
if (ed == sv_player || ed->free)
continue; //don't draw player's own bbox or freed edicts
// if (r_showbboxes.value != 2)
// if (!SV_VisibleToClient (sv_player, ed, sv.worldmodel))
// continue; //don't draw if not in pvs
if (ed->v.mins[0] == ed->v.maxs[0] && ed->v.mins[1] == ed->v.maxs[1] && ed->v.mins[2] == ed->v.maxs[2])
{
//point entity
R_EmitWirePoint (ed->v.origin);
}
else
{
//box entity
if ((ed->v.solid == SOLID_BSP || ed->v.solid == SOLID_EXT_BSPTRIGGER) && (ed->v.angles[0]||ed->v.angles[1]||ed->v.angles[2]) && pr_checkextension.value)
R_EmitWireBox (ed->v.absmin, ed->v.absmax);
else
{
VectorAdd (ed->v.mins, ed->v.origin, mins);
VectorAdd (ed->v.maxs, ed->v.origin, maxs);
R_EmitWireBox (mins, maxs);
}
}
}
PR_SwitchQCVM(NULL);
PR_SwitchQCVM(oldvm);
}
glColor3f (1,1,1); glColor3f (1,1,1);
glEnable (GL_TEXTURE_2D); glEnable (GL_TEXTURE_2D);

View file

@ -1591,7 +1591,9 @@ void VID_Init (void)
int p, width, height, refreshrate, bpp; int p, width, height, refreshrate, bpp;
int display_width, display_height, display_refreshrate, display_bpp; int display_width, display_height, display_refreshrate, display_bpp;
qboolean fullscreen; qboolean fullscreen;
const char *read_vars[] = { "vid_fullscreen", cvar_t *v;
size_t i;
static const char *read_vars[] = { "vid_fullscreen",
"vid_width", "vid_width",
"vid_height", "vid_height",
"vid_refreshrate", "vid_refreshrate",
@ -1599,7 +1601,9 @@ void VID_Init (void)
"vid_vsync", "vid_vsync",
"vid_fsaa", "vid_fsaa",
"vid_desktopfullscreen", "vid_desktopfullscreen",
"vid_borderless"}; "vid_borderless",
"gl_load24bit", //including this here so we don't start up to the wrong setting.
};
#define num_readvars ( sizeof(read_vars)/sizeof(read_vars[0]) ) #define num_readvars ( sizeof(read_vars)/sizeof(read_vars[0]) )
Cvar_RegisterVariable (&vid_fullscreen); //johnfitz Cvar_RegisterVariable (&vid_fullscreen); //johnfitz
@ -1611,15 +1615,14 @@ void VID_Init (void)
Cvar_RegisterVariable (&vid_fsaa); //QuakeSpasm Cvar_RegisterVariable (&vid_fsaa); //QuakeSpasm
Cvar_RegisterVariable (&vid_desktopfullscreen); //QuakeSpasm Cvar_RegisterVariable (&vid_desktopfullscreen); //QuakeSpasm
Cvar_RegisterVariable (&vid_borderless); //QuakeSpasm Cvar_RegisterVariable (&vid_borderless); //QuakeSpasm
Cvar_SetCallback (&vid_fullscreen, VID_Changed_f); for (i = 0; i < num_readvars; i++)
Cvar_SetCallback (&vid_width, VID_Changed_f); {
Cvar_SetCallback (&vid_height, VID_Changed_f); v = Cvar_FindVar(read_vars[i]);
Cvar_SetCallback (&vid_refreshrate, VID_Changed_f); if (!v || v->callback)
Cvar_SetCallback (&vid_bpp, VID_Changed_f); Sys_Error("Cvar %s not found yet, or already has a callback", read_vars[i]);
Cvar_SetCallback (&vid_vsync, VID_Changed_f); else
Cvar_SetCallback (&vid_fsaa, VID_FSAA_f); Cvar_SetCallback (v, VID_Changed_f);
Cvar_SetCallback (&vid_desktopfullscreen, VID_Changed_f); }
Cvar_SetCallback (&vid_borderless, VID_Changed_f);
Cmd_AddCommand ("vid_unlock", VID_Unlock); //johnfitz Cmd_AddCommand ("vid_unlock", VID_Unlock); //johnfitz
Cmd_AddCommand ("vid_restart", VID_Restart); //johnfitz Cmd_AddCommand ("vid_restart", VID_Restart); //johnfitz

View file

@ -1434,11 +1434,11 @@ static void Host_Loadgame_f (void)
{ // parse an edict { // parse an edict
ent = EDICT_NUM(entnum); ent = EDICT_NUM(entnum);
if (entnum < qcvm->num_edicts) { if (entnum < qcvm->num_edicts) {
SV_UnlinkEdict(ent);
ent->free = false; ent->free = false;
memset (&ent->v, 0, qcvm->progs->entityfields * 4); memset (&ent->v, 0, qcvm->progs->entityfields * 4);
} }
else { else {
SV_UnlinkEdict(ent);
memset (ent, 0, qcvm->edict_size); memset (ent, 0, qcvm->edict_size);
ent->baseline = nullentitystate; ent->baseline = nullentitystate;
} }

View file

@ -91,5 +91,8 @@ char *PL_GetClipboardData (void)
void PL_ErrorDialog (const char *errorMsg) void PL_ErrorDialog (const char *errorMsg)
{ {
#if SDL_MAJOR_VERSION >= 2
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Sys_Error", errorMsg, NULL);
#endif
} }

View file

@ -976,6 +976,8 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
SV_Precache_Model(PR_GetString(ED_NewString(com_token))); SV_Precache_Model(PR_GetString(ED_NewString(com_token)));
else if (!strcmp(keyname, "_precache_sound") && sv.state == ss_loading) else if (!strcmp(keyname, "_precache_sound") && sv.state == ss_loading)
SV_Precache_Sound(PR_GetString(ED_NewString(com_token))); SV_Precache_Sound(PR_GetString(ED_NewString(com_token)));
else if (!strcmp(keyname, "_skyroom") && ent == sv.qcvm.edicts)
SV_SetupSkyRoom(com_token);
} }
//spike //spike
continue; continue;
@ -1194,6 +1196,7 @@ static void PR_MergeEngineFieldDefs (void)
{"alpha", ev_float}, //just because we can (though its already handled in a weird hacky way) {"alpha", ev_float}, //just because we can (though its already handled in a weird hacky way)
{"scale", ev_float}, //hurrah for being able to rescale entities. {"scale", ev_float}, //hurrah for being able to rescale entities.
{"emiteffectnum", ev_float}, //constantly emitting particles, even without moving. {"emiteffectnum", ev_float}, //constantly emitting particles, even without moving.
{"pvsflags", ev_float}, //extra controls to enable/disable pvs checks on ents.
{"traileffectnum", ev_float}, //custom effect for trails {"traileffectnum", ev_float}, //custom effect for trails
//{"glow_size", ev_float}, //deprecated particle trail rubbish //{"glow_size", ev_float}, //deprecated particle trail rubbish
//{"glow_color", ev_float}, //deprecated particle trail rubbish //{"glow_color", ev_float}, //deprecated particle trail rubbish

View file

@ -159,7 +159,7 @@ eval_t *GetEdictFieldValue(edict_t *ed, int fldofs); //handles invalid offsets w
int ED_FindFieldOffset (const char *name); int ED_FindFieldOffset (const char *name);
#define GetEdictFieldValid(fld) (qcvm->extfields.fld>=0) #define GetEdictFieldValid(fld) (qcvm->extfields.fld>=0)
#define GetEdictFieldEval(ed,fld) ((eval_t *)((char *)&ed->v + qcvm->extfields.fld*4)) //caller must validate the field first #define GetEdictFieldEval(ed,fld) ((eval_t *)((float *)&ed->v + qcvm->extfields.fld)) //caller must validate the field first
//from pr_cmds, no longer static so that pr_ext can use them. //from pr_cmds, no longer static so that pr_ext can use them.
sizebuf_t *WriteDest (void); sizebuf_t *WriteDest (void);
@ -324,6 +324,7 @@ struct pr_extfields_s
QCEXTFIELD(viewzoom, ".float") /*float*/ \ QCEXTFIELD(viewzoom, ".float") /*float*/ \
QCEXTFIELD(SendEntity, ".float(entity to, float changedflags)") /*function*/ \ QCEXTFIELD(SendEntity, ".float(entity to, float changedflags)") /*function*/ \
QCEXTFIELD(SendFlags, ".float") /*float. :( */ \ QCEXTFIELD(SendFlags, ".float") /*float. :( */ \
QCEXTFIELD(pvsflags, ".float") /*float*/ \
//end of list //end of list
#define QCEXTFIELD(n,t) int n; #define QCEXTFIELD(n,t) int n;

View file

@ -643,8 +643,7 @@ static void GLWater_CreateShaders (void)
//The following 4 lines SHOULD match the software renderer, except normalised coords rather than snapped texels //The following 4 lines SHOULD match the software renderer, except normalised coords rather than snapped texels
"#define M_PI 3.14159\n" "#define M_PI 3.14159\n"
"#define TIMEBIAS (((WarpTime*20.0)*M_PI*2.0)/128.0)\n" "#define TIMEBIAS (((WarpTime*20.0)*M_PI*2.0)/128.0)\n"
" ntc.s += 0.125 + sin(tc_tex.t*M_PI + TIMEBIAS)*0.125;\n" " ntc += 0.125 + sin(tc_tex.ts*M_PI + TIMEBIAS)*0.125;\n"
" ntc.t += 0.125 + sin(tc_tex.s*M_PI + TIMEBIAS)*0.125;\n"
" vec4 result = texture2D(Tex, ntc.st);\n" " vec4 result = texture2D(Tex, ntc.st);\n"
"#ifdef LIT\n" "#ifdef LIT\n"
" result *= texture2D(LMTex, tc_lm.xy);\n" " result *= texture2D(LMTex, tc_lm.xy);\n"

View file

@ -99,6 +99,9 @@ typedef struct
eval_t *ptr; eval_t *ptr;
} customstats[MAX_CL_STATS*2]; //strings or numeric... } customstats[MAX_CL_STATS*2]; //strings or numeric...
size_t numcustomstats; size_t numcustomstats;
qboolean skyroom_pos_known;
vec4_t skyroom_pos;
} server_t; } server_t;
@ -289,6 +292,13 @@ typedef struct client_s
#define MSG_EXT_MULTICAST 4 // temporary buffer that can be splurged more reliably / with more control. #define MSG_EXT_MULTICAST 4 // temporary buffer that can be splurged more reliably / with more control.
#define MSG_EXT_ENTITY 5 // for csqc networking. we don't actually support this. I'm just defining it for completeness. #define MSG_EXT_ENTITY 5 // for csqc networking. we don't actually support this. I'm just defining it for completeness.
#define PVSF_NORMALPVS 0x0
#define PVSF_NOTRACECHECK 0x1
#define PVSF_USEPHS 0x2
#define PVSF_IGNOREPVS 0x3
#define PVSF_MODE_MASK 0x3
#define PVSF_NOREMOVE 0x80
//============================================================================ //============================================================================
extern cvar_t teamplay; extern cvar_t teamplay;
@ -349,5 +359,7 @@ void SV_RunClients (void);
void SV_SaveSpawnparms (); void SV_SaveSpawnparms ();
void SV_SpawnServer (const char *server); void SV_SpawnServer (const char *server);
void SV_SetupSkyRoom(char *value);
#endif /* _QUAKE_SERVER_H */ #endif /* _QUAKE_SERVER_H */

View file

@ -1186,6 +1186,7 @@ void SV_BuildEntityState(client_t *client, edict_t *ent, entity_state_t *state)
} }
byte *SV_FatPVS (vec3_t org, qmodel_t *worldmodel); byte *SV_FatPVS (vec3_t org, qmodel_t *worldmodel);
static void SV_AddToFatPVS (vec3_t org, mnode_t *node, qmodel_t *worldmodel);
static void SVFTE_BuildSnapshotForClient (client_t *client) static void SVFTE_BuildSnapshotForClient (client_t *client)
{ {
unsigned int e, i; unsigned int e, i;
@ -1208,6 +1209,11 @@ static void SVFTE_BuildSnapshotForClient (client_t *client)
// find the client's PVS // find the client's PVS
VectorAdd (clent->v.origin, clent->v.view_ofs, org); VectorAdd (clent->v.origin, clent->v.view_ofs, org);
pvs = SV_FatPVS (org, qcvm->worldmodel); pvs = SV_FatPVS (org, qcvm->worldmodel);
if (sv.skyroom_pos_known)
{
VectorMA(sv.skyroom_pos, sv.skyroom_pos[3], org, org);
SV_AddToFatPVS (org, qcvm->worldmodel->nodes, qcvm->worldmodel); //spike -- allow _skyroom term to punch a hole through the server's pvs. FIXME: no paralax considered here.
}
if (maxentities > (unsigned int)qcvm->num_edicts) if (maxentities > (unsigned int)qcvm->num_edicts)
maxentities = (unsigned int)qcvm->num_edicts; maxentities = (unsigned int)qcvm->num_edicts;
@ -1237,7 +1243,7 @@ static void SVFTE_BuildSnapshotForClient (client_t *client)
} }
eflags = 0; eflags = 0;
emiteffect = GetEdictFieldValue(ent, qcvm->extfields.emiteffectnum)->_float; emiteffect = GetEdictFieldEval(ent, emiteffectnum)->_float;
iscsqc = cancsqc && GetEdictFieldEval(ent, SendEntity)->function; iscsqc = cancsqc && GetEdictFieldEval(ent, SendEntity)->function;
if (ent != clent) // clent is ALLWAYS sent if (ent != clent) // clent is ALLWAYS sent
{ {
@ -1245,7 +1251,7 @@ static void SVFTE_BuildSnapshotForClient (client_t *client)
if ((!ent->v.modelindex || !PR_GetString(ent->v.model)[0]) && !emiteffect && !iscsqc) if ((!ent->v.modelindex || !PR_GetString(ent->v.model)[0]) && !emiteffect && !iscsqc)
{ {
invisible: invisible:
if (client->pendingcsqcentities_bits[e] /*&& !((int)GetEdictFieldEval(ent, pvsflags)->_float & PVFS_NOREMOVE)*/) if (client->pendingcsqcentities_bits[e] && !((int)GetEdictFieldEval(ent, pvsflags)->_float & PVSF_NOREMOVE))
client->pendingcsqcentities_bits[e] |= SENDFLAG_REMOVE; client->pendingcsqcentities_bits[e] |= SENDFLAG_REMOVE;
continue; continue;
} }
@ -1255,28 +1261,27 @@ invisible:
eflags |= EFLAGS_VIEWMODEL; eflags |= EFLAGS_VIEWMODEL;
else if (val && val->edict) else if (val && val->edict)
goto invisible; goto invisible;
else else switch((int)GetEdictFieldEval(ent, pvsflags)->_float&PVSF_MODE_MASK)
{ {
case PVSF_NOTRACECHECK: //we don't do trace checks anyway, oh well.
case PVSF_NORMALPVS:
//attached entities should use the pvs of the parent rather than the child (because the child will typically be bugging out around '0 0 0', so won't be useful) //attached entities should use the pvs of the parent rather than the child (because the child will typically be bugging out around '0 0 0', so won't be useful)
parent = ent; parent = ent;
while ((val = GetEdictFieldValue(parent, qcvm->extfields.tag_entity)) && val->edict) while (GetEdictFieldEval(parent, tag_entity)->edict)
parent = PROG_TO_EDICT(val->edict); parent = PROG_TO_EDICT(GetEdictFieldEval(parent, tag_entity)->edict);
if (parent->num_leafs) if (parent->num_leafs < MAX_ENT_LEAFS) //assumed to be in all leafs, if there's an overflow.
{ {
// ignore if not touching a PV leaf // ignore if not touching a PV leaf
for (i=0 ; i < parent->num_leafs ; i++) for (i=0 ; i < parent->num_leafs ; i++)
if (pvs[parent->leafnums[i] >> 3] & (1 << (parent->leafnums[i]&7) )) if (pvs[parent->leafnums[i] >> 3] & (1 << (parent->leafnums[i]&7) ))
break; break;
if (i == parent->num_leafs)
// ericw -- added ent->num_leafs < MAX_ENT_LEAFS condition.
//
// if ent->num_leafs == MAX_ENT_LEAFS, the ent is visible from too many leafs
// for us to say whether it's in the PVS, so don't try to vis cull it.
// this commonly happens with rotators, because they often have huge bboxes
// spanning the entire map, or really tall lifts, etc.
if (i == parent->num_leafs && parent->num_leafs < MAX_ENT_LEAFS)
goto invisible; // not visible goto invisible; // not visible
} }
break;
case PVSF_USEPHS: //we don't support PHS. expand it wider than asked
case PVSF_IGNOREPVS:
break;
} }
} }
@ -2111,8 +2116,8 @@ retry:
MSG_WriteByte (&client->message, svc_setview); MSG_WriteByte (&client->message, svc_setview);
MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict));
MSG_WriteByte (&host_client->message, svc_signonnum); MSG_WriteByte (&client->message, svc_signonnum);
MSG_WriteByte (&host_client->message, 1); MSG_WriteByte (&client->message, 1);
client->sendsignon = PRESPAWN_FLUSH; client->sendsignon = PRESPAWN_FLUSH;
@ -2367,7 +2372,24 @@ static int fatbytes;
static byte *fatpvs; static byte *fatpvs;
static int fatpvs_capacity; static int fatpvs_capacity;
void SV_AddToFatPVS (vec3_t org, mnode_t *node, qmodel_t *worldmodel) //johnfitz -- added worldmodel as a parameter
void SV_SetupSkyRoom(char *value)
{
sv.skyroom_pos_known = true;
sv.skyroom_pos[0] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
sv.skyroom_pos[1] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
sv.skyroom_pos[2] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
sv.skyroom_pos[3] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
// sv.skyroom_orientation[3] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
// sv.skyroom_orientation[0] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
// sv.skyroom_orientation[1] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
// sv.skyroom_orientation[2] = strtod(value, &value); while(*value == ' ' || *value == '\t') value++;
}
static void SV_AddToFatPVS (vec3_t org, mnode_t *node, qmodel_t *worldmodel) //johnfitz -- added worldmodel as a parameter
{ {
int i; int i;
byte *pvs; byte *pvs;
@ -2481,6 +2503,11 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
// find the client's PVS // find the client's PVS
VectorAdd (clent->v.origin, clent->v.view_ofs, org); VectorAdd (clent->v.origin, clent->v.view_ofs, org);
pvs = SV_FatPVS (org, qcvm->worldmodel); pvs = SV_FatPVS (org, qcvm->worldmodel);
if (sv.skyroom_pos_known)
{
VectorMA(sv.skyroom_pos, sv.skyroom_pos[3], org, org);
SV_AddToFatPVS (org, qcvm->worldmodel->nodes, qcvm->worldmodel); //spike -- allow _skyroom term to punch a hole through the server's pvs. FIXME: no paralax considered here.
}
// send over all entities (excpet the client) that touch the pvs // send over all entities (excpet the client) that touch the pvs
ent = NEXT_EDICT(qcvm->edicts); ent = NEXT_EDICT(qcvm->edicts);

View file

@ -148,7 +148,8 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
if (!model || model->type != mod_brush) if (!model || model->type != mod_brush)
{ {
Con_Warning ("SOLID_BSP with a non bsp model (%s at %f %f %f)\n", Con_Warning ("SOLID_BSP%s with a non bsp model (%s at %f %f %f)\n",
(ent->v.solid == SOLID_EXT_BSPTRIGGER)?"TRIGGER":"",
PR_GetString(ent->v.classname), ent->v.origin[0], ent->v.origin[1], ent->v.origin[2]); PR_GetString(ent->v.classname), ent->v.origin[0], ent->v.origin[1], ent->v.origin[2]);
goto nohitmeshsupport; goto nohitmeshsupport;
} }