reworked penalties flags. now a single bitfield instead of separate booleans. added 'blind' penalty.

tweaked portals again. no longer wrongly impacting against the portal's front/back planes, even with speed.
reworked PEXT_LIGHTSTYLECOL, now uses a vector instead of a channel mask.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4699 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-06-25 03:53:11 +00:00
parent 957e9b494c
commit ceb32ec494
27 changed files with 378 additions and 370 deletions

View File

@ -1402,11 +1402,14 @@ void CL_Record_f (void)
continue;
#ifdef PEXT_LIGHTSTYLECOL
if ((cls.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && cl_lightstyle[i].colour!=7 && *cl_lightstyle[i].map)
if ((cls.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (cl_lightstyle[i].colours[0]!=1||cl_lightstyle[i].colours[1]!=1||cl_lightstyle[i].colours[2]!=1) && *cl_lightstyle[i].map)
{
MSG_WriteByte (&buf, svcfte_lightstylecol);
MSG_WriteByte (&buf, (unsigned char)i);
MSG_WriteByte (&buf, cl_lightstyle[i].colour);
MSG_WriteByte (&buf, 0x87);
MSG_WriteShort (&buf, cl_lightstyle[i].colours[0]*1024);
MSG_WriteShort (&buf, cl_lightstyle[i].colours[1]*1024);
MSG_WriteShort (&buf, cl_lightstyle[i].colours[2]*1024);
MSG_WriteString (&buf, cl_lightstyle[i].map);
}
else

View File

@ -1336,7 +1336,7 @@ void CL_ClearState (void)
// memset (cl_dlights, 0, sizeof(cl_dlights));
memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
for (i = 0; i < MAX_LIGHTSTYLES; i++)
cl_lightstyle[i].colour = 7;
R_UpdateLightStyle(i, NULL, 1, 1, 1);
rtlights_first = rtlights_max = RTL_FIRST;

View File

@ -3765,15 +3765,12 @@ void CLQ2_ParseConfigString (void)
}
else if (i >= Q2CS_LIGHTS && i < Q2CS_LIGHTS+Q2MAX_LIGHTSTYLES)
{
cl_lightstyle[i - Q2CS_LIGHTS].colour = 7; //white
Q_strncpyz (cl_lightstyle[i - Q2CS_LIGHTS].map, s, sizeof(cl_lightstyle[i-Q2CS_LIGHTS].map));
cl_lightstyle[i - Q2CS_LIGHTS].length = Q_strlen(cl_lightstyle[i - Q2CS_LIGHTS].map);
R_UpdateLightStyle(i, s, 1, 1, 1);
}
else if (i == Q2CS_CDTRACK)
{
// if (cl.refresh_prepped)
Media_NumberedTrack (atoi(s), atoi(s));
Media_BackgroundTrack (s, NULL);
}
else if (i >= Q2CS_MODELS && i < Q2CS_MODELS+Q2MAX_MODELS)
{
@ -5928,9 +5925,7 @@ void CLQW_ParseServerMessage (void)
i = MSG_ReadByte ();
if (i >= MAX_LIGHTSTYLES)
Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES");
cl_lightstyle[i].colour = 7; //white
Q_strncpyz (cl_lightstyle[i].map, MSG_ReadString(), sizeof(cl_lightstyle[i].map));
cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
R_UpdateLightStyle(i, MSG_ReadString(), 1, 1, 1);
break;
#ifdef PEXT_LIGHTSTYLECOL
case svcfte_lightstylecol:
@ -5939,9 +5934,24 @@ void CLQW_ParseServerMessage (void)
i = MSG_ReadByte ();
if (i >= MAX_LIGHTSTYLES)
Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES");
cl_lightstyle[i].colour = MSG_ReadByte();
Q_strncpyz (cl_lightstyle[i].map, MSG_ReadString(), sizeof(cl_lightstyle[i].map));
cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
{
int bits;
vec3_t rgb;
bits = MSG_ReadByte();
if (bits & 0x80)
{
rgb[0] = MSG_ReadShort()/1024.0;
rgb[1] = MSG_ReadShort()/1024.0;
rgb[1] = MSG_ReadShort()/1024.0;
}
else
{
rgb[0] = (bits&1)?1:0;
rgb[1] = (bits&2)?1:0;
rgb[2] = (bits&4)?1:0;
}
R_UpdateLightStyle(i, MSG_ReadString(), rgb[0], rgb[1], rgb[2]);
}
break;
#endif
@ -6915,9 +6925,7 @@ void CLNQ_ParseServerMessage (void)
MSG_ReadString();
break;
}
cl_lightstyle[i].colour = 7; //white
Q_strncpyz (cl_lightstyle[i].map, MSG_ReadString(), sizeof(cl_lightstyle[i].map));
cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
R_UpdateLightStyle(i, MSG_ReadString(), 1, 1, 1);
break;
case svcnq_updatestatlong:

View File

@ -404,7 +404,11 @@ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode)
void SCR_CPrint_f(void)
{
SCR_CenterPrint(0, Cmd_Args(), true);
char *s = Cmd_Args();
if (Cmd_Argc() == 2)
SCR_CenterPrint(0, Cmd_Argv(1), true);
else
SCR_CenterPrint(0, Cmd_Args(), true);
}
void SCR_EraseCenterString (void)

View File

@ -296,7 +296,8 @@ typedef struct
{
int length;
char map[MAX_STYLESTRING];
int colour;
vec3_t colours;
int colourkey;
} lightstyle_t;

View File

