diff --git a/config/menus_edit.cfg b/config/menus_edit.cfg index 88498683..ba4b8b1a 100644 --- a/config/menus_edit.cfg +++ b/config/menus_edit.cfg @@ -181,6 +181,10 @@ menuinit [ menuitem "" -1 menuitemtextinput (concatword "Ambient light (0..255 or 0xrrggbb, default 0):\t") (if (< $ambient 256) $ambient (concatword "0x" (h0 6 $ambient))) [ambient $arg1] menuitem "" -1 + menuitemcheckbox "Map override: Disable water reflection" "$mapoverride_nowaterreflect" [ mapoverride_nowaterreflect $arg1 ] + menuitemcheckbox "Map override: Limit water waveheight" "$mapoverride_limitwaveheight" [ mapoverride_limitwaveheight $arg1 ] + menuitemcheckbox "Map override: Disable stencil shadows" "$mapoverride_nostencilshadows" [ mapoverride_nostencilshadows $arg1 ] + menuitem "" -1 push n (getnotexture) if (! (strlen $n)) [n = ] menuitem (concatword "Notexture:\t\t\t\t" (pop n)) [showmenu "Set notexture"] diff --git a/config/menus_settings.cfg b/config/menus_settings.cfg index 0a3508bd..f4f84e50 100644 --- a/config/menus_settings.cfg +++ b/config/menus_settings.cfg @@ -396,6 +396,9 @@ const setshadowq [ menuitemcheckbox [Dynamic lights: ] "$dynlight" [ dynlight $arg1 ] menuitemcheckbox [Bulletholes: ] "$bullethole" [ bullethole $arg1 ] menuitemcheckbox [Scorch: ] "$scorch" [ scorch $arg1 ] +menuitemcheckbox "Ignore map override: Disable water reflection" "$ignoreoverride_nowaterreflect" [ ignoreoverride_nowaterreflect $arg1 ] +menuitemcheckbox "Ignore map override: Limit water waveheight" "$ignoreoverride_limitwaveheight" [ ignoreoverride_limitwaveheight $arg1 ] +menuitemcheckbox "Ignore map override: Disable stencil shadows" "$ignoreoverride_nostencilshadows" [ ignoreoverride_nostencilshadows $arg1 ] menuitem [Enable 0.93 FOV compatiblity...] [ fovcompat; sleep 100 fovcompatmenu ] menuitem [] -1 menuitem [FPS Range...] [ showmenu [FPS Range] ] diff --git a/source/src/cube.h b/source/src/cube.h index 89ef675c..8e2d8e56 100644 --- a/source/src/cube.h +++ b/source/src/cube.h @@ -49,7 +49,7 @@ extern int xtraverts; extern float fovy, aspect; extern int farplane; extern bool minimap, reflecting, refracting; -extern int stenciling, stencilshadow; +extern int stenciling, stencilshadow, effective_stencilshadow; extern bool intermission; extern int arenaintermission; extern hashtable mapinfo; diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index 7a1bdf3b..f98d1bf7 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -1016,8 +1016,17 @@ void readdepth(int w, int h, vec &pos) pos = vec(world.x, world.y, world.z).div(world.w); } +VARP(ignoreoverride_nowaterreflect, 0, 0, 1); +VARP(ignoreoverride_nostencilshadows, 0, 0, 1); + +int effective_stencilshadow = 0; + void gl_drawframe(int w, int h, float changelod, float curfps) { + extern int mapoverride_nostencilshadows, mapoverride_nowaterreflect; + effective_stencilshadow = mapoverride_nostencilshadows && !ignoreoverride_nostencilshadows ? 0 : stencilshadow; + bool effective_waterreflect = waterreflect && (!mapoverride_nowaterreflect || ignoreoverride_nowaterreflect); + dodynlights(); drawminimap(w, h); @@ -1055,7 +1064,7 @@ void gl_drawframe(int w, int h, float changelod, float curfps) transplayer(); readmatrices(); - if(!underwater && waterreflect) + if(!underwater && effective_waterreflect) { extern int wx1; if(wx1>=0) @@ -1066,8 +1075,8 @@ void gl_drawframe(int w, int h, float changelod, float curfps) } } - if(stencilshadow && hasstencil && stencilbits >= 8) glClearStencil((hasSTS || hasST2) && !hasSTW ? 128 : 0); - glClear((outsidemap(camera1) ? GL_COLOR_BUFFER_BIT : 0) | GL_DEPTH_BUFFER_BIT | (stencilshadow && hasstencil && stencilbits >= 8 ? GL_STENCIL_BUFFER_BIT : 0)); + if(effective_stencilshadow && hasstencil && stencilbits >= 8) glClearStencil((hasSTS || hasST2) && !hasSTW ? 128 : 0); + glClear((outsidemap(camera1) ? GL_COLOR_BUFFER_BIT : 0) | GL_DEPTH_BUFFER_BIT | (effective_stencilshadow && hasstencil && stencilbits >= 8 ? GL_STENCIL_BUFFER_BIT : 0)); glEnable(GL_TEXTURE_2D); @@ -1105,7 +1114,7 @@ void gl_drawframe(int w, int h, float changelod, float curfps) rendermapmodels(); endmodelbatches(); - if(stencilshadow && hasstencil && stencilbits >= 8) drawstencilshadows(); + if(effective_stencilshadow && hasstencil && stencilbits >= 8) drawstencilshadows(); startmodelbatches(); renderentities(); @@ -1133,7 +1142,7 @@ void gl_drawframe(int w, int h, float changelod, float curfps) render_particles(curtime, PT_DECAL_MASK); - int nquads = renderwater(hf, !waterreflect || underwater ? 0 : reflecttex, !waterreflect || !waterrefract || underwater ? 0 : refracttex); + int nquads = renderwater(hf, !effective_waterreflect || underwater ? 0 : reflecttex, !effective_waterreflect || !waterrefract || underwater ? 0 : refracttex); render_particles(curtime, ~PT_DECAL_MASK); diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index cd019fd4..df31ecd1 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -671,7 +671,7 @@ void endmodelbatches(bool flush) } renderbatchedmodel(b.m, bm); } - if(dynshadow && b.m->hasshadows() && (!reflecting || refracting) && (!stencilshadow || !hasstencil || stencilbits < 8)) + if(dynshadow && b.m->hasshadows() && (!reflecting || refracting) && (!effective_stencilshadow || !hasstencil || stencilbits < 8)) { loopvj(b.batched) { @@ -780,7 +780,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl if(!OUTBORD(x, y)) { sqr *s = S(x, y); - if(!(anim&ANIM_TRANSLUCENT) && dynshadow && m->hasshadows() && (!reflecting || refracting) && (!stencilshadow || !hasstencil || stencilbits < 8)) + if(!(anim&ANIM_TRANSLUCENT) && dynshadow && m->hasshadows() && (!reflecting || refracting) && (!effective_stencilshadow || !hasstencil || stencilbits < 8)) { vec center(o.x, o.y, s->floor); if(s->type==FHF) center.z -= s->vdelta/4.0f; diff --git a/source/src/water.cpp b/source/src/water.cpp index 129da005..78c8f011 100644 --- a/source/src/water.cpp +++ b/source/src/water.cpp @@ -34,7 +34,10 @@ void setwatercolor(const char *r, const char *g, const char *b, const char *a) } COMMANDN(watercolour, setwatercolor, "ssss"); + FVAR(waveheight, 0, 0.3f, 1.0f); +VARP(ignoreoverride_limitwaveheight, 0, 0, 1); +float effective_waveheight = 0.3f; void getwatercolour() { @@ -69,7 +72,7 @@ COMMAND(setwatercolour, "si"); float angle = v1*v2*0.1f/(2*M_PI) + t; \ float s = angle - int(angle) - 0.5f; \ s *= 8 - fabs(s)*16; \ - float h = waveheight*0.5f*s; \ + float h = effective_waveheight*0.5f*s; \ varray::attrib(v1, v2, v3+h); \ body; \ } @@ -81,7 +84,7 @@ COMMAND(setwatercolour, "si"); }) #define VERTWT(vertwt, defbody, body) \ VERTWC(vertwt, defbody, { \ - float duv = waveheight*0.5f*v; \ + float duv = effective_waveheight*0.5f*v; \ body; \ }) @@ -192,6 +195,9 @@ int renderwater(float hf, GLuint reflecttex, GLuint refracttex) { if(wx1<0) return nquads; + extern int mapoverride_limitwaveheight; + effective_waveheight = mapoverride_limitwaveheight && !ignoreoverride_limitwaveheight ? 0.1f : waveheight; + wx1 -= wx1%watersubdiv; wy1 -= wy1%watersubdiv; diff --git a/source/src/world.h b/source/src/world.h index ce779caa..39c2c2b8 100644 --- a/source/src/world.h +++ b/source/src/world.h @@ -55,7 +55,13 @@ enum INVISIBLE = 1<<2 }; -enum { MHF_AUTOMAPCONFIG = 1<<0 }; +enum +{ + MHF_AUTOMAPCONFIG = 1<<0, // autogenerate map-config during map save + MHF_DISABLEWATERREFLECT = 1 << 8, // force waterreflect to zero + MHF_LIMITWATERWAVEHEIGHT = 1 << 9, // limit waveheight to 0.1 + MHF_DISABLESTENCILSHADOWS = 1 << 10 // force stencilshadow to 0 +}; #define MAPVERSION 10 // default map format version to be written (bump if map format changes, see worldio.cpp) diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 34e4e0b8..9ca3452a 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -775,6 +775,17 @@ int maploaded = 0; VAR(curmaprevision, 1, 0, 0); COMMANDF(getmaptimestamp, "s", (char *fmt) { result(hdr.timestamp ? timestring((time_t)hdr.timestamp, *fmt != 'U', *fmt == 'U' ? fmt + 1 : fmt) : "no timestamp stored"); }); +void changemapflag(int val, int mask) +{ + int old = hdr.flags; + if(val) hdr.flags |= mask; + else hdr.flags &= ~mask; + if(editmode && old != hdr.flags) unsavededits++; +} +VARF(mapoverride_nowaterreflect, 0, 0, 1, changemapflag(mapoverride_nowaterreflect, MHF_DISABLEWATERREFLECT)); +VARF(mapoverride_limitwaveheight, 0, 0, 1, changemapflag(mapoverride_limitwaveheight, MHF_LIMITWATERWAVEHEIGHT)); +VARF(mapoverride_nostencilshadows, 0, 0, 1, changemapflag(mapoverride_nostencilshadows, MHF_DISABLESTENCILSHADOWS)); + extern char *mlayout; extern int Mv, Ma, Hhits; extern float Mh; @@ -852,6 +863,9 @@ int load_world(char *mname) // still supports all map formats that have e } if(hdr.version < 10) hdr.waterlevel *= WATERLEVELSCALING; setfvar("waterlevel", float(hdr.waterlevel) / WATERLEVELSCALING); + mapoverride_nowaterreflect = (hdr.flags & MHF_DISABLEWATERREFLECT) ? 1 : 0; + mapoverride_limitwaveheight = (hdr.flags & MHF_LIMITWATERWAVEHEIGHT) ? 1 : 0; + mapoverride_nostencilshadows = (hdr.flags & MHF_DISABLESTENCILSHADOWS) ? 1 : 0; // read and convert all entities persistent_entity *tempents = new persistent_entity[hdr.numents];