fix test cases (implement equals(game) properly, and `is_empty` is false depending on get_content_type for Q2 now)

remove unnecessary condition from Q2 contents_are_empty since areaportals are already considered a valid non-empty type via get_content_type
This commit is contained in:
Jonathan 2022-06-11 09:19:51 -04:00
parent 0dfeff934a
commit 13bf99a7f3
5 changed files with 33 additions and 24 deletions

View File

@ -72,6 +72,8 @@ struct gamedef_generic_t : public gamedef_t
contentflags_t create_detail_solid_contents(const contentflags_t &original) const { throw std::bad_cast(); }
bool contents_are_type_equal(const contentflags_t &self, const contentflags_t &other) const { throw std::bad_cast(); }
bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const { throw std::bad_cast(); }
bool contents_are_any_detail(const contentflags_t &) const { throw std::bad_cast(); }
@ -130,7 +132,7 @@ struct q1_contentflags_data
constexpr bool operator==(const q1_contentflags_data &other) const { return origin == other.origin && clip == other.clip; }
constexpr bool operator!=(const q1_contentflags_data &other) const { return !(*this == other); }
constexpr explicit operator bool() const { return origin && clip; }
constexpr explicit operator bool() const { return origin || clip; }
};
template<gameid_t ID>
@ -156,7 +158,7 @@ struct gamedef_q1_like_t : public gamedef_t
contentflags_t cluster_contents(const contentflags_t &contents0, const contentflags_t &contents1) const
{
if (contents0 == contents1)
if (contents0.equals(this, contents1))
return contents0;
/*
@ -251,7 +253,7 @@ struct gamedef_q1_like_t : public gamedef_t
return {0, CFLAGS_DETAIL};
}
bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const
bool contents_are_type_equal(const contentflags_t &self, const contentflags_t &other) const
{
if (self.game_data.has_value() != other.game_data.has_value()) {
return false;
@ -268,6 +270,11 @@ struct gamedef_q1_like_t : public gamedef_t
self.native == other.native;
}
bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const
{
return contents_are_type_equal(self, other);
}
bool contents_are_any_detail(const contentflags_t &contents) const
{
// in Q1, there are only CFLAGS_DETAIL, CFLAGS_DETAIL_ILLUSIONARY, or CFLAGS_DETAIL_FENCE
@ -314,7 +321,7 @@ struct gamedef_q1_like_t : public gamedef_t
bool contents_clip_same_type(const contentflags_t &self, const contentflags_t &other) const
{
return self == other && self.clips_same_type.value_or(true);
return self.equals(this, other) && self.clips_same_type.value_or(true);
}
bool contents_are_empty(const contentflags_t &contents) const
@ -377,7 +384,7 @@ struct gamedef_q1_like_t : public gamedef_t
bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1) const
{
/* If contents values are the same and not solid, can see through */
return !(contents0.is_solid(this) || contents1.is_solid(this)) && contents0 == contents1;
return !(contents0.is_solid(this) || contents1.is_solid(this)) && contents0.equals(this, contents1);
}
bool contents_seals_map(const contentflags_t &contents) const override
@ -672,12 +679,18 @@ struct gamedef_q2_t : public gamedef_t
return result;
}
bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const
bool contents_are_type_equal(const contentflags_t &self, const contentflags_t &other) const
{
return (self.extended & CFLAGS_CONTENTS_MASK) == (other.extended & CFLAGS_CONTENTS_MASK) &&
get_content_type(self) == get_content_type(other);
}
bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const
{
return (self.extended & CFLAGS_CONTENTS_MASK) == (other.extended & CFLAGS_CONTENTS_MASK) &&
self.native == other.native;
}
bool contents_are_any_detail(const contentflags_t &contents) const
{
return ((contents.native & Q2_CONTENTS_DETAIL) != 0);
@ -746,11 +759,7 @@ struct gamedef_q2_t : public gamedef_t
if (contents.extended & CFLAGS_CONTENTS_MASK)
return false;
if (contents.native & Q2_CONTENTS_AREAPORTAL)
return false; // HACK: needs to return false in order for LinkConvexFaces to assign Q2_CONTENTS_AREAPORTAL
// to the leaf
return !(contents.native & Q2_ALL_VISIBLE_CONTENTS);
return !get_content_type(contents);
}
bool contents_are_solid(const contentflags_t &contents) const
@ -1179,9 +1188,16 @@ bool surfflags_t::is_valid(const gamedef_t *game) const
return game->surfflags_are_valid(*this);
}
bool contentflags_t::equals(const gamedef_t *game, const contentflags_t &other) const
{
return game->contents_are_equal(*this, other) &&
mirror_inside == other.mirror_inside &&
clips_same_type == other.clips_same_type;
}
bool contentflags_t::types_equal(const contentflags_t &other, const gamedef_t *game) const
{
return game->contents_are_equal(*this, other);
return game->contents_are_type_equal(*this, other);
}
int32_t contentflags_t::priority(const gamedef_t *game) const

View File

@ -598,12 +598,7 @@ struct contentflags_t
// don't check this directly, use `will_clip_same_type` to allow the game to decide.
std::optional<bool> clips_same_type = std::nullopt;
constexpr bool operator==(const contentflags_t &other) const
{
return native == other.native && extended == other.extended;
}
constexpr bool operator!=(const contentflags_t &other) const { return !(*this == other); }
bool equals(const gamedef_t *game, const contentflags_t &other) const;
// is any kind of detail? (solid, liquid, etc.)
bool is_any_detail(const gamedef_t *game) const;
@ -1817,6 +1812,7 @@ struct gamedef_t
virtual contentflags_t create_detail_illusionary_contents(const contentflags_t &original) const = 0;
virtual contentflags_t create_detail_fence_contents(const contentflags_t &original) const = 0;
virtual contentflags_t create_detail_solid_contents(const contentflags_t &original) const = 0;
virtual bool contents_are_type_equal(const contentflags_t &self, const contentflags_t &other) const = 0;
virtual bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const = 0;
virtual bool contents_are_any_detail(const contentflags_t &contents) const = 0;
virtual bool contents_are_detail_solid(const contentflags_t &contents) const = 0;

View File

@ -1134,10 +1134,6 @@ struct twosided
// swap the front and back values
constexpr void swap() { std::swap(front, back); }
// equality checks
constexpr bool operator==(const twosided &other) const { return front == other.front && back == other.back; }
constexpr bool operator!=(const twosided &other) const { return !(*this == other); }
};
namespace qv {

View File

@ -940,7 +940,7 @@ static void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int
* include them in the model bounds so collision detection works
* correctly.
*/
if (contents.is_clip(options.target_game) && hullnum != HULL_COLLISION) {
if (hullnum != HULL_COLLISION && contents.is_clip(options.target_game)) {
if (hullnum == 0) {
std::optional<brush_t> brush = LoadBrush(src, mapbrush, contents, rotate_offset, rottype, hullnum);

View File

@ -69,7 +69,8 @@ static face_t *TryMerge(face_t *f1, face_t *f2)
bool keep1, keep2;
if (!f1->w.size() || !f2->w.size() || f1->planeside != f2->planeside || f1->texinfo != f2->texinfo ||
f1->contents != f2->contents || f1->lmshift != f2->lmshift)
!f1->contents[0].equals(options.target_game, f2->contents[0]) || !f1->contents[1].equals(options.target_game, f2->contents[1]) ||
f1->lmshift[0] != f2->lmshift[0] || f1->lmshift[1] != f2->lmshift[1])
return NULL;
// find a common edge