@ -3010,16 +3010,17 @@ static void QCBUILTIN PF_cs_lightstyle (pubprogfuncs_t *prinst, struct globalvar
{
int stnum = G_FLOAT(OFS_PARM0);
const char *str = PR_GetStringOfs(prinst, OFS_PARM1);
int colourflags = 7;
vec3_t rgb = {1,1,1};
if (prinst->callargc >= 3) //fte is a quakeworld engine
VectorCopy(G_VECTOR(OFS_PARM2), rgb);
if ((unsigned)stnum >= MAX_LIGHTSTYLES)
{
Con_Printf ("PF_cs_lightstyle: stnum > MAX_LIGHTSTYLES");
return;
}
cl_lightstyle[stnum].colour = colourflags;
Q_strncpyz (cl_lightstyle[stnum].map, str, sizeof(cl_lightstyle[stnum].map));
cl_lightstyle[stnum].length = Q_strlen(cl_lightstyle[stnum].map);
R_UpdateLightStyle(stnum, str, rgb[0],rgb[1],rgb[2]);
}
//entity(string field, float match) findchainflags = #450

View File

@ -982,11 +982,11 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour;
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
if (scale)
{
if (cl_lightstyle[surf->styles[maps]].colour == 7) //hopefully a faster alternative.
if (cl_lightstyle[surf->styles[maps]].colours[0] == 1 && cl_lightstyle[surf->styles[maps]].colours[1] == 1 && cl_lightstyle[surf->styles[maps]].colours[2] == 1) //hopefully a faster alternative.
{
bl = blocklights;
for (i=0 ; i<size*3 ; i++)
@ -996,15 +996,24 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
}
else
{
if (cl_lightstyle[surf->styles[maps]].colour & 1)
if (cl_lightstyle[surf->styles[maps]].colours[0])
{
scale = d_lightstylevalue[surf->styles[maps]] * cl_lightstyle[surf->styles[maps]].colours[0];
for (i=0 ; i<size ; i++)
blocklights[i+0] += lightmap[i*3+0] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 2)
}
if (cl_lightstyle[surf->styles[maps]].colours[1])
{
scale = d_lightstylevalue[surf->styles[maps]] * cl_lightstyle[surf->styles[maps]].colours[1];
for (i=0 ; i<size ; i++)
blocklights[i+1] += lightmap[i*3+1] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 4)
}
if (cl_lightstyle[surf->styles[maps]].colours[2])
{
scale = d_lightstylevalue[surf->styles[maps]] * cl_lightstyle[surf->styles[maps]].colours[2];
for (i=0 ; i<size ; i++)
blocklights[i+2] += lightmap[i*3+2] * scale;
}
lightmap += size*3; // skip to next lightmap
}
}
@ -1018,9 +1027,9 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour;
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
if (cl_lightstyle[surf->styles[maps]].colour == 7) //hopefully a faster alternative.
if (cl_lightstyle[surf->styles[maps]].colours[0] == 1 && cl_lightstyle[surf->styles[maps]].colours[1] == 1 && cl_lightstyle[surf->styles[maps]].colours[2] == 1) //hopefully a faster alternative.
{
bl = blocklights;
for (i=0 ; i<size ; i++)
@ -1033,15 +1042,24 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
}
else
{
if (cl_lightstyle[surf->styles[maps]].colour & 1)
if (cl_lightstyle[surf->styles[maps]].colours[0])
{
scale = d_lightstylevalue[surf->styles[maps]] * cl_lightstyle[surf->styles[maps]].colours[0];
for (i=0, bl = blocklights; i<size; i++, bl+=3)
*bl += lightmap[i] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 2)
}
if (cl_lightstyle[surf->styles[maps]].colours[1])
{
scale = d_lightstylevalue[surf->styles[maps]] * cl_lightstyle[surf->styles[maps]].colours[1];
for (i=0, bl = blocklights+1; i<size; i++, bl+=3)
*bl += lightmap[i] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 4)
}
if (cl_lightstyle[surf->styles[maps]].colours[2])
{
scale = d_lightstylevalue[surf->styles[maps]] * cl_lightstyle[surf->styles[maps]].colours[2];
for (i=0, bl = blocklights+2; i<size; i++, bl+=3)
*bl += lightmap[i] * scale;
}
lightmap += size; // skip to next lightmap
}
}
@ -1098,7 +1116,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
blocklights[i] = 255*256;
}
surf->cached_light[0] = d_lightstylevalue[0];
surf->cached_colour[0] = cl_lightstyle[0].colour;
surf->cached_colour[0] = cl_lightstyle[0].colourkey;
}
else if (r_fullbright.ival)
{
@ -1120,7 +1138,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
{
scale = d_lightstylevalue[surf->styles[maps]]/3;
surf->cached_light[maps] = scale; // 8.8 fraction
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour;
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
for (i=0 ; i<size ; i++)
blocklights[i] += (lightmap[i*3]+lightmap[i*3+1]+lightmap[i*3+2]) * scale;
lightmap += size*3; // skip to next lightmap
@ -1132,7 +1150,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour;
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
for (i=0 ; i<size ; i++)
blocklights[i] += lightmap[i] * scale;
lightmap += size; // skip to next lightmap
@ -1187,7 +1205,7 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != 255 ;
maps++)
if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]
|| cl_lightstyle[fa->styles[maps]].colour != fa->cached_colour[maps])
|| cl_lightstyle[fa->styles[maps]].colourkey != fa->cached_colour[maps])
goto dynamic;
}

View File

@ -467,6 +467,7 @@ qbyte *R_MarkLeaves_Q3 (void);
void R_SetFrustum (float projmat[16], float viewmat[16]);
void R_SetRenderer(rendererinfo_t *ri);
void R_AnimateLight (void);
void R_UpdateLightStyle(unsigned int style, const char *stylestring, float r, float g, float b);
struct texture_s *R_TextureAnimation (int frame, struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
struct texture_s *R_TextureAnimation_Q2 (struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
void RQ_Init(void);

View File

@ -150,7 +150,7 @@ static trace_t PM_PlayerTracePortals(vec3_t start, vec3_t end, unsigned int soli
if (tookportal)
*tookportal = trace.fraction;
trace = PM_PlayerTrace (from, end, MASK_PLAYERSOLID);
return PM_PlayerTrace (from, end, MASK_PLAYERSOLID);
}
}
}

View File

