1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +01:00

Fix areas with a temporary workaround.

This commit is contained in:
Sandu Liviu Catalin 2022-03-16 21:58:00 +02:00
parent 1c7fee69ea
commit 38f0a53cd8
2 changed files with 61 additions and 9 deletions

View File

@ -161,7 +161,7 @@ bool Area::IsInside(float x, float y) const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AreaManager::AreaManager(size_t sz) noexcept AreaManager::AreaManager(size_t sz) noexcept
: m_Queue(), m_ProcList(), m_Grid{} : m_Queue(), m_ProcList(), m_Grid{}, m_Cells{}
{ {
// Negative half grid size (left) // Negative half grid size (left)
int l = (-GRIDH * CELLD); int l = (-GRIDH * CELLD);
@ -171,21 +171,30 @@ AreaManager::AreaManager(size_t sz) noexcept
int r = (l + CELLD); int r = (l + CELLD);
// Positive half grid size (top) // Positive half grid size (top)
int t = abs(l); int t = abs(l);
// Row/Column of the grid
int row = 0, col = 0;
// Initialize the grid cells // Initialize the grid cells
for (auto & a : m_Grid) for (auto & a : m_Grid)
{ {
// Reset the column
col = 0;
// Process row
for (auto & c : a) for (auto & c : a)
{ {
auto & cx = m_Cells[row][col];
// Grab a reference to the cell // Grab a reference to the cell
// Configure the range of the cell // Configure the range of the cell
c.mL = static_cast< float >(l); c.mL = cx.mL = static_cast< float >(l);
c.mB = static_cast< float >(b); c.mB = cx.mB = static_cast< float >(b);
c.mR = static_cast< float >(r); c.mR = cx.mR = static_cast< float >(r);
c.mT = static_cast< float >(t); c.mT = cx.mT = static_cast< float >(t);
// Reserve area memory if requested // Reserve area memory if requested
c.mAreas.reserve(sz); c.mAreas.reserve(sz);
// Reset the locks on this area // Reset the locks on this area
c.mLocks = 0; c.mLocks = 0;
// Set the row and column
c.mRow = row;
c.mCol = col++;
// Advance the left side // Advance the left side
l = r; l = r;
// Advance the right side // Advance the right side
@ -203,6 +212,8 @@ AreaManager::AreaManager(size_t sz) noexcept
t -= CELLD; t -= CELLD;
} }
} }
// Advance row
++row;
} }
// Reserve some space in the queue // Reserve some space in the queue
m_Queue.reserve(128); m_Queue.reserve(128);
@ -340,6 +351,21 @@ void AreaManager::RemoveArea(Area & a)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Vector2i AreaManager::LocateCell(float x, float y) Vector2i AreaManager::LocateCell(float x, float y)
{ {
for (int r = 0; r < GRIDN; ++r)
{
for (int c = 0; c < GRIDN; ++c)
{
auto & bb = m_Cells[r][c];
// Check whether point is inside cell
if (bb.mL <= x && bb.mR >= x && bb.mB <= y && bb.mT >= y)
{
return {r, c}; // Is inside
}
}
}
// Not found
return {NOCELL, NOCELL};
/*
// Transform the world coordinates into a cell coordinates // Transform the world coordinates into a cell coordinates
// and cast to integral after rounding the value // and cast to integral after rounding the value
int xc = static_cast< int >(std::round(x / CELLD)); int xc = static_cast< int >(std::round(x / CELLD));
@ -364,6 +390,7 @@ Vector2i AreaManager::LocateCell(float x, float y)
} }
// Return the identified cell row and column // Return the identified cell row and column
return {GRIDH+xc, GRIDH-yc}; return {GRIDH+xc, GRIDH-yc};
*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -469,6 +496,7 @@ void Register_Areas(HSQUIRRELVM vm)
.Func(_SC("TestEx"), &Area::TestEx) .Func(_SC("TestEx"), &Area::TestEx)
.Func(_SC("Manage"), &Area::Manage) .Func(_SC("Manage"), &Area::Manage)
.Func(_SC("Unmanage"), &Area::Unmanage) .Func(_SC("Unmanage"), &Area::Unmanage)
.CbFunc(_SC("EachCell"), &Area::EachCell)
// Static Functions // Static Functions
.StaticFunc(_SC("GlobalTest"), &Areas_TestPoint) .StaticFunc(_SC("GlobalTest"), &Areas_TestPoint)
.StaticFunc(_SC("GlobalTestEx"), &Areas_TestPointEx) .StaticFunc(_SC("GlobalTestEx"), &Areas_TestPointEx)

View File

@ -29,15 +29,25 @@ struct AreaCell
Areas mAreas; // Areas that intersect with the cell. Areas mAreas; // Areas that intersect with the cell.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
int mLocks; // The amount of locks on the cell. int mLocks; // The amount of locks on the cell.
int mRow; // Row location in the grid.
int mCol; // Column location in the grid.
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Default constructor. * Default constructor.
*/ */
AreaCell() AreaCell()
: mL(0), mB(0), mR(0), mT(0), mAreas(0), mLocks(0) : mL(0), mB(0), mR(0), mT(0), mAreas(0), mLocks(0), mRow(0), mCol(0)
{ {
//... //...
} }
/* --------------------------------------------------------------------------------------------
* Show information (mainly for debug purposes).
*/
String Dump()
{
return fmt::format("({} : {} | {} : {}) {} : {}", mL, mB, mR, mT, mRow, mCol);
}
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@ -454,6 +464,17 @@ struct Area
*/ */
bool Unmanage(); bool Unmanage();
/* --------------------------------------------------------------------------------------------
* Iterate all managed cells through a functor.
*/
void EachCell(Function & fn) const
{
for (const auto & e : mCells)
{
fn.Execute(static_cast< SQInteger >(e->mRow), static_cast< SQInteger >(e->mCol));
}
}
protected: protected:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@ -610,7 +631,10 @@ private:
ProcList m_ProcList; // Actions ready to be completed. ProcList m_ProcList; // Actions ready to be completed.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
AreaCell m_Grid[GRIDN][GRIDN]; // A grid of area lists. AreaCell m_Grid[GRIDN][GRIDN]; // A grid of area lists.
// --------------------------------------------------------------------------------------------
struct {
float mL, mB, mR, mT;
} m_Cells[GRIDN][GRIDN];
public: public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@ -664,7 +688,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Clear all cell lists and release any script references. * Clear all cell lists and release any script references.
*/ */
static Vector2i LocateCell(float x, float y); Vector2i LocateCell(float x, float y);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Test a point to see whether it intersects with any areas * Test a point to see whether it intersects with any areas
@ -679,7 +703,7 @@ public:
return; // Not our problem return; // Not our problem
} }
// Retrieve a reference to the identified cell // Retrieve a reference to the identified cell
AreaCell & c = m_Grid[cc.y][cc.x]; AreaCell & c = m_Grid[cc.x][cc.y];
// Is this cell empty? // Is this cell empty?
if (c.mAreas.empty()) if (c.mAreas.empty())
{ {