diff --git a/include/qbsp/qbsp.hh b/include/qbsp/qbsp.hh index 09aaf02d..c4820576 100644 --- a/include/qbsp/qbsp.hh +++ b/include/qbsp/qbsp.hh @@ -115,6 +115,7 @@ #define CFLAGS_STRUCTURAL_COVERED_BY_DETAIL (1U << 0) #define CFLAGS_WAS_ILLUSIONARY (1U << 1) /* was illusionary, got changed to something else */ #define CFLAGS_DETAIL_WALL (1U << 2) /* don't clip world for func_detail_wall entities */ +#define CFLAGS_BMODEL_MIRROR_INSIDE (1U << 3) /* set "_mirrorinside" "1" on a bmodel to mirror faces for when the player is inside. */ // Texture flags. Only TEX_SPECIAL is written to the .bsp. // Extended flags are written to a .texinfo file and read by the light tool diff --git a/man/qbsp.1 b/man/qbsp.1 index db7cf4fc..8fbc8d2b 100644 --- a/man/qbsp.1 +++ b/man/qbsp.1 @@ -239,6 +239,9 @@ Similar to func_detail_wall except it's suitable for fence textures, never clips .IP "\fB""_lmscale"" ""n""\fP" Generates an LMSHIFT bspx lump for use by a light util. Note that both scaled and unscaled lighting will normally be used. +.IP "\fB""_mirrorinside"" ""n""\fP" +Set to 1 to save mirrored inside faces for bmodels, so when the player view is inside the bmodel, they will still see the faces. (e.g. for func_water, or func_illusionary) + .SH MAP COMPATIBILITY In addition to standard Quake 1 .map files, TyrUtils QBSP is compatible with: diff --git a/qbsp/brush.cc b/qbsp/brush.cc index ff92375f..06fbf2d9 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -1118,6 +1118,11 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum) i /= 2; } + /* _mirrorinside key (for func_water etc.) */ + if (atoi(ValueForKey(src, "_mirrorinside"))) { + cflags |= CFLAGS_BMODEL_MIRROR_INSIDE; + } + for (i = 0; i < src->nummapbrushes; i++, mapbrush++) { mapbrush = &src->mapbrush(i); contents = Brush_GetContents(mapbrush); diff --git a/qbsp/csg4.cc b/qbsp/csg4.cc index 913ce7a8..85a65946 100644 --- a/qbsp/csg4.cc +++ b/qbsp/csg4.cc @@ -356,7 +356,11 @@ SaveFacesToPlaneList(face_t *facelist, bool mirror, std::map &pla || face->contents[1] == CONTENTS_DETAIL_FENCE || (face->cflags[1] & CFLAGS_WAS_ILLUSIONARY) || face->contents[1] == CONTENTS_SOLID) { - newface->texinfo = MakeSkipTexinfo(); + + // if CFLAGS_BMODEL_MIRROR_INSIDE is set, never change to skip + if (!(face->cflags[1] & CFLAGS_BMODEL_MIRROR_INSIDE)) { + newface->texinfo = MakeSkipTexinfo(); + } } for (int i = 0; i < face->w.numpoints; i++)