diff --git a/common/bspfile.cc b/common/bspfile.cc index 36071be5..72ce3212 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -98,7 +98,7 @@ struct gamedef_generic_t : public gamedef_t bool contents_are_valid(const contentflags_t &, bool) const override { throw std::bad_cast(); } - bool portal_can_see_through(const contentflags_t &, const contentflags_t &) const override { throw std::bad_cast(); } + bool portal_can_see_through(const contentflags_t &, const contentflags_t &, bool, bool) const override { throw std::bad_cast(); } bool contents_seals_map(const contentflags_t &contents) const override { throw std::bad_cast(); } @@ -385,8 +385,24 @@ public: } } - bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1) const + bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1, bool transwater, bool transsky) const { + /* If water is transparent, liquids are like empty space */ + if (transwater) { + if (contents_are_liquid(contents0) && contents_are_empty(contents1)) + return true; + if (contents_are_liquid(contents1) && contents_are_empty(contents0)) + return true; + } + + /* If sky is transparent, then sky is like empty space */ + if (transsky) { + if (contents_are_sky(contents0) && contents_are_empty(contents1)) + return true; + if (contents_are_empty(contents0) && contents_are_sky(contents1)) + return true; + } + /* If contents values are the same and not solid, can see through */ return !(contents0.is_solid(this) || contents1.is_solid(this)) && contents0.equals(this, contents1); } @@ -918,7 +934,7 @@ struct gamedef_q2_t : public gamedef_t return 0; } - bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1) const + bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1, bool, bool) const { int32_t c0 = contents0.native, c1 = contents1.native; diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index 99084b7a..287e8fba 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -1810,7 +1810,7 @@ struct gamedef_t virtual bool contents_are_sky(const contentflags_t &contents) const = 0; virtual bool contents_are_liquid(const contentflags_t &contents) const = 0; virtual bool contents_are_valid(const contentflags_t &contents, bool strict = true) const = 0; - virtual bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1) const = 0; + virtual bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1, bool transwater, bool transsky) const = 0; virtual bool contents_seals_map(const contentflags_t &contents) const = 0; virtual contentflags_t contents_remap_for_export(const contentflags_t &contents) const = 0; virtual contentflags_t combine_contents(const contentflags_t &a, const contentflags_t &b) const = 0; diff --git a/qbsp/portals.cc b/qbsp/portals.cc index 245af472..9d7fb495 100644 --- a/qbsp/portals.cc +++ b/qbsp/portals.cc @@ -77,28 +77,8 @@ static bool PortalThru(const portal_t *p) if (contents0.illusionary_visblocker || contents1.illusionary_visblocker) return false; - // FIXME: we can't move this directly to portal_can_see_through because - // "options" isn't exposed there. - if (options.target_game->id != GAME_QUAKE_II) { - /* If water is transparent, liquids are like empty space */ - if (options.transwater.value()) { - if (contents0.is_liquid(options.target_game) && contents1.is_empty(options.target_game)) - return true; - if (contents1.is_liquid(options.target_game) && contents0.is_empty(options.target_game)) - return true; - } - - /* If sky is transparent, then sky is like empty space */ - if (options.transsky.value()) { - if (contents0.is_sky(options.target_game) && contents1.is_empty(options.target_game)) - return true; - if (contents0.is_empty(options.target_game) && contents1.is_sky(options.target_game)) - return true; - } - } - // Check per-game visibility - return options.target_game->portal_can_see_through(contents0, contents1); + return options.target_game->portal_can_see_through(contents0, contents1, options.transwater.value(), options.transsky.value()); } static void WritePortals_r(node_t *node, std::ofstream &portalFile, bool clusters)