Fix saves sometimes being one cell larger than intended

Namely, when any dimension of the underlying particle area is divisible by CELL. Importantly, this includes "normal" saves (as opposed to stamps), which take the entire simulation area, making them impossible to load.

Broken by c2bb77721208, where RectBetween(topLeft / CELL, bottomRight / CELL) was rewritten to RectSized(pos / CELL, size / CELL), which is not equivalent. This commit also neglected to add TopLeft() and BottomRight() to Rect. Incorrectly fixed by 6a903ed132b3, where RectSized(pos / CELL, size / CELL) was rewritten to RectBetween(pos / CELL, (pos + size) / CELL), which is also not equivalent.
This commit is contained in:
Tamás Bálint Misius 2024-10-16 07:59:04 +02:00
parent 7353894618
commit 8cab4ab738
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
2 changed files with 13 additions and 1 deletions

View File

@ -380,6 +380,18 @@ public:
return point.X >= pos.X && point.X < pos.X + size.X && point.Y >= pos.Y && point.Y < pos.Y + size.Y; return point.X >= pos.X && point.X < pos.X + size.X && point.Y >= pos.Y && point.Y < pos.Y + size.Y;
} }
template<typename S = T, typename = std::enable_if_t<std::is_integral_v<S>>>
inline Vec2<T> TopLeft() const
{
return pos;
}
template<typename S = T, typename = std::enable_if_t<std::is_integral_v<S>>>
inline Vec2<T> BottomRight() const
{
return pos + size - Vec2<T>(1, 1);
}
template<typename S> template<typename S>
Rect<decltype(std::declval<T>() + std::declval<S>())> Inset(S delta) const Rect<decltype(std::declval<T>() + std::declval<S>())> Inset(S delta) const
{ {

View File

@ -312,7 +312,7 @@ void Simulation::Load(const GameSave *save, bool includePressure, Vec2<int> bloc
std::unique_ptr<GameSave> Simulation::Save(bool includePressure, Rect<int> partR) // particle coordinates std::unique_ptr<GameSave> Simulation::Save(bool includePressure, Rect<int> partR) // particle coordinates
{ {
auto blockR = RectBetween(partR.pos / CELL, (partR.pos + partR.size) / CELL); auto blockR = RectBetween(partR.TopLeft() / CELL, partR.BottomRight() / CELL);
auto blockP = blockR.pos; auto blockP = blockR.pos;
auto newSave = std::make_unique<GameSave>(blockR.size); auto newSave = std::make_unique<GameSave>(blockR.size);