@ -263,12 +263,14 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en
//a portal is flush with a world surface behind it.
//this causes problems. namely that we can't pass through the portal plane if the bsp behind it prevents out origin from getting through.
//so if the trace was clipped and ended infront of the portal, continue the trace to the edges of the portal cutout instead.
void PM_PortalCSG(physent_t *portal, float *trmin, float *trmax, vec3_t start, vec3_t end, trace_t *trace)
static void PM_PortalCSG(physent_t *portal, int entnum, float *trmin, float *trmax, vec3_t start, vec3_t end, trace_t *trace)
{
vec4_t planes[6]; //far, near, right, left, up, down
int plane;
vec3_t worldpos;
float portalradius = 128;
int hitplane = -1;
float bestfrac;
//only run this code if we impacted on the portal's parent.
if (trace->fraction == 1 && !trace->startsolid)
return;
@ -287,8 +289,8 @@ void PM_PortalCSG(physent_t *portal, float *trmin, float *trmax, vec3_t start, v
VectorNegate(planes[5], planes[4]);
portalradius/=2;
planes[0][3] = DotProduct(portal->origin, planes[0]) - (1.1/32);
planes[1][3] = DotProduct(portal->origin, planes[1]) - (1.1/32); //an epsilon beyond the portal
planes[0][3] = DotProduct(portal->origin, planes[0]) - (4.0/32);
planes[1][3] = DotProduct(portal->origin, planes[1]) - (4.0/32); //an epsilon beyond the portal. this needs to cover funny angle differences
planes[2][3] = DotProduct(portal->origin, planes[2]) - portalradius;
planes[3][3] = DotProduct(portal->origin, planes[3]) - portalradius;
planes[4][3] = DotProduct(portal->origin, planes[4]) - portalradius;
@ -305,16 +307,15 @@ void PM_PortalCSG(physent_t *portal, float *trmin, float *trmax, vec3_t start, v
if (!plane) //front plane gets further away with side
planes[plane][3] -= DotProduct(nearest, planes[plane]);
else if (plane>1) //side planes get nearer with size
planes[plane][3] += DotProduct(nearest, planes[plane]);
planes[plane][3] += 24;//+= DotProduct(nearest, planes[plane]);
if (d - planes[plane][3] >= 0)
continue; //endpos is inside
else
return; //end is already outside
}
//yup, we're inside, the trace shouldn't end where it actually did
trace->fraction = 1;
trace->startsolid = trace->allsolid = false;
VectorInterpolate(start, 1, end, trace->endpos);
bestfrac = 1;
hitplane = -1;
for (plane = 0; plane < 6; plane++)
{
float ds = DotProduct(start, planes[plane]) - planes[plane][3];
@ -322,18 +323,32 @@ void PM_PortalCSG(physent_t *portal, float *trmin, float *trmax, vec3_t start, v
float frac;
if (ds >= 0 && de < 0)
{
frac = (ds-(1.0/32)) / (ds - de);
if (frac < trace->fraction)
frac = (ds - (1/32.0)) / (ds - de);
if (frac < bestfrac)
{
if (frac < 0)
frac = 0;
trace->fraction = frac;
hitplane = plane;
bestfrac = frac;
VectorInterpolate(start, frac, end, trace->endpos);
VectorCopy(planes[plane], trace->plane.normal);
trace->plane.dist = planes[plane][3];
}
}
}
trace->startsolid = trace->allsolid = false;
//if we cross the front of the portal, don't shorten the trace, that will artificially clip us
if (hitplane == 0 && trace->fraction > bestfrac)
return;
//okay, elongate to clip to the portal hole properly.
trace->fraction = bestfrac;
VectorInterpolate(start, bestfrac, end, trace->endpos);
if (hitplane >= 0)
{
VectorCopy(planes[hitplane], trace->plane.normal);
trace->plane.dist = planes[hitplane][3];
if (hitplane == 1)
trace->entnum = entnum;
}
}
/*
@ -377,7 +392,7 @@ qboolean PM_TestPlayerPosition (vec3_t pos)
{
pe = &pmove.physents[j];
if (pe->isportal)
PM_PortalCSG(pe, pmove.player_mins, pmove.player_maxs, pos, pos, &trace);
PM_PortalCSG(pe, j, pmove.player_mins, pmove.player_maxs, pos, pos, &trace);
}
if (trace.allsolid)
return false;
@ -441,7 +456,7 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask)
else if (pe->isportal)
{
//make sure we don't hit the world if we're inside the portal
PM_PortalCSG(pe, pmove.player_mins, pmove.player_maxs, start, end, &total);
PM_PortalCSG(pe, i, pmove.player_mins, pmove.player_maxs, start, end, &total);
// trace a line through the apropriate clipping hull
if (!PM_TransformedHullCheck (pe->model, start, end, vec3_origin, vec3_origin, &trace, pe->origin, pe->angles))
@ -459,7 +474,7 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask)
{
pe = &pmove.physents[j];
if (pe->isportal)
PM_PortalCSG(pe, pmove.player_mins, pmove.player_maxs, start, end, &trace);
PM_PortalCSG(pe, j, pmove.player_mins, pmove.player_maxs, start, end, &trace);
}
pe = &pmove.physents[i];
}
@ -469,13 +484,10 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask)
trace.startsolid = true;
if (trace.startsolid && pe->isportal)
continue;
if (trace.startsolid)
trace.fraction = 0;
trace.startsolid = false;
// did we clip the move?
if (trace.fraction < total.fraction)
if (trace.fraction < total.fraction || (trace.startsolid && !total.startsolid))
{
// fix trace up by the offset
total = trace;

View File

@ -448,7 +448,7 @@ void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
void QCBUILTIN PF_multicast (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_svtraceline (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_changelevel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_applylightstyle(int style, const char *val, int col);
void QCBUILTIN PF_applylightstyle(int style, const char *val, vec3_t rgb);
void PF_ambientsound_Internal (float *pos, const char *samp, float vol, float attenuation);
void QCBUILTIN PF_makestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);

View File

@ -843,7 +843,6 @@ hull_t *Q1BSP_ChooseHull(model_t *model, int forcehullnum, vec3_t mins, vec3_t m
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, trace_t *trace)
{
hull_t *hull;
vec3_t size;
vec3_t start_l, end_l;
vec3_t offset;

View File

@ -384,8 +384,8 @@ typedef struct msurface_s
qbyte styles[MAXQ1LIGHTMAPS];
qbyte vlstyles[MAXRLIGHTMAPS];
int cached_light[MAXQ1LIGHTMAPS]; // values currently used in lightmap
int cached_colour[MAXQ1LIGHTMAPS];
qboolean cached_dlight; // true if dynamic light in cache
qbyte cached_colour[MAXQ1LIGHTMAPS];
#ifndef NOSTAINS
qboolean stained;
#endif

View File

@ -30,6 +30,26 @@ extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps;
int r_dlightframecount;
int d_lightstylevalue[256]; // 8.8 fraction of base light value
void R_UpdateLightStyle(unsigned int style, const char *stylestring, float r, float g, float b)
{
if (style >= MAX_LIGHTSTYLES)
return;
if (!stylestring)
stylestring = "";
Q_strncpyz (cl_lightstyle[style].map, stylestring, sizeof(cl_lightstyle[style].map));
cl_lightstyle[style].length = Q_strlen(cl_lightstyle[style].map);
if (!cl_lightstyle[style].length)
{
d_lightstylevalue[style] = 256;
VectorSet(cl_lightstyle[style].colours, 1,1,1);
}
else
VectorSet(cl_lightstyle[style].colours, r,g,b);
cl_lightstyle[style].colourkey = (int)(cl_lightstyle[style].colours[0]*0x400) ^ (int)(cl_lightstyle[style].colours[1]*0x100000) ^ (int)(cl_lightstyle[style].colours[2]*0x40000000);
}
/*
==================
R_AnimateLight
@ -52,13 +72,9 @@ void R_AnimateLight (void)
for (j=0 ; j<MAX_LIGHTSTYLES ; j++)
{
int v1, v2, vd;
if (!cl_lightstyle[j].length)
{
d_lightstylevalue[j] = 256;
cl_lightstyle[j].colour = 7;
continue;
}
v1 = i % cl_lightstyle[j].length;
v1 = cl_lightstyle[j].map[v1] - 'a';
@ -1330,12 +1346,9 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += lightmap[0] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 2)
l[1] += lightmap[1] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 4)
l[2] += lightmap[2] * scale;
l[0] += lightmap[0] * scale * cl_lightstyle[surf->styles[maps]].colours[0];
l[1] += lightmap[1] * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += lightmap[2] * scale * cl_lightstyle[surf->styles[maps]].colours[2];
l[3] += (deluxmap[0]-127)*scale;
l[4] += (deluxmap[1]-127)*scale;
@ -1359,12 +1372,9 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += *lightmap * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 2)
l[1] += *lightmap * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 4)
l[2] += *lightmap * scale;
l[0] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[0];
l[1] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[2];
l[3] += deluxmap[0]*scale;
l[4] += deluxmap[1]*scale;
@ -1388,12 +1398,9 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += lightmap[0] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 2)
l[1] += lightmap[1] * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 4)
l[2] += lightmap[2] * scale;
l[0] += lightmap[0] * scale * cl_lightstyle[surf->styles[maps]].colours[0];
l[1] += lightmap[1] * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += lightmap[2] * scale * cl_lightstyle[surf->styles[maps]].colours[2];
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1) * 3;
@ -1408,12 +1415,9 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += *lightmap * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 2)
l[1] += *lightmap * scale;
if (cl_lightstyle[surf->styles[maps]].colour & 4)
l[2] += *lightmap * scale;
l[0] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[0];
l[1] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[2];
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1);

View File

@ -3406,18 +3406,9 @@ void Sh_DrawLights(qbyte *vis)
colour[2] = dl->color[2];
if (dl->style)
{
if (cl_lightstyle[dl->style-1].colour & 1)
colour[0] *= d_lightstylevalue[dl->style-1]/255.0f;
else
colour[0] = 0;
if (cl_lightstyle[dl->style-1].colour & 2)
colour[1] *= d_lightstylevalue[dl->style-1]/255.0f;
else
colour[1] = 0;
if (cl_lightstyle[dl->style-1].colour & 4)
colour[2] *= d_lightstylevalue[dl->style-1]/255.0f;
else
colour[2] = 0;
colour[0] *= cl_lightstyle[dl->style-1].colours[0] * d_lightstylevalue[dl->style-1]/255.0f;
colour[1] *= cl_lightstyle[dl->style-1].colours[1] * d_lightstylevalue[dl->style-1]/255.0f;
colour[2] *= cl_lightstyle[dl->style-1].colours[2] * d_lightstylevalue[dl->style-1]/255.0f;
}
if (colour[0] < 0.001 && colour[1] < 0.001 && colour[2] < 0.001)

View File

@ -3970,7 +3970,7 @@ static void QCBUILTIN PF_walkmove (pubprogfuncs_t *prinst, struct globalvars_s *
pr_global_struct->self = oldself;
}
void QCBUILTIN PF_applylightstyle(int style, const char *val, int col)
void QCBUILTIN PF_applylightstyle(int style, const char *val, vec3_t rgb)
{
client_t *client;
int j;
@ -3990,7 +3990,7 @@ void QCBUILTIN PF_applylightstyle(int style, const char *val, int col)
sv.strings.lightstyles[style] = Z_StrDup(val);
#ifdef PEXT_LIGHTSTYLECOL
sv.strings.lightstylecolours[style] = col;
VectorCopy(rgb, sv.strings.lightstylecolours[style]);
#endif
// send message to all clients on this server
@ -4007,11 +4007,14 @@ void QCBUILTIN PF_applylightstyle(int style, const char *val, int col)
if (!*val)
continue;
#ifdef PEXT_LIGHTSTYLECOL
if ((client->fteprotocolextensions & PEXT_LIGHTSTYLECOL) && col!=7)
if ((client->fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (rgb[0] != 1 || rgb[1] != 1 || rgb[2] != 1))
{
ClientReliableWrite_Begin (client, svcfte_lightstylecol, strlen(val)+4);
ClientReliableWrite_Byte (client, style);
ClientReliableWrite_Char (client, col);
ClientReliableWrite_Char (client, 0x87);
ClientReliableWrite_Short (client, rgb[0]*1024);
ClientReliableWrite_Short (client, rgb[1]*1024);
ClientReliableWrite_Short (client, rgb[2]*1024);
ClientReliableWrite_String (client, val);
}
else
@ -4038,22 +4041,17 @@ static void QCBUILTIN PF_lightstyle (pubprogfuncs_t *prinst, struct globalvars_s
{
int style;
const char *val;
vec3_t rgb = {1,1,1};
#ifdef PEXT_LIGHTSTYLECOL
int col;
if (svprogfuncs->callargc >= 3)
{
col = G_FLOAT(OFS_PARM2);
if (IS_NAN(col) || !col || col > 0x111)
col = 7;
}
else col = 7;
VectorCopy(G_VECTOR(OFS_PARM2), rgb);
#endif
style = G_FLOAT(OFS_PARM0);
val = PR_GetStringOfs(prinst, OFS_PARM1);
PF_applylightstyle(style, val, col);
PF_applylightstyle(style, val, rgb);
}
static void QCBUILTIN PF_lightstylevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -4081,16 +4079,11 @@ static void QCBUILTIN PF_lightstylestatic (pubprogfuncs_t *prinst, struct global
"o", "p", "q", "r", "s", "t", "u",
"v", "w", "x", "y", "z"
};
vec3_t rgb = {1,1,1};
#ifdef PEXT_LIGHTSTYLECOL
int col;
if (svprogfuncs->callargc >= 3)
{
col = G_FLOAT(OFS_PARM2);
if (IS_NAN(col) || !col || col > 0x111)
col = 7;
}
else col = 7;
VectorCopy(G_VECTOR(OFS_PARM2), rgb);
#endif
style = G_FLOAT(OFS_PARM0);
@ -4101,7 +4094,7 @@ static void QCBUILTIN PF_lightstylestatic (pubprogfuncs_t *prinst, struct global
num = 'z'-'a'-1;
val = styleDefs[num];
PF_applylightstyle(style, val, col);
PF_applylightstyle(style, val, rgb);
}
/*
@ -4357,7 +4350,7 @@ extern sizebuf_t csqcmsgbuffer;
void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int dest = G_FLOAT(OFS_PARM0);
qbyte val = (qbyte)G_FLOAT(OFS_PARM1);
qbyte val = 0xff & (int)G_FLOAT(OFS_PARM1);
if (dest == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteByte(&csqcmsgbuffer, val);
@ -4400,7 +4393,7 @@ void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int dest = G_FLOAT(OFS_PARM0);
char val = (char)G_FLOAT(OFS_PARM1);
char val = 0xff & (int)G_FLOAT(OFS_PARM1);
if (dest == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteChar(&csqcmsgbuffer, val);
@ -5236,17 +5229,17 @@ char *PF_infokey_Internal (int entnum, const char *key)
value = "";
}
else if (!strcmp(key, "*VIP"))
value = svs.clients[entnum-1].isvip?"1":"";
value = (svs.clients[entnum-1].penalties & BAN_VIP)?"1":"";
else if (!strcmp(key, "*ismuted"))
value = svs.clients[entnum-1].ismuted?"1":"";
value = (svs.clients[entnum-1].penalties & BAN_MUTE)?"1":"";
else if (!strcmp(key, "*isdeaf"))
value = svs.clients[entnum-1].isdeaf?"1":"";
value = (svs.clients[entnum-1].penalties & BAN_DEAF)?"1":"";
else if (!strcmp(key, "*iscrippled"))
value = svs.clients[entnum-1].iscrippled?"1":"";
value = (svs.clients[entnum-1].penalties & BAN_CRIPPLED)?"1":"";
else if (!strcmp(key, "*iscuffed"))
value = svs.clients[entnum-1].iscuffed?"1":"";
value = (svs.clients[entnum-1].penalties & BAN_CUFF)?"1":"";
else if (!strcmp(key, "*islagged"))
value = svs.clients[entnum-1].islagged?"1":"";
value = (svs.clients[entnum-1].penalties & BAN_LAGGED)?"1":"";
else
value = Info_ValueForKey (svs.clients[entnum-1].userinfo, key);
} else
@ -8614,6 +8607,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
VectorCopy(ent->v->maxs, pmove.player_maxs);
VectorCopy(ent->v->mins, pmove.player_mins);
pmove.world = &sv.world;
pmove.skipent = -1;
pmove.numphysent = 1;
pmove.physents[0].model = sv.world.worldmodel;
@ -8645,6 +8639,8 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
VectorCopy(pmove.velocity, ent->v->velocity);
VectorCopy(pmove.angles, sv_player->v->v_angle);
ent->v->waterlevel = pmove.waterlevel;
@ -8694,6 +8690,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
{
if (gfuncs.RunClientCommand)
{
vec3_t startangle;
#ifdef SVCHAT
if (SV_ChatMove(ucmd->impulse))
{
@ -8709,6 +8706,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
sv_player->v->v_angle[1] = SHORT2ANGLE(ucmd->angles[1]);
sv_player->v->v_angle[2] = SHORT2ANGLE(ucmd->angles[2]);
}
VectorCopy(sv_player->v->v_angle, startangle);
if (progstype == PROG_H2)
sv_player->xv->light_level = 128; //hmm... HACK!!!
@ -8725,7 +8723,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
if (ucmd->impulse && SV_FilterImpulse(ucmd->impulse, host_client->trustlevel))
sv_player->v->impulse = ucmd->impulse;
if (host_client->iscuffed)
if (host_client->penalties & BAN_CUFF)
{
sv_player->v->impulse = 0;
sv_player->v->button0 = 0;
@ -8792,6 +8790,23 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, client->edict);
PR_ExecuteProgram(svprogfuncs, gfuncs.RunClientCommand);
if (!sv_player->v->fixangle)
{
int i;
vec3_t delta;
VectorSubtract (sv_player->v->v_angle, startangle, delta);
if (delta[0] || delta[1] || delta[2])
{
//eular angle changes suck
client_t *cl = ClientReliableWrite_BeginSplit(client, svcfte_setangledelta, 7);
for (i=0 ; i < 3 ; i++)
ClientReliableWrite_Angle16 (cl, delta[i]);
}
}
return true;
}
return false;
@ -8960,7 +8975,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"setmodel", PF_setmodel, 3, 3, 3, 0, D("void(entity e, string m)","Looks up m in the model precache list, and sets both e.model and e.modelindex to match. BSP models will set e.mins and e.maxs accordingly, other models depend upon the value of sv_gameplayfix_setmodelrealbox - for compatibility you should always call setsize after all pickups or non-bsp models. Also relinks collision state.")},
{"setsize", PF_setsize, 4, 4, 4, 0, D("void(entity e, vector min, vector max)", "Sets the e's mins and maxs fields. Also relinks collision state, which sets absmin and absmax too.")},
{"qtest_setabssize",PF_setsize, 5, 0, 0, 0, D("void(entity e, vector min, vector max)", "qtest"), true},
{"lightstylestatic",PF_lightstylestatic,0, 0, 5, 5, D("void(float style, float val)", "Sets the lightstyle to an explicit numerical level. From Hexen2.")},
{"lightstylestatic",PF_lightstylestatic,0, 0, 5, 5, D("void(float style, float val, optional vector rgb)", "Sets the lightstyle to an explicit numerical level. From Hexen2.")},
{"breakpoint", PF_break, 6, 6, 6, 0, D("void()", "Trigger a debugging event. FTE will break into the qc debugger. Other engines may crash with a debug execption.")},
{"random", PF_random, 7, 7, 7, 0, D("float()", "Returns a random value between 0 and 1. Be warned, this builtin can return 1 in most engines, which can break arrays.")},
{"sound", PF_sound, 8, 8, 8, 0, D("void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags)", "Starts a sound centered upon the given entity.\nchan is the entity sound channel to use, channel 0 will allow you to mix many samples at once, others will replace the old sample\n'samp' must have been precached first\nif specified, 'speedpct' should normally be around 100 (or =0), 200 for double speed or 50 for half speed.\nflags&1 means the sound should be sent reliably.")},
@ -8997,7 +9012,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
// {"qtest_flymove", NULL, 33}, // float(vector dir) flymove = #33;
//qbism super8's 'private'sound #33
{"droptofloor", PF_droptofloor, 34, 34, 34, 0, D("float()", "Instantly moves the entity downwards until it hits the ground. If the entity would need to drop more than 'pr_droptofloorunits' quake units, its position will be considered invalid and the builtin will abort.")},
{"lightstyle", PF_lightstyle, 35, 35, 35, 0, D("void(float lightstyle, string stylestring, optional float channels)", "Specifies an auto-animating string that specifies the light intensity for entities using that lightstyle.\na is off, z is fully lit. Should be lower case only.\nchannels&1 enables red light.\nchannels&2 enables green light.\nchannels&4 enables blue light.\n")},
{"lightstyle", PF_lightstyle, 35, 35, 35, 0, D("void(float lightstyle, string stylestring, optional vector rgb)", "Specifies an auto-animating string that specifies the light intensity for entities using that lightstyle.\na is off, z is fully lit. Should be lower case only.\nrgb will recolour all lights using that lightstyle.\n")},
{"rint", PF_rint, 36, 36, 36, 0, D("float(float)", "Rounds the given float up or down to the closest integeral value. X.5 rounds away from 0")},
{"floor", PF_floor, 37, 37, 37, 0, D("float(float)", "Rounds the given float downwards, even when negative.")},
{"ceil", PF_ceil, 38, 38, 38, 0, D("float(float)", "Rounds the given float upwards, even when negative.")},

View File

@ -658,7 +658,9 @@ static int bi_lua_precache_sound(lua_State *L)
}
static int bi_lua_lightstyle(lua_State *L)
{
PF_applylightstyle(lua.tointegerx(L, 1, NULL), lua.tolstring(L, 2, NULL), 7);
vec3_t rgb;
lua_readvector(L, 3, rgb);
PF_applylightstyle(lua.tointegerx(L, 1, NULL), lua.tolstring(L, 2, NULL), rgb);
return 0;
}
static int bi_lua_spawn(lua_State *L)

View File

@ -597,7 +597,10 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con
break;
case G_LIGHTSTYLE:
PF_applylightstyle(VM_LONG(arg[0]), VM_POINTER(arg[1]), 7);
{
vec3_t rgb = {1,1,1};
PF_applylightstyle(VM_LONG(arg[0]), VM_POINTER(arg[1]), rgb);
}
break;
case G_SETORIGIN:

View File

@ -138,7 +138,7 @@ typedef struct
char particle_precache[MAX_SSPARTICLESPRE][MAX_QPATH]; // NULL terminated
char sound_precache[MAX_SOUNDS][MAX_QPATH]; // NULL terminated
const char *lightstyles[MAX_LIGHTSTYLES];
qbyte lightstylecolours[MAX_LIGHTSTYLES];
vec3_t lightstylecolours[MAX_LIGHTSTYLES];
};
} strings;
char h2miditrack[MAX_QPATH];
@ -481,13 +481,14 @@ typedef struct client_s
#endif
//true/false/persist
qbyte ismuted;
unsigned int penalties;
/* qbyte ismuted;
qbyte iscuffed;
qbyte iscrippled;
qbyte isdeaf;
qbyte islagged;
qbyte isvip;
*/
qbyte istobeloaded; //loadgame creates place holders for clients to connect to. Effectivly loading a game reconnects all clients, but has precreated ents.
double floodprotmessage;
@ -745,7 +746,9 @@ typedef struct
#define BAN_CRIPPLED (1u<<4) //can't move
#define BAN_DEAF (1u<<5) //can't see say/say_team
#define BAN_LAGGED (1u<<6) //given an extra 200ms
#define BAN_VIP (1u<<7) //mods might give the user special rights
#define BAN_VIP (1u<<7) //mods might give the user special rights, via the *VIP infokey. the engine itself currently does not do anything but track it.
#define BAN_BLIND (1u<<8) //player's pvs is wiped.
#define BAN_SPECONLY (1u<<9) //player is forced to spectate
typedef struct bannedips_s {
unsigned int banflags;

View File

@ -316,7 +316,7 @@ static void SV_Give_f (void)
return;
}
if (developer.value)
/* if (developer.value)
{
int oldself;
oldself = pr_global_struct->self;
@ -324,7 +324,7 @@ static void SV_Give_f (void)
Con_Printf("Result: %s\n", svprogfuncs->EvaluateDebugString(svprogfuncs, Cmd_Args()));
pr_global_struct->self = oldself;
}
*/
if (!SV_SetPlayer ())
{
return;
@ -363,7 +363,7 @@ static void SV_Give_f (void)
case 'c':
sv_player->v->ammo_cells = v;
break;
default:
/* default:
{
int oldself;
oldself = pr_global_struct->self;
@ -372,6 +372,7 @@ static void SV_Give_f (void)
Con_TPrintf("Result: %s\n", svprogfuncs->EvaluateDebugString(svprogfuncs, Cmd_Args()));
pr_global_struct->self = oldself;
}
*/
}
}
@ -765,18 +766,14 @@ void SV_KickSlot_f (void)
void SV_EvaluatePenalties(client_t *cl)
{
bannedips_t *banip;
bannedips_t *cuff = NULL;
bannedips_t *mute = NULL;
bannedips_t *cripple = NULL;
bannedips_t *deaf = NULL;
bannedips_t *lagged = NULL;
bannedips_t *vip = NULL;
bannedips_t *safe = NULL;
bannedips_t *banned = NULL;
char *penalties[8];
char *reasons[8];
unsigned int penalties = 0, delta, p;
char *penaltyreason[10];
char *activepenalties[10];
char *reasons[10] = {NULL};
char *penaltynames[10] = {"ban", "safe", "cuff", "mute", "crippled", "deaf", "lag", "vip", "blind", "spec"};
int numpenalties = 0;
int numreasons = 0;
int i;
if (cl->realip.type != NA_INVALID)
{
@ -784,22 +781,16 @@ void SV_EvaluatePenalties(client_t *cl)
{
if (NET_CompareAdrMasked(&cl->realip, &banip->adr, &banip->adrmask))
{
if ((banip->banflags & BAN_CUFF) && !cuff)
cuff = banip;
if ((banip->banflags & BAN_MUTE) && !mute)
mute = banip;
if ((banip->banflags & BAN_CRIPPLED) && !cripple)
cripple = banip;
if ((banip->banflags & BAN_DEAF) && !deaf)
deaf = banip;
if ((banip->banflags & BAN_LAGGED) && !lagged)
lagged = banip;
if ((banip->banflags & BAN_BAN) && !banned)
banned = banip;
if ((banip->banflags & BAN_PERMIT) && !safe)
safe = banip;
if ((banip->banflags & BAN_VIP) && !vip)
vip = banip;
for (i = 0; i < sizeof(penaltyreason)/sizeof(penaltyreason[0]); i++)
{
p = 1u<<i;
if (banip->banflags & p)
{
if (!penaltyreason[i])
penaltyreason[i] = banip->reason;
penalties |= p;
}
}
}
}
}
@ -807,164 +798,80 @@ void SV_EvaluatePenalties(client_t *cl)
{
if (NET_CompareAdrMasked(&cl->netchan.remote_address, &banip->adr, &banip->adrmask))
{
if ((banip->banflags & BAN_CUFF) && !cuff)
cuff = banip;
if ((banip->banflags & BAN_MUTE) && !mute)
mute = banip;
if ((banip->banflags & BAN_CRIPPLED) && !cripple)
cripple = banip;
if ((banip->banflags & BAN_DEAF) && !deaf)
deaf = banip;
if ((banip->banflags & BAN_LAGGED) && !lagged)
lagged = banip;
if ((banip->banflags & BAN_BAN) && !banned)
banned = banip;
if ((banip->banflags & BAN_PERMIT) && !safe)
safe = banip;
if ((banip->banflags & BAN_VIP) && !vip)
vip = banip;
for (i = 0; i < sizeof(penaltyreason)/sizeof(penaltyreason[0]); i++)
{
p = 1u<<i;
if (banip->banflags & p)
{
if (!penaltyreason[i])
penaltyreason[i] = banip->reason;
penalties |= p;
}
}
}
}
if (banned && !safe)
delta = cl->penalties ^ penalties;
cl->penalties = penalties;
if ((penalties & (BAN_BAN | BAN_PERMIT)) == BAN_BAN)
{
if (*banned->reason)
SV_BroadcastPrintf(PRINT_HIGH, va("%s was banned: %s\n", cl->name, banned->reason));
//we should only reach here by a player getting banned mid-game.
if (penaltyreason[0])
SV_BroadcastPrintf(PRINT_HIGH, va("%s was banned: %s\n", cl->name, penaltyreason[0]));
else
SV_BroadcastPrintf(PRINT_HIGH, va("%s was banned\n", cl->name));
cl->drop = true;
}
if (cuff)
{
if (!cl->iscuffed)
{
cl->iscuffed = true;
penalties[numpenalties++] = "cuffed";
reasons[numreasons++] = cuff->reason;
}
}
else
{
if (cl->iscuffed == true)
{
cl->iscuffed = false;
SV_PrintToClient(cl, PRINT_HIGH, "Cuff expired\n");
}
}
//don't announce these now.
delta &= ~(BAN_BAN | BAN_PERMIT);
if (cripple)
{
if (!cl->iscrippled)
{
cl->iscrippled = true;
penalties[numpenalties++] = "crippled";
reasons[numreasons++] = cripple->reason;
}
}
else
{
if (cl->iscrippled == true)
{
cl->iscrippled = false;
SV_PrintToClient(cl, PRINT_HIGH, "Cripple expired\n");
}
}
if (mute)
{
if (!cl->ismuted)
{
cl->ismuted = true;
if (!deaf)
{
penalties[numpenalties++] = "muted";
reasons[numreasons++] = mute->reason;
}
}
}
else
{
if (cl->ismuted == true)
{
cl->ismuted = false;
if (!cl->isdeaf)
SV_PrintToClient(cl, PRINT_HIGH, "Mute expired\n");
if (!deaf && cl->isdeaf == true)
cl->isdeaf = false; //don't let them know that they were ever mute+deaf.
}
}
if (deaf)
{
if (!cl->isdeaf)
{
cl->isdeaf = true;
if (!mute)
{
penalties[numpenalties++] = "deaf";
reasons[numreasons++] = deaf->reason;
}
}
}
else
{
if (cl->isdeaf == true)
{
cl->isdeaf = false;
SV_PrintToClient(cl, PRINT_HIGH, "Deafness expired\n");
}
}
if (lagged)
{
if (!cl->islagged)
{
cl->islagged = true;
penalties[numpenalties++] = "lagged";
reasons[numreasons++] = lagged->reason;
}
}
else
{
if (cl->islagged == true)
{
cl->islagged = false;
SV_PrintToClient(cl, PRINT_HIGH, "Lag penalty expired\n");
}
}
if (vip)
{
if (!cl->isvip)
{
cl->isvip = true;
penalties[numpenalties++] = "vip";
reasons[numreasons++] = deaf->reason;
}
}
else
{
if (cl->isvip == true)
{
cl->isvip = false;
SV_PrintToClient(cl, PRINT_HIGH, "VIP expired\n");
}
}
//deaf+mute sees no (other) penalty messages
if (((penalties|delta) & (BAN_MUTE|BAN_DEAF)) == (BAN_MUTE|BAN_DEAF))
delta = 0;
if (cl->controller)
return; //don't spam it for every player in a splitscreen client.
delta = 0; //don't spam it for every player in a splitscreen client.
if (delta & BAN_VIP)
{
delta &= ~BAN_VIP; //don't refer to this as a penalty
if (penalties & p)
SV_PrintToClient(cl, PRINT_HIGH, "You are a VIP, apparently\n");
else
SV_PrintToClient(cl, PRINT_HIGH, "VIP expired\n");
}
for (i = 0; i < sizeof(penaltyreason)/sizeof(penaltyreason[0]); i++)
{
p = 1u<<i;
if (delta & p)
{
if (penalties & p)
{
if (penaltynames[i])
activepenalties[numpenalties++] = penaltynames[i];
if (reasons[i] && *reasons[i])
reasons[numreasons++] = reasons[i];
}
else
SV_PrintToClient(cl, PRINT_HIGH, va("Penalty expired: %s\n", penaltynames[i]));
}
}
if (numpenalties)
{
char penaltystring[1024];
int i, j;
Q_strncpyz(penaltystring, "You are ", sizeof(penaltystring));
Q_strncpyz(penaltystring, "You are penalised: ", sizeof(penaltystring));
for (i = 0; i < numpenalties; i++)
{
if (i && i == numpenalties-1)
Q_strncatz(penaltystring, " and ", sizeof(penaltystring));
else if (i)
Q_strncatz(penaltystring, ", ", sizeof(penaltystring));
Q_strncatz(penaltystring, penalties[i], sizeof(penaltystring));
Q_strncatz(penaltystring, activepenalties[i], sizeof(penaltystring));
}
Q_strncatz(penaltystring, "\n", sizeof(penaltystring));
SV_PrintToClient(cl, PRINT_HIGH, penaltystring);
@ -1200,6 +1107,8 @@ static void SV_FilterIP_f (void)
proto.banflags |= BAN_LAGGED;
else if (!Q_strcasecmp(com_token, "vip"))
proto.banflags |= BAN_VIP;
else if (!Q_strcasecmp(com_token, "blind"))
proto.banflags |= BAN_BLIND;
else
Con_Printf("Unknown ban/penalty flag: %s. ignoring.\n", com_token);
}
@ -1266,6 +1175,7 @@ static void SV_FilterList_f (void)
"deaf",
"lag",
"vip",
"blind",
NULL
};
@ -1380,6 +1290,12 @@ static void SV_Unfilter_f (void)
if (!all && !found)
Con_Printf("address was not filtered\n");
if (found)
{
reevaluatebans = true;
SV_KillExpiredBans();
}
}
static void SV_PenaltyToggle (unsigned int banflag, char *penaltyname)
{
@ -1905,7 +1821,7 @@ void SV_ConSay_f(void)
{
if (client->state == cs_free)
continue;
if (client->isdeaf)
if (client->penalties & BAN_DEAF)
continue;
SV_ClientPrintf(client, PRINT_CHAT, "%s\n", text);
}
@ -2245,17 +2161,17 @@ void SV_User_f (void)
if (cl->download)
Con_Printf ("download: \"%s\" %ik/%ik (%i%%)", cl->downloadfn, cl->downloadcount/1024, cl->downloadsize/1024, (cl->downloadcount*100)/cl->downloadsize);
if (cl->iscrippled)
if (cl->penalties & BAN_CRIPPLED)
Con_Printf("crippled\n");
if (cl->iscuffed)
if (cl->penalties & BAN_CUFF)
Con_Printf("cuffed\n");
if (cl->isdeaf)
if (cl->penalties & BAN_DEAF)
Con_Printf("deaf\n");
if (cl->islagged)
if (cl->penalties & BAN_LAGGED)
Con_Printf("lagged\n");
if (cl->ismuted)
if (cl->penalties & BAN_MUTE)
Con_Printf("muted\n");
if (cl->isvip)
if (cl->penalties & BAN_VIP)
Con_Printf("vip\n");
SV_CalcNetRates(cl, &ftime, &frames, &minf, &maxf);

View File

@ -2290,6 +2290,10 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
if (cl->state != cs_spawned && !(cl->state == cs_free && cl->name[0])) //this includes bots, and nq bots
continue;
if ((client->penalties & BAN_BLIND) && client != cl)
continue;
isbot = (!cl->name[0] || cl->protocol == SCP_BAD);
ent = cl->edict;
if (cl->viewent && ent == clent)
@ -3139,6 +3143,12 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
limit = min(client->max_net_ents, sv.world.num_edicts);
if (client->penalties & BAN_BLIND)
{
e = client->edict->entnum;
limit = e+1;
}
for ( ; e<limit ; e++)
{
ent = EDICT_NUM(svprogfuncs, e);
@ -3496,10 +3506,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
SV_Snapshot_Clear(pack);
if (!pack->entities)
{
Con_Printf("DON'T PANIC!\n");
return;
}
// put other visible entities into either a packet_entities or a nails message

View File

@ -469,12 +469,12 @@ void SV_DropClient (client_t *drop)
rs.deaths += drop->deaths;
rs.flags1 &= ~(RANK_CUFFED|RANK_MUTED|RANK_CRIPPLED);
if (drop->iscuffed==2)
rs.flags1 |= RANK_CUFFED;
if (drop->ismuted==2)
rs.flags1 |= RANK_MUTED;
if (drop->iscrippled==2)
rs.flags1 |= RANK_CRIPPLED;
// if (drop->iscuffed==2)
// rs.flags1 |= RANK_CUFFED;
// if (drop->ismuted==2)
// rs.flags1 |= RANK_MUTED;
// if (drop->iscrippled==2)
// rs.flags1 |= RANK_CRIPPLED;
drop->kills=0;
drop->deaths=0;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
@ -5659,12 +5659,12 @@ qboolean ReloadRanking(client_t *cl, const char *newname)
rs.deaths += cl->deaths;
rs.flags1 &= ~(RANK_CUFFED|RANK_MUTED|RANK_CRIPPLED);
if (cl->iscuffed==2)
rs.flags1 |= RANK_CUFFED;
if (cl->ismuted==2)
rs.flags1 |= RANK_MUTED;
if (cl->iscrippled==2)
rs.flags1 |= RANK_CRIPPLED;
// if (cl->iscuffed==2)
// rs.flags1 |= RANK_CUFFED;
// if (cl->ismuted==2)
// rs.flags1 |= RANK_MUTED;
// if (cl->iscrippled==2)
// rs.flags1 |= RANK_CRIPPLED;
cl->kills=0;
cl->deaths=0;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
@ -5680,17 +5680,11 @@ qboolean ReloadRanking(client_t *cl, const char *newname)
return false;
cl->rankid = newid;
if (rs.flags1 & RANK_CUFFED)
cl->iscuffed=2;
else if (cl->iscuffed) //continue being cuffed, but don't inflict the new user with persistant cuffing.
cl->iscuffed=1;
cl->penalties |= BAN_CUFF;
if (rs.flags1 & RANK_MUTED)
cl->ismuted=2;
else if (cl->ismuted)
cl->ismuted=1;
cl->penalties |= BAN_MUTE;
if (rs.flags1 & RANK_CRIPPLED)
cl->iscrippled=2;
else if (cl->iscrippled)
cl->iscrippled=1;
cl->penalties |= BAN_CRIPPLED;
cl->trustlevel = rs.trustlevel;
return true;
@ -5768,7 +5762,7 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose)
if (strncmp(newname, cl->name, sizeof(cl->namebuf)-1))
{
if (cl->ismuted && *cl->name && verbose) //!verbose is a gamecode-forced update, where the gamecode is expected to know what its doing.
if ((cl->penalties & BAN_MUTE) && *cl->name && verbose) //!verbose is a gamecode-forced update, where the gamecode is expected to know what its doing.
SV_ClientTPrintf (cl, PRINT_HIGH, "Muted players may not change their names\n");
else
{

View File

@ -1956,11 +1956,14 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
if (!sv.strings.lightstyles[i])
continue;
#ifdef PEXT_LIGHTSTYLECOL
if ((demo.recorder.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && sv.strings.lightstylecolours[i]!=7 && sv.strings.lightstyles[i])
if ((demo.recorder.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (sv.strings.lightstylecolours[i][0]!=1||sv.strings.lightstylecolours[i][1]!=1||sv.strings.lightstylecolours[i][2]!=1) && sv.strings.lightstyles[i])
{
MSG_WriteByte (&buf, svcfte_lightstylecol);
MSG_WriteByte (&buf, (unsigned char)i);
MSG_WriteByte (&buf, sv.strings.lightstylecolours[i]);
MSG_WriteByte (&buf, 0x87);
MSG_WriteShort(&buf, sv.strings.lightstylecolours[i][0]*1024);
MSG_WriteShort(&buf, sv.strings.lightstylecolours[i][1]*1024);
MSG_WriteShort(&buf, sv.strings.lightstylecolours[i][2]*1024);
MSG_WriteString (&buf, sv.strings.lightstyles[i]);
}
else

View File

@ -403,14 +403,15 @@ static int WPhys_FlyMove (world_t *w, wedict_t *ent, const vec3_t gravitydir, fl
VectorSubtract(end, trace.endpos, move);
WPhys_PortalTransform(w, ent, impact, from, move);
VectorAdd(from, move, end);
//if we follow the portal, then we basically need to restart from the other side.
time_left -= time_left * trace.fraction;
VectorCopy (ent->v->velocity, primal_velocity);
VectorCopy (ent->v->velocity, original_velocity);
numplanes = 0;
trace = World_Move (w, from, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, (wedict_t*)ent);
impact = trace.ent;
}
if (trace.startsolid)

View File

@ -669,6 +669,8 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
else if (mask)
{
if (client->penalties & BAN_BLIND)
continue;
#ifdef Q2SERVER
if (ge)
leafnum = CM_PointLeafnum (sv.world.worldmodel, client->q2edict->s.origin);
@ -829,6 +831,9 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
if (!mask) //no pvs? broadcast.
goto inrange;
if (client->penalties & BAN_BLIND)
continue;
if (to == MULTICAST_PHS_R || to == MULTICAST_PHS)
{
vec3_t delta;

View File

@ -1531,12 +1531,15 @@ void SVQW_Spawn_f (void)
if (!sv.strings.lightstyles[i])
continue;
#ifdef PEXT_LIGHTSTYLECOL
if ((host_client->fteprotocolextensions & PEXT_LIGHTSTYLECOL) && sv.strings.lightstylecolours[i]!=7 && sv.strings.lightstyles[i])
if ((host_client->fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (sv.strings.lightstylecolours[i][0]!=1||sv.strings.lightstylecolours[i][1]!=1||sv.strings.lightstylecolours[i][2]!=1) && sv.strings.lightstyles[i])
{
ClientReliableWrite_Begin (host_client, svcfte_lightstylecol,
3 + (sv.strings.lightstyles[i] ? strlen(sv.strings.lightstyles[i]) : 1));
10 + (sv.strings.lightstyles[i] ? strlen(sv.strings.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_Char (host_client, sv.strings.lightstylecolours[i]);
ClientReliableWrite_Char (host_client, 0x87);
ClientReliableWrite_Short (host_client, sv.strings.lightstylecolours[i][0]*1024);
ClientReliableWrite_Short (host_client, sv.strings.lightstylecolours[i][1]*1024);
ClientReliableWrite_Short (host_client, sv.strings.lightstylecolours[i][2]*1024);
ClientReliableWrite_String (host_client, sv.strings.lightstyles[i]);
}
else
@ -2317,7 +2320,7 @@ void SV_VoiceReadPacket(void)
bytes = MSG_ReadShort();
ring = &voice.ring[voice.write & (VOICE_RING_SIZE-1)];
//voice data does not get echoed to the sender unless sv_voip_echo is on too, which is rarely the case, so no worries about leaking the mute+deaf talking-to-yourself thing
if (bytes > sizeof(ring->data) || host_client->ismuted || !sv_voip.ival)
if (bytes > sizeof(ring->data) || (host_client->penalties & BAN_MUTE) || !sv_voip.ival)
{
MSG_ReadSkip(bytes);
return;
@ -2349,7 +2352,7 @@ void SV_VoiceReadPacket(void)
if (!cl->spectator)
continue;
if (cl->isdeaf)
if (cl->penalties & BAN_DEAF)
continue;
if (vt == VT_TEAM)
@ -3112,7 +3115,7 @@ void SV_SayOne_f (void)
if (Cmd_Argc () < 3)
return;
if (host_client->ismuted && !host_client->isdeaf)
if ((host_client->penalties & BAN_MUTE) && !(host_client->penalties & BAN_DEAF))
{
SV_ClientTPrintf(host_client, PRINT_CHAT, "You are muted\n");
return;
@ -3120,7 +3123,7 @@ void SV_SayOne_f (void)
while((to = SV_GetClientForString(Cmd_Argv(1), &clnum)))
{
if (host_client->ismuted)
if ((host_client->penalties & BAN_MUTE))
continue;
if (host_client->spectator)
{
@ -3132,7 +3135,7 @@ void SV_SayOne_f (void)
else
Q_snprintfz (text, sizeof(text), "{%s}:", host_client->name);
if (to->isdeaf)
if (to->penalties & BAN_DEAF)
continue;
for (i = 2; ; i++)
@ -3246,7 +3249,7 @@ void SV_Say (qboolean team)
if (Cmd_Argc () < 2)
return;
if (!host_client->ismuted)
if (!(host_client->penalties & BAN_MUTE))
Sys_ServerActivity();
memset(sent, 0, sizeof(sent));
@ -3263,7 +3266,7 @@ void SV_Say (qboolean team)
else
Q_snprintfz (text, sizeof(text), "%s: ", host_client->name);
if (host_client->ismuted && !host_client->isdeaf)
if ((host_client->penalties & BAN_MUTE) && !(host_client->penalties & BAN_DEAF))
{
SV_ClientTPrintf(host_client, PRINT_CHAT, "You cannot chat while muted\n");
return;
@ -3321,7 +3324,7 @@ void SV_Say (qboolean team)
Q_strcat(text, "\n");
if (!host_client->ismuted)
if (!(host_client->penalties & BAN_MUTE))
Sys_Printf ("%s", text);
mvdrecording = sv.mvdrecording;
@ -3347,12 +3350,12 @@ void SV_Say (qboolean team)
}
}
if (host_client->ismuted)
if (host_client->penalties & BAN_MUTE)
{
if (client != host_client)
continue;
}
else if (client->isdeaf)
else if (client->penalties & BAN_DEAF)
continue;
cls |= 1 << j;
@ -3970,12 +3973,12 @@ void SV_Vote_f (void)
int totalusers = 0;
qboolean passes;
if (!votelevel.value || (host_client->ismuted && host_client->isdeaf))
if (!votelevel.value || ((host_client->penalties & (BAN_MUTE|BAN_DEAF)) == (BAN_MUTE|BAN_DEAF)))
{
SV_ClientTPrintf(host_client, PRINT_HIGH, "Voting was dissallowed\n");
return;
}
if (host_client->ismuted)
if (host_client->penalties & BAN_MUTE)
{
SV_ClientTPrintf(host_client, PRINT_HIGH, "Sorry, you cannot vote when muted as it may allow you to send a message.\n");
return;
@ -5924,7 +5927,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
if (ucmd->impulse && SV_FilterImpulse(ucmd->impulse, host_client->trustlevel))
sv_player->v->impulse = ucmd->impulse;
if (host_client->iscuffed)
if (host_client->penalties & BAN_CUFF)
{
sv_player->v->impulse = 0;
sv_player->v->button0 = 0;
@ -6488,7 +6491,7 @@ void SV_ExecuteClientMessage (client_t *cl)
cl->delay = bound(0, cl->delay, 1); //but make sure things don't go crazy
}
}
if (cl->islagged)
if (cl->penalties & BAN_LAGGED)
if (cl->delay < 0.2)
cl->delay = 0.2;
}
@ -6623,7 +6626,7 @@ void SV_ExecuteClientMessage (client_t *cl)
}
}
if (split->iscrippled)
if (split->penalties & BAN_CRIPPLED)
{
split->lastcmd.forwardmove = 0; //hmmm.... does this work well enough?
oldest.forwardmove = 0;
@ -6891,7 +6894,7 @@ void SVQ2_ExecuteClientMessage (client_t *cl)
return;
}
if (cl->iscrippled)
if (cl->penalties & BAN_CRIPPLED)
{
cl->lastcmd.forwardmove = 0; //hmmm.... does this work well enough?
oldest.forwardmove = 0;

View File

@ -1373,6 +1373,8 @@ void World_PortalCSG(wedict_t *portal, float *trmin, float *trmax, vec3_t start,
vec4_t planes[6]; //far, near, right, left, up, down
int plane;
vec3_t worldpos;
float bestfrac;
int hitplane;
float portalradius = portal->v->impulse;
//only run this code if we impacted on the portal's parent.
if (trace->fraction == 1 && !trace->startsolid)
@ -1392,8 +1394,8 @@ void World_PortalCSG(wedict_t *portal, float *trmin, float *trmax, vec3_t start,
VectorNegate(planes[5], planes[4]);
portalradius/=2;
planes[0][3] = DotProduct(portal->v->origin, planes[0]) - (1.0/32);
planes[1][3] = DotProduct(portal->v->origin, planes[1]) - (1.0/32); //an epsilon beyond the portal
planes[0][3] = DotProduct(portal->v->origin, planes[0]) - (4.0/32);
planes[1][3] = DotProduct(portal->v->origin, planes[1]) - (4.0/32); //an epsilon beyond the portal
planes[2][3] = DotProduct(portal->v->origin, planes[2]) - portalradius;
planes[3][3] = DotProduct(portal->v->origin, planes[3]) - portalradius;
planes[4][3] = DotProduct(portal->v->origin, planes[4]) - portalradius;
@ -1410,16 +1412,15 @@ void World_PortalCSG(wedict_t *portal, float *trmin, float *trmax, vec3_t start,
if (!plane) //front plane gets further away with side
planes[plane][3] -= DotProduct(nearest, planes[plane]);
else if (plane>1) //side planes get nearer with size
planes[plane][3] += DotProduct(nearest, planes[plane]);
planes[plane][3] += 24;//DotProduct(nearest, planes[plane]);
if (d - planes[plane][3] >= 0)
continue; //endpos is inside
else
return; //end is already outside
}
//yup, we're inside, the trace shouldn't end where it actually did
trace->fraction = 1;
trace->startsolid = trace->allsolid = false;
VectorInterpolate(start, 1, end, trace->endpos);
bestfrac = 1;
hitplane = -1;
for (plane = 0; plane < 6; plane++)
{
float ds = DotProduct(start, planes[plane]) - planes[plane][3];
@ -1427,18 +1428,31 @@ void World_PortalCSG(wedict_t *portal, float *trmin, float *trmax, vec3_t start,
float frac;
if (ds >= 0 && de < 0)
{
frac = (ds-(1.0/32)) / (ds - de);
if (frac < trace->fraction)
frac = (ds) / (ds - de);
if (frac < bestfrac)
{
if (frac < 0)
frac = 0;
trace->fraction = frac;
VectorInterpolate(start, frac, end, trace->endpos);
VectorCopy(planes[plane], trace->plane.normal);
trace->plane.dist = planes[plane][3];
bestfrac = frac;
hitplane = plane;
}
}
}
trace->startsolid = trace->allsolid = false;
//if we cross the front of the portal, don't shorten the trace, that will artificially clip us
if (hitplane == 0 && trace->fraction > bestfrac)
return;
//okay, elongate to clip to the portal hole properly.
trace->fraction = bestfrac;
VectorInterpolate(start, bestfrac, end, trace->endpos);
if (hitplane >= 0)
{
VectorCopy(planes[hitplane], trace->plane.normal);
trace->plane.dist = planes[hitplane][3];
if (hitplane == 1)
trace->ent = portal;
}
}
/*