1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-30 02:05:13 +01:00

Allow patrol areas to be single tiles

Change the patrol areas to be stored as a sorted list of points grouped in fixed cells for each staff entity. The complexity will be a mixed O(1) and O(log n) search.
This commit is contained in:
Ted John
2022-03-02 00:44:11 +00:00
parent b6175bb556
commit 566bc4d311
6 changed files with 175 additions and 94 deletions

View File

@@ -2015,64 +2015,23 @@ namespace OpenRCT2
cs.ReadWrite(guest.ItemFlags);
}
static std::vector<TileCoordsXY> GetPatrolArea(Staff& staff)
{
std::vector<TileCoordsXY> area;
if (staff.PatrolInfo != nullptr)
{
for (size_t i = 0; i < STAFF_PATROL_AREA_SIZE; i++)
{
// 32 blocks per array item (32 bits)
auto arrayItem = staff.PatrolInfo->Data[i];
for (size_t j = 0; j < 32; j++)
{
auto blockIndex = (i * 32) + j;
if (arrayItem & (1 << j))
{
auto sx = (blockIndex % STAFF_PATROL_AREA_BLOCKS_PER_LINE) * 4;
auto sy = (blockIndex / STAFF_PATROL_AREA_BLOCKS_PER_LINE) * 4;
for (size_t y = 0; y < 4; y++)
{
for (size_t x = 0; x < 4; x++)
{
area.push_back({ static_cast<int32_t>(sx + x), static_cast<int32_t>(sy + y) });
}
}
}
}
}
}
return area;
}
static void SetPatrolArea(Staff& staff, const std::vector<TileCoordsXY>& area)
{
if (area.empty())
{
staff.ClearPatrolArea();
}
else
{
for (const auto& coord : area)
{
staff.SetPatrolArea(coord.ToCoordsXY(), true);
}
}
}
template<> void ParkFile::ReadWriteEntity(OrcaStream& os, OrcaStream::ChunkStream& cs, Staff& entity)
{
ReadWritePeep(os, cs, entity);
std::vector<TileCoordsXY> patrolArea;
if (cs.GetMode() == OrcaStream::Mode::WRITING)
if (cs.GetMode() == OrcaStream::Mode::WRITING && entity.PatrolInfo != nullptr)
{
patrolArea = GetPatrolArea(entity);
patrolArea = entity.PatrolInfo->ToVector();
}
cs.ReadWriteVector(patrolArea, [&cs](TileCoordsXY& value) { cs.ReadWrite(value); });
if (cs.GetMode() == OrcaStream::Mode::READING)
{
SetPatrolArea(entity, patrolArea);
if (entity.PatrolInfo == nullptr)
entity.PatrolInfo = new PatrolArea();
else
entity.PatrolInfo->Clear();
entity.PatrolInfo->Union(patrolArea);
}
if (os.GetHeader().TargetVersion <= 1)