1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-05-10 19:13:44 +00:00

Fix logic oversights that would sometimes mess up map tiles when moved to front or back

This commit is contained in:
fgenesis 2024-05-12 17:45:01 +02:00
parent cd50cf6b70
commit b4acacf3bc
2 changed files with 29 additions and 17 deletions

View file

@ -23,7 +23,7 @@ TileStorage::Sizes TileStorage::stats() const
return sz; return sz;
} }
void TileStorage::moveToFront(const size_t *indices, size_t n) void TileStorage::moveToFront(size_t *indices, size_t n)
{ {
if(n) if(n)
{ {
@ -32,7 +32,7 @@ void TileStorage::moveToFront(const size_t *indices, size_t n)
} }
} }
void TileStorage::moveToBack(const size_t *indices, size_t n) void TileStorage::moveToBack(size_t *indices, size_t n)
{ {
if(n) if(n)
{ {
@ -60,7 +60,7 @@ void TileStorage::doInteraction(const Vector& pos, const Vector& vel, float mult
} }
} }
void TileStorage::_moveToFront(const size_t *indices, size_t n) void TileStorage::_moveToFront(size_t *indices, size_t n)
{ {
// move tile to front -> move it to the back of the list, to be rendered last aka on top of everything else // move tile to front -> move it to the back of the list, to be rendered last aka on top of everything else
@ -68,14 +68,15 @@ void TileStorage::_moveToFront(const size_t *indices, size_t n)
{ {
TileData tile = tiles[*indices]; TileData tile = tiles[*indices];
tiles.erase(tiles.begin() + *indices); tiles.erase(tiles.begin() + *indices);
*indices = tiles.size();
tiles.push_back(tile); tiles.push_back(tile);
return; return;
} }
_moveToPos(size(), indices, n); _moveToPos(MV_END, indices, n);
} }
void TileStorage::_moveToBack(const size_t *indices, size_t n) void TileStorage::_moveToBack(size_t *indices, size_t n)
{ {
// move tile to back -> move it to the front of the list, to be rendered first aka underneath everything else // move tile to back -> move it to the front of the list, to be rendered first aka underneath everything else
@ -84,28 +85,33 @@ void TileStorage::_moveToBack(const size_t *indices, size_t n)
TileData tile = tiles[*indices]; TileData tile = tiles[*indices];
tiles.erase(tiles.begin() + *indices); tiles.erase(tiles.begin() + *indices);
tiles.insert(tiles.begin(), tile); tiles.insert(tiles.begin(), tile);
*indices = 0;
return; return;
} }
_moveToPos(0, indices, n); _moveToPos(MV_BEGIN, indices, n);
} }
void TileStorage::_moveToPos(size_t where, const size_t * indices, size_t n) void TileStorage::_moveToPos(MoveTarget where, size_t * indices, size_t n)
{ {
std::vector<size_t> tmp(indices, indices + n); std::vector<size_t> tmp(indices, indices + n);
std::sort(tmp.begin(), tmp.end());
std::vector<TileData> tt(n); std::vector<TileData> tt(n);
// sorted indices -> preserve relative order of tiles // unsorted indices -> preserve relative order of tiles
for(size_t i = 0; i < n; ++i) for(size_t i = 0; i < n; ++i)
tt[i] = tiles[tmp[i]]; tt[i] = tiles[tmp[i]];
std::sort(tmp.begin(), tmp.end());
// SORTED indices, erasing from the BACK -> we don't get a destructive index shift // SORTED indices, erasing from the BACK -> we don't get a destructive index shift
for(size_t i = tmp.size(); i --> 0; ) for(size_t i = n; i --> 0; )
tiles.erase(tiles.begin() + tmp[i]); tiles.erase(tiles.begin() + tmp[i]);
tiles.insert(tiles.begin() + where, tt.begin(), tt.end()); size_t offs = where == MV_BEGIN ? 0 : tiles.size();
tiles.insert(tiles.begin() + offs, tt.begin(), tt.end());
for(size_t i = 0; i < n; ++i)
indices[i] = i + offs;
} }
size_t TileStorage::moveToOther(TileStorage& other, const size_t *indices, size_t n) size_t TileStorage::moveToOther(TileStorage& other, const size_t *indices, size_t n)

View file

@ -220,8 +220,9 @@ public:
TileStorage(); TileStorage();
~TileStorage(); ~TileStorage();
void moveToFront(const size_t *indices, size_t n); // Pass in old indices, updates indices where the tiles are afterwards
void moveToBack(const size_t *indices, size_t n); void moveToFront(size_t *indices, size_t n);
void moveToBack(size_t *indices, size_t n);
// returns starting index of new tiles. Since new tiles are always appended at the end, // returns starting index of new tiles. Since new tiles are always appended at the end,
// the new indices corresponding to the moved tiles are [retn .. retn+n) // the new indices corresponding to the moved tiles are [retn .. retn+n)
@ -254,14 +255,19 @@ public:
std::vector<TileData> tiles; // must call refreshAll() after changing this std::vector<TileData> tiles; // must call refreshAll() after changing this
private: private:
enum MoveTarget
{
MV_BEGIN,
MV_END,
};
std::vector<size_t> indicesToUpdate; std::vector<size_t> indicesToUpdate;
std::vector<size_t> indicesToCollide; std::vector<size_t> indicesToCollide;
void _refreshTile(const TileData& t); void _refreshTile(const TileData& t);
void _moveToFront(const size_t *indices, size_t n); void _moveToFront(size_t *indices, size_t n);
void _moveToBack(const size_t *indices, size_t n); void _moveToBack(size_t *indices, size_t n);
void _moveToPos(size_t where, const size_t *indices, size_t n); void _moveToPos(MoveTarget where, size_t *indices, size_t n);
TileStorage(const TileStorage&); // no-copy TileStorage(const TileStorage&); // no-copy
}; };