mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor patrol area class to new file
This commit is contained in:
parent
566bc4d311
commit
90718ca81c
|
@ -23,6 +23,7 @@
|
|||
#include <openrct2/actions/StaffSetPatrolAreaAction.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/entity/EntityRegistry.h>
|
||||
#include <openrct2/entity/PatrolArea.h>
|
||||
#include <openrct2/entity/Staff.h>
|
||||
#include <openrct2/localisation/Formatter.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
|
@ -550,7 +551,7 @@ void WindowStaffOverviewDropdown(rct_window* w, rct_widgetindex widgetIndex, int
|
|||
if (!tool_set(w, widgetIndex, Tool::WalkDown))
|
||||
{
|
||||
show_gridlines();
|
||||
gStaffDrawPatrolAreas = w->number;
|
||||
SetPatrolAreaToRender(EntityId::FromUnderlying(w->number));
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
}
|
||||
|
@ -1282,7 +1283,7 @@ void WindowStaffOverviewToolAbort(rct_window* w, rct_widgetindex widgetIndex)
|
|||
else if (widgetIndex == WIDX_PATROL)
|
||||
{
|
||||
hide_gridlines();
|
||||
gStaffDrawPatrolAreas = 0xFFFF;
|
||||
ClearPatrolAreaToRender();
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/entity/EntityList.h>
|
||||
#include <openrct2/entity/EntityRegistry.h>
|
||||
#include <openrct2/entity/PatrolArea.h>
|
||||
#include <openrct2/entity/Staff.h>
|
||||
#include <openrct2/localisation/Formatter.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
|
@ -141,7 +142,7 @@ public:
|
|||
if (!tool_set(this, WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON, Tool::Crosshair))
|
||||
{
|
||||
show_gridlines();
|
||||
gStaffDrawPatrolAreas = _selectedTab | 0x8000;
|
||||
SetPatrolAreaToRender(GetSelectedStaffType());
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
break;
|
||||
|
@ -471,7 +472,7 @@ public:
|
|||
{
|
||||
hide_gridlines();
|
||||
tool_cancel();
|
||||
gStaffDrawPatrolAreas = 0xFFFF;
|
||||
ClearPatrolAreaToRender();
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
}
|
||||
|
@ -593,7 +594,7 @@ private:
|
|||
if (footpathCoords.IsNull())
|
||||
return nullptr;
|
||||
|
||||
auto isPatrolAreaSet = staff_is_patrol_area_set_for_type(GetSelectedStaffType(), footpathCoords);
|
||||
auto isPatrolAreaSet = IsPatrolAreaSetForStaffType(GetSelectedStaffType(), footpathCoords);
|
||||
|
||||
Peep* closestPeep = nullptr;
|
||||
auto closestPeepDistance = std::numeric_limits<int32_t>::max();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "entity/EntityList.h"
|
||||
#include "entity/EntityRegistry.h"
|
||||
#include "entity/Guest.h"
|
||||
#include "entity/PatrolArea.h"
|
||||
#include "entity/Staff.h"
|
||||
#include "interface/Viewport.h"
|
||||
#include "interface/Window_internal.h"
|
||||
|
@ -350,7 +351,7 @@ namespace Editor
|
|||
}
|
||||
|
||||
ResetAllEntities();
|
||||
staff_reset_modes();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
gNumGuestsInPark = 0;
|
||||
gNumGuestsHeadingForPark = 0;
|
||||
gNumGuestsInParkLastWeek = 0;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "core/FileScanner.h"
|
||||
#include "core/Path.hpp"
|
||||
#include "entity/EntityRegistry.h"
|
||||
#include "entity/PatrolArea.h"
|
||||
#include "entity/Peep.h"
|
||||
#include "entity/Staff.h"
|
||||
#include "interface/Colour.h"
|
||||
|
@ -448,7 +449,7 @@ void game_fix_save_vars()
|
|||
// Fix gParkEntrance locations for which the tile_element no longer exists
|
||||
fix_park_entrance_locations();
|
||||
|
||||
staff_update_greyed_patrol_areas();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
}
|
||||
|
||||
void game_load_init()
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "actions/GameAction.h"
|
||||
#include "config/Config.h"
|
||||
#include "entity/EntityRegistry.h"
|
||||
#include "entity/PatrolArea.h"
|
||||
#include "entity/Staff.h"
|
||||
#include "interface/Screenshot.h"
|
||||
#include "localisation/Date.h"
|
||||
|
@ -67,7 +68,7 @@ void GameState::InitAll(const TileCoordsXY& mapSize)
|
|||
banner_init();
|
||||
ride_init_all();
|
||||
ResetAllEntities();
|
||||
staff_reset_modes();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
date_reset();
|
||||
climate_reset(ClimateType::CoolAndWet);
|
||||
News::InitQueue();
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "StaffSetPatrolAreaAction.h"
|
||||
|
||||
#include "../entity/EntityRegistry.h"
|
||||
#include "../entity/PatrolArea.h"
|
||||
#include "../entity/Peep.h"
|
||||
#include "../entity/Staff.h"
|
||||
#include "../interface/Window.h"
|
||||
|
@ -97,7 +98,7 @@ GameActions::Result StaffSetPatrolAreaAction::Execute() const
|
|||
break;
|
||||
}
|
||||
|
||||
staff_update_greyed_patrol_areas();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
|
||||
return GameActions::Result();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2022 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "PatrolArea.h"
|
||||
|
||||
#include "EntityList.h"
|
||||
#include "Staff.h"
|
||||
|
||||
static PatrolArea _consolidatedPatrolArea[EnumValue(StaffType::Count)];
|
||||
static std::variant<StaffType, EntityId> _patrolAreaToRender;
|
||||
|
||||
static bool CompareTileCoordsXY(const TileCoordsXY& lhs, const TileCoordsXY& rhs)
|
||||
{
|
||||
if (lhs.y == rhs.y)
|
||||
return lhs.x < rhs.x;
|
||||
return lhs.y < rhs.y;
|
||||
}
|
||||
|
||||
const PatrolArea::Cell* PatrolArea::GetCell(const TileCoordsXY& pos) const
|
||||
{
|
||||
return const_cast<PatrolArea*>(this)->GetCell(pos);
|
||||
}
|
||||
|
||||
PatrolArea::Cell* PatrolArea::GetCell(const TileCoordsXY& pos)
|
||||
{
|
||||
auto areaPos = TileCoordsXY(pos.x / Cell::Width, pos.y / Cell::Height);
|
||||
if (areaPos.x < 0 || areaPos.x >= CellColumns || areaPos.y < 0 || areaPos.y >= CellRows)
|
||||
return nullptr;
|
||||
|
||||
auto& area = Areas[(areaPos.y * CellColumns) + areaPos.x];
|
||||
return &area;
|
||||
}
|
||||
|
||||
bool PatrolArea::IsEmpty() const
|
||||
{
|
||||
return TileCount == 0;
|
||||
}
|
||||
|
||||
void PatrolArea::Clear()
|
||||
{
|
||||
for (auto& area : Areas)
|
||||
{
|
||||
area.SortedTiles.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool PatrolArea::Get(const TileCoordsXY& pos) const
|
||||
{
|
||||
auto* area = GetCell(pos);
|
||||
if (area == nullptr)
|
||||
return false;
|
||||
|
||||
auto it = std::lower_bound(area->SortedTiles.begin(), area->SortedTiles.end(), pos, CompareTileCoordsXY);
|
||||
auto found = it != area->SortedTiles.end() && *it == pos;
|
||||
return found;
|
||||
}
|
||||
|
||||
bool PatrolArea::Get(const CoordsXY& pos) const
|
||||
{
|
||||
return Get(TileCoordsXY(pos));
|
||||
}
|
||||
|
||||
void PatrolArea::Set(const TileCoordsXY& pos, bool value)
|
||||
{
|
||||
auto* area = GetCell(pos);
|
||||
if (area == nullptr)
|
||||
return;
|
||||
|
||||
auto it = std::lower_bound(area->SortedTiles.begin(), area->SortedTiles.end(), pos, CompareTileCoordsXY);
|
||||
auto found = it != area->SortedTiles.end() && *it == pos;
|
||||
|
||||
if (!found && value)
|
||||
{
|
||||
area->SortedTiles.insert(it, pos);
|
||||
TileCount++;
|
||||
}
|
||||
else if (found && !value)
|
||||
{
|
||||
area->SortedTiles.erase(it);
|
||||
assert(TileCount != 0);
|
||||
TileCount--;
|
||||
}
|
||||
}
|
||||
|
||||
void PatrolArea::Set(const CoordsXY& pos, bool value)
|
||||
{
|
||||
Set(TileCoordsXY(pos), value);
|
||||
}
|
||||
|
||||
void PatrolArea::Union(const PatrolArea& other)
|
||||
{
|
||||
for (size_t i = 0; i < Areas.size(); i++)
|
||||
{
|
||||
for (const auto& pos : other.Areas[i].SortedTiles)
|
||||
{
|
||||
Set(pos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatrolArea::Union(const std::vector<TileCoordsXY>& other)
|
||||
{
|
||||
for (const auto& pos : other)
|
||||
{
|
||||
Set(pos, true);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TileCoordsXY> PatrolArea::ToVector() const
|
||||
{
|
||||
std::vector<TileCoordsXY> result;
|
||||
for (const auto& area : Areas)
|
||||
{
|
||||
for (const auto& pos : area.SortedTiles)
|
||||
{
|
||||
result.push_back(pos);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const PatrolArea& GetMergedPatrolArea(const StaffType type)
|
||||
{
|
||||
return _consolidatedPatrolArea[EnumValue(type)];
|
||||
}
|
||||
|
||||
void UpdateConsolidatedPatrolAreas()
|
||||
{
|
||||
for (int32_t staffType = 0; staffType < EnumValue(StaffType::Count); ++staffType)
|
||||
{
|
||||
// Reset all of the merged data for the type.
|
||||
auto& mergedArea = _consolidatedPatrolArea[staffType];
|
||||
mergedArea.Clear();
|
||||
|
||||
for (auto staff : EntityList<Staff>())
|
||||
{
|
||||
if (EnumValue(staff->AssignedStaffType) != staffType)
|
||||
continue;
|
||||
|
||||
if (staff->PatrolInfo == nullptr)
|
||||
continue;
|
||||
|
||||
mergedArea.Union(*staff->PatrolInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsPatrolAreaSetForStaffType(StaffType type, const CoordsXY& coords)
|
||||
{
|
||||
return _consolidatedPatrolArea[EnumValue(type)].Get(coords);
|
||||
}
|
||||
|
||||
std::variant<StaffType, EntityId> GetPatrolAreaToRender()
|
||||
{
|
||||
return _patrolAreaToRender;
|
||||
}
|
||||
|
||||
void ClearPatrolAreaToRender()
|
||||
{
|
||||
SetPatrolAreaToRender(EntityId::GetNull());
|
||||
}
|
||||
|
||||
void SetPatrolAreaToRender(EntityId staffId)
|
||||
{
|
||||
_patrolAreaToRender = staffId;
|
||||
}
|
||||
|
||||
void SetPatrolAreaToRender(StaffType staffType)
|
||||
{
|
||||
_patrolAreaToRender = staffType;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2022 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../world/Map.h"
|
||||
#include "Peep.h"
|
||||
|
||||
#include <variant>
|
||||
|
||||
// The number of elements in the gStaffPatrolAreas array per staff member. Every bit in the array represents a 4x4 square.
|
||||
// Right now, it's a 32-bit array like in RCT2. 32 * 128 = 4096 bits, which is also the number of 4x4 squares on a 256x256 map.
|
||||
constexpr size_t STAFF_PATROL_AREA_BLOCKS_PER_LINE = MAXIMUM_MAP_SIZE_TECHNICAL / 4;
|
||||
constexpr size_t STAFF_PATROL_AREA_SIZE = (STAFF_PATROL_AREA_BLOCKS_PER_LINE * STAFF_PATROL_AREA_BLOCKS_PER_LINE) / 32;
|
||||
|
||||
class PatrolArea
|
||||
{
|
||||
private:
|
||||
struct Cell
|
||||
{
|
||||
static constexpr auto Width = 64;
|
||||
static constexpr auto Height = 64;
|
||||
static constexpr auto NumTiles = Width * Height;
|
||||
|
||||
std::vector<TileCoordsXY> SortedTiles;
|
||||
};
|
||||
|
||||
static constexpr auto CellColumns = (MAXIMUM_MAP_SIZE_TECHNICAL + (Cell::Width - 1)) / Cell::Width;
|
||||
static constexpr auto CellRows = (MAXIMUM_MAP_SIZE_TECHNICAL + (Cell::Height - 1)) / Cell::Height;
|
||||
static constexpr auto NumCells = CellColumns * CellRows;
|
||||
|
||||
std::array<Cell, NumCells> Areas;
|
||||
size_t TileCount{};
|
||||
|
||||
const Cell* GetCell(const TileCoordsXY& pos) const;
|
||||
Cell* GetCell(const TileCoordsXY& pos);
|
||||
|
||||
public:
|
||||
bool IsEmpty() const;
|
||||
void Clear();
|
||||
bool Get(const TileCoordsXY& pos) const;
|
||||
bool Get(const CoordsXY& pos) const;
|
||||
void Set(const TileCoordsXY& pos, bool value);
|
||||
void Set(const CoordsXY& pos, bool value);
|
||||
void Union(const PatrolArea& other);
|
||||
void Union(const std::vector<TileCoordsXY>& other);
|
||||
std::vector<TileCoordsXY> ToVector() const;
|
||||
};
|
||||
|
||||
void UpdateConsolidatedPatrolAreas();
|
||||
bool IsPatrolAreaSetForStaffType(StaffType type, const CoordsXY& coords);
|
||||
std::variant<StaffType, EntityId> GetPatrolAreaToRender();
|
||||
void ClearPatrolAreaToRender();
|
||||
void SetPatrolAreaToRender(EntityId staffId);
|
||||
void SetPatrolAreaToRender(StaffType staffType);
|
|
@ -52,6 +52,7 @@
|
|||
#include "../world/Scenery.h"
|
||||
#include "../world/SmallScenery.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "PatrolArea.h"
|
||||
#include "Staff.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -667,7 +668,7 @@ void peep_sprite_remove(Peep* peep)
|
|||
else
|
||||
{
|
||||
staff->ClearPatrolArea();
|
||||
staff_update_greyed_patrol_areas();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
|
||||
News::DisableNewsItems(News::ItemType::Peep, staff->sprite_index.ToUnderlying());
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "../world/Scenery.h"
|
||||
#include "../world/SmallScenery.h"
|
||||
#include "../world/Surface.h"
|
||||
#include "PatrolArea.h"
|
||||
#include "Peep.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -61,128 +62,10 @@ const rct_string_id StaffCostumeNames[] = {
|
|||
};
|
||||
// clang-format on
|
||||
|
||||
uint16_t gStaffDrawPatrolAreas;
|
||||
colour_t gStaffHandymanColour;
|
||||
colour_t gStaffMechanicColour;
|
||||
colour_t gStaffSecurityColour;
|
||||
|
||||
static PatrolArea _mergedPatrolAreas[EnumValue(StaffType::Count)];
|
||||
|
||||
static bool CompareTileCoordsXY(const TileCoordsXY& lhs, const TileCoordsXY& rhs)
|
||||
{
|
||||
if (lhs.y == rhs.y)
|
||||
return lhs.x < rhs.x;
|
||||
return lhs.y < rhs.y;
|
||||
}
|
||||
|
||||
const PatrolArea::Cell* PatrolArea::GetCell(TileCoordsXY pos) const
|
||||
{
|
||||
return const_cast<PatrolArea*>(this)->GetCell(pos);
|
||||
}
|
||||
|
||||
PatrolArea::Cell* PatrolArea::GetCell(TileCoordsXY pos)
|
||||
{
|
||||
auto areaPos = TileCoordsXY(pos.x / Cell::Width, pos.y / Cell::Height);
|
||||
if (areaPos.x < 0 || areaPos.x >= CellColumns || areaPos.y < 0 || areaPos.y >= CellRows)
|
||||
return nullptr;
|
||||
|
||||
auto& area = Areas[(areaPos.y * CellColumns) + areaPos.x];
|
||||
return &area;
|
||||
}
|
||||
|
||||
bool PatrolArea::IsEmpty() const
|
||||
{
|
||||
return TileCount == 0;
|
||||
}
|
||||
|
||||
void PatrolArea::Clear()
|
||||
{
|
||||
for (auto& area : Areas)
|
||||
{
|
||||
area.SortedTiles.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool PatrolArea::Get(TileCoordsXY pos) const
|
||||
{
|
||||
auto* area = GetCell(pos);
|
||||
if (area == nullptr)
|
||||
return false;
|
||||
|
||||
auto it = std::lower_bound(area->SortedTiles.begin(), area->SortedTiles.end(), pos, CompareTileCoordsXY);
|
||||
auto found = it != area->SortedTiles.end() && *it == pos;
|
||||
return found;
|
||||
}
|
||||
|
||||
bool PatrolArea::Get(CoordsXY pos) const
|
||||
{
|
||||
return Get(TileCoordsXY(pos));
|
||||
}
|
||||
|
||||
void PatrolArea::Set(TileCoordsXY pos, bool value)
|
||||
{
|
||||
auto* area = GetCell(pos);
|
||||
if (area == nullptr)
|
||||
return;
|
||||
|
||||
auto it = std::lower_bound(area->SortedTiles.begin(), area->SortedTiles.end(), pos, CompareTileCoordsXY);
|
||||
auto found = it != area->SortedTiles.end() && *it == pos;
|
||||
|
||||
if (!found && value)
|
||||
{
|
||||
area->SortedTiles.insert(it, pos);
|
||||
TileCount++;
|
||||
}
|
||||
else if (found && !value)
|
||||
{
|
||||
area->SortedTiles.erase(it);
|
||||
assert(TileCount != 0);
|
||||
TileCount--;
|
||||
}
|
||||
}
|
||||
|
||||
void PatrolArea::Set(CoordsXY pos, bool value)
|
||||
{
|
||||
Set(TileCoordsXY(pos), value);
|
||||
}
|
||||
|
||||
void PatrolArea::Union(const PatrolArea& other)
|
||||
{
|
||||
for (size_t i = 0; i < Areas.size(); i++)
|
||||
{
|
||||
for (const auto& pos : other.Areas[i].SortedTiles)
|
||||
{
|
||||
Set(pos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatrolArea::Union(const std::vector<TileCoordsXY>& other)
|
||||
{
|
||||
for (const auto& pos : other)
|
||||
{
|
||||
Set(pos, true);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TileCoordsXY> PatrolArea::ToVector() const
|
||||
{
|
||||
std::vector<TileCoordsXY> result;
|
||||
for (const auto& area : Areas)
|
||||
{
|
||||
for (const auto& pos : area.SortedTiles)
|
||||
{
|
||||
result.push_back(pos);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const PatrolArea& GetMergedPatrolArea(const StaffType type)
|
||||
{
|
||||
return _mergedPatrolAreas[EnumValue(type)];
|
||||
}
|
||||
|
||||
// Maximum manhattan distance that litter can be for a handyman to seek to it
|
||||
const uint16_t MAX_LITTER_DISTANCE = 3 * COORDS_XY_STEP;
|
||||
|
||||
|
@ -191,40 +74,6 @@ template<> bool EntityBase::Is<Staff>() const
|
|||
return Type == EntityType::Staff;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006BD3A4
|
||||
*/
|
||||
void staff_reset_modes()
|
||||
{
|
||||
staff_update_greyed_patrol_areas();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0C3F
|
||||
*/
|
||||
void staff_update_greyed_patrol_areas()
|
||||
{
|
||||
for (int32_t staffType = 0; staffType < EnumValue(StaffType::Count); ++staffType)
|
||||
{
|
||||
// Reset all of the merged data for the type.
|
||||
auto& mergedArea = _mergedPatrolAreas[staffType];
|
||||
mergedArea.Clear();
|
||||
|
||||
for (auto staff : EntityList<Staff>())
|
||||
{
|
||||
if (EnumValue(staff->AssignedStaffType) != staffType)
|
||||
continue;
|
||||
|
||||
if (staff->PatrolInfo == nullptr)
|
||||
return;
|
||||
|
||||
mergedArea.Union(*staff->PatrolInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0905
|
||||
|
@ -433,11 +282,6 @@ bool Staff::IsPatrolAreaSet(const CoordsXY& coords) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool staff_is_patrol_area_set_for_type(StaffType type, const CoordsXY& coords)
|
||||
{
|
||||
return _mergedPatrolAreas[EnumValue(type)].Get(coords);
|
||||
}
|
||||
|
||||
void Staff::SetPatrolArea(const CoordsXY& coords, bool value)
|
||||
{
|
||||
if (PatrolInfo == nullptr)
|
||||
|
|
|
@ -14,45 +14,7 @@
|
|||
#include "Peep.h"
|
||||
|
||||
class DataSerialiser;
|
||||
|
||||
// The number of elements in the gStaffPatrolAreas array per staff member. Every bit in the array represents a 4x4 square.
|
||||
// Right now, it's a 32-bit array like in RCT2. 32 * 128 = 4096 bits, which is also the number of 4x4 squares on a 256x256 map.
|
||||
constexpr size_t STAFF_PATROL_AREA_BLOCKS_PER_LINE = MAXIMUM_MAP_SIZE_TECHNICAL / 4;
|
||||
constexpr size_t STAFF_PATROL_AREA_SIZE = (STAFF_PATROL_AREA_BLOCKS_PER_LINE * STAFF_PATROL_AREA_BLOCKS_PER_LINE) / 32;
|
||||
|
||||
struct PatrolArea
|
||||
{
|
||||
private:
|
||||
struct Cell
|
||||
{
|
||||
static constexpr auto Width = 64;
|
||||
static constexpr auto Height = 64;
|
||||
static constexpr auto NumTiles = Width * Height;
|
||||
|
||||
std::vector<TileCoordsXY> SortedTiles;
|
||||
};
|
||||
|
||||
static constexpr auto CellColumns = (MAXIMUM_MAP_SIZE_TECHNICAL + (Cell::Width - 1)) / Cell::Width;
|
||||
static constexpr auto CellRows = (MAXIMUM_MAP_SIZE_TECHNICAL + (Cell::Height - 1)) / Cell::Height;
|
||||
static constexpr auto NumCells = CellColumns * CellRows;
|
||||
|
||||
std::array<Cell, NumCells> Areas;
|
||||
size_t TileCount{};
|
||||
|
||||
const Cell* GetCell(TileCoordsXY pos) const;
|
||||
Cell* GetCell(TileCoordsXY pos);
|
||||
|
||||
public:
|
||||
bool IsEmpty() const;
|
||||
void Clear();
|
||||
bool Get(TileCoordsXY pos) const;
|
||||
bool Get(CoordsXY pos) const;
|
||||
void Set(TileCoordsXY pos, bool value);
|
||||
void Set(CoordsXY pos, bool value);
|
||||
void Union(const PatrolArea& other);
|
||||
void Union(const std::vector<TileCoordsXY>& other);
|
||||
std::vector<TileCoordsXY> ToVector() const;
|
||||
};
|
||||
class PatrolArea;
|
||||
|
||||
struct Staff : Peep
|
||||
{
|
||||
|
@ -181,14 +143,10 @@ enum class EntertainerCostume : uint8_t
|
|||
|
||||
extern const rct_string_id StaffCostumeNames[static_cast<uint8_t>(EntertainerCostume::Count)];
|
||||
|
||||
extern uint16_t gStaffDrawPatrolAreas;
|
||||
extern colour_t gStaffHandymanColour;
|
||||
extern colour_t gStaffMechanicColour;
|
||||
extern colour_t gStaffSecurityColour;
|
||||
|
||||
void staff_reset_modes();
|
||||
void staff_update_greyed_patrol_areas();
|
||||
bool staff_is_patrol_area_set_for_type(StaffType type, const CoordsXY& coords);
|
||||
colour_t staff_get_colour(StaffType staffType);
|
||||
bool staff_set_colour(StaffType staffType, colour_t value);
|
||||
uint32_t staff_get_available_entertainer_costumes();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "../drawing/IDrawingEngine.h"
|
||||
#include "../entity/EntityList.h"
|
||||
#include "../entity/Guest.h"
|
||||
#include "../entity/PatrolArea.h"
|
||||
#include "../entity/Staff.h"
|
||||
#include "../paint/Paint.h"
|
||||
#include "../profiling/Profiling.h"
|
||||
|
@ -90,7 +91,7 @@ void viewport_init_all()
|
|||
gPickupPeepImage = ImageId();
|
||||
reset_tooltip_not_shown();
|
||||
gMapSelectFlags = 0;
|
||||
gStaffDrawPatrolAreas = 0xFFFF;
|
||||
ClearPatrolAreaToRender();
|
||||
textinput_cancel();
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,7 @@
|
|||
<ClInclude Include="entity\Litter.h" />
|
||||
<ClInclude Include="entity\MoneyEffect.h" />
|
||||
<ClInclude Include="entity\Particle.h" />
|
||||
<ClInclude Include="entity\PatrolArea.h" />
|
||||
<ClInclude Include="entity\Peep.h" />
|
||||
<ClInclude Include="entity\Staff.h" />
|
||||
<ClInclude Include="FileClassifier.h" />
|
||||
|
@ -687,6 +688,7 @@
|
|||
<ClCompile Include="entity\Litter.cpp" />
|
||||
<ClCompile Include="entity\MoneyEffect.cpp" />
|
||||
<ClCompile Include="entity\Particle.cpp" />
|
||||
<ClCompile Include="entity\PatrolArea.cpp" />
|
||||
<ClCompile Include="entity\Peep.cpp" />
|
||||
<ClCompile Include="entity\Staff.cpp" />
|
||||
<ClCompile Include="FileClassifier.cpp" />
|
||||
|
@ -952,4 +954,4 @@
|
|||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -15,6 +15,7 @@
|
|||
#include "../../core/Numerics.hpp"
|
||||
#include "../../drawing/LightFX.h"
|
||||
#include "../../entity/EntityRegistry.h"
|
||||
#include "../../entity/PatrolArea.h"
|
||||
#include "../../entity/Peep.h"
|
||||
#include "../../entity/Staff.h"
|
||||
#include "../../interface/Viewport.h"
|
||||
|
@ -898,45 +899,19 @@ static bool ShouldDrawSupports(paint_session& session, const PathElement& pathEl
|
|||
|
||||
static void PaintPatrolAreas(paint_session& session, const PathElement& pathEl)
|
||||
{
|
||||
if (gStaffDrawPatrolAreas != 0xFFFF)
|
||||
auto colour = GetPatrolAreaTileColour(session.MapPosition);
|
||||
if (colour)
|
||||
{
|
||||
// TODO: Split this into two.
|
||||
auto staffIndex = gStaffDrawPatrolAreas;
|
||||
auto staffType = static_cast<StaffType>(staffIndex & 0x7FFF);
|
||||
auto is_staff_list = staffIndex & 0x8000;
|
||||
|
||||
auto patrolColour = COLOUR_LIGHT_BLUE;
|
||||
|
||||
if (!is_staff_list)
|
||||
uint32_t baseImageIndex = SPR_TERRAIN_STAFF;
|
||||
auto patrolAreaBaseZ = pathEl.GetBaseZ();
|
||||
if (pathEl.IsSloped())
|
||||
{
|
||||
Staff* staff = GetEntity<Staff>(EntityId::FromUnderlying(staffIndex));
|
||||
if (staff == nullptr)
|
||||
{
|
||||
log_error("Invalid staff index for draw patrol areas!");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!staff->IsPatrolAreaSet(session.MapPosition))
|
||||
{
|
||||
patrolColour = COLOUR_GREY;
|
||||
}
|
||||
staffType = staff->AssignedStaffType;
|
||||
}
|
||||
baseImageIndex = SPR_TERRAIN_STAFF_SLOPED + ((pathEl.GetSlopeDirection() + session.CurrentRotation) & 3);
|
||||
patrolAreaBaseZ += 16;
|
||||
}
|
||||
|
||||
if (staff_is_patrol_area_set_for_type(staffType, session.MapPosition))
|
||||
{
|
||||
uint32_t baseImageIndex = SPR_TERRAIN_STAFF;
|
||||
auto patrolAreaBaseZ = pathEl.GetBaseZ();
|
||||
if (pathEl.IsSloped())
|
||||
{
|
||||
baseImageIndex = SPR_TERRAIN_STAFF_SLOPED + ((pathEl.GetSlopeDirection() + session.CurrentRotation) & 3);
|
||||
patrolAreaBaseZ += 16;
|
||||
}
|
||||
|
||||
auto imageId = ImageId(baseImageIndex, patrolColour);
|
||||
PaintAddImageAsParent(session, imageId, { 16, 16, patrolAreaBaseZ + 2 }, { 1, 1, 0 });
|
||||
}
|
||||
auto imageId = ImageId(baseImageIndex, *colour);
|
||||
PaintAddImageAsParent(session, imageId, { 16, 16, patrolAreaBaseZ + 2 }, { 1, 1, 0 });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "../../core/Numerics.hpp"
|
||||
#include "../../drawing/Drawing.h"
|
||||
#include "../../entity/EntityRegistry.h"
|
||||
#include "../../entity/PatrolArea.h"
|
||||
#include "../../entity/Peep.h"
|
||||
#include "../../entity/Staff.h"
|
||||
#include "../../interface/Colour.h"
|
||||
|
@ -969,6 +970,51 @@ static std::pair<int32_t, int32_t> surface_get_height_above_water(
|
|||
return { localHeight, localSurfaceShape };
|
||||
}
|
||||
|
||||
std::optional<colour_t> GetPatrolAreaTileColour(const CoordsXY& pos)
|
||||
{
|
||||
auto patrolAreaToRender = GetPatrolAreaToRender();
|
||||
if (const auto* staffType = std::get_if<StaffType>(&patrolAreaToRender))
|
||||
{
|
||||
if (IsPatrolAreaSetForStaffType(*staffType, pos))
|
||||
{
|
||||
return COLOUR_GREY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& staffId = std::get<EntityId>(patrolAreaToRender);
|
||||
auto* staff = GetEntity<Staff>(staffId);
|
||||
if (staff != nullptr)
|
||||
{
|
||||
if (staff->IsPatrolAreaSet(pos))
|
||||
{
|
||||
return COLOUR_LIGHT_BLUE;
|
||||
}
|
||||
else if (IsPatrolAreaSetForStaffType(staff->AssignedStaffType, pos))
|
||||
{
|
||||
return COLOUR_GREY;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static void PaintPatrolArea(paint_session& session, const SurfaceElement& element, int32_t height, uint8_t surfaceShape)
|
||||
{
|
||||
auto colour = GetPatrolAreaTileColour(session.MapPosition);
|
||||
if (colour)
|
||||
{
|
||||
assert(surfaceShape < std::size(byte_97B444));
|
||||
|
||||
auto [localZ, localSurfaceShape] = surface_get_height_above_water(element, height, surfaceShape);
|
||||
auto imageId = ImageId(SPR_TERRAIN_SELECTION_PATROL_AREA + byte_97B444[localSurfaceShape], *colour);
|
||||
|
||||
auto* backup = session.LastPS;
|
||||
PaintAddImageAsParent(session, imageId, { 0, 0, localZ }, { 32, 32, 1 });
|
||||
session.LastPS = backup;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x0066062C
|
||||
*/
|
||||
|
@ -1101,49 +1147,7 @@ void PaintSurface(paint_session& session, uint8_t direction, uint16_t height, co
|
|||
has_surface = true;
|
||||
}
|
||||
|
||||
// Draw Staff Patrol Areas
|
||||
// loc_660D02
|
||||
if (gStaffDrawPatrolAreas != EntityId::GetNull().ToUnderlying())
|
||||
{
|
||||
// TODO: Split is_staff_list into a new variable.
|
||||
const int32_t staffIndex = gStaffDrawPatrolAreas;
|
||||
const bool is_staff_list = staffIndex & 0x8000;
|
||||
const int16_t x = session.MapPosition.x, y = session.MapPosition.y;
|
||||
|
||||
uint8_t staffType = staffIndex & 0x7FFF;
|
||||
uint32_t image_id = IMAGE_TYPE_REMAP;
|
||||
uint8_t patrolColour = COLOUR_LIGHT_BLUE;
|
||||
|
||||
if (!is_staff_list)
|
||||
{
|
||||
Staff* staff = GetEntity<Staff>(EntityId::FromUnderlying(staffIndex));
|
||||
if (staff == nullptr)
|
||||
{
|
||||
log_error("Invalid staff index for draw patrol areas!");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!staff->IsPatrolAreaSet({ x, y }))
|
||||
{
|
||||
patrolColour = COLOUR_GREY;
|
||||
}
|
||||
staffType = static_cast<uint8_t>(staff->AssignedStaffType);
|
||||
}
|
||||
}
|
||||
|
||||
if (staff_is_patrol_area_set_for_type(static_cast<StaffType>(staffType), session.MapPosition))
|
||||
{
|
||||
assert(surfaceShape < std::size(byte_97B444));
|
||||
|
||||
auto [local_height, local_surfaceShape] = surface_get_height_above_water(tileElement, height, surfaceShape);
|
||||
image_id |= SPR_TERRAIN_SELECTION_PATROL_AREA + byte_97B444[local_surfaceShape];
|
||||
image_id |= patrolColour << 19;
|
||||
|
||||
paint_struct* backup = session.LastPS;
|
||||
PaintAddImageAsParent(session, image_id, { 0, 0, local_height }, { 32, 32, 1 });
|
||||
session.LastPS = backup;
|
||||
}
|
||||
}
|
||||
PaintPatrolArea(session, tileElement, height, surfaceShape);
|
||||
|
||||
// Draw Peep Spawns
|
||||
if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode)
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
#include "../../common.h"
|
||||
#include "../../sprites.h"
|
||||
#include "../../world/Location.hpp"
|
||||
|
||||
#include <optional>
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -102,3 +105,5 @@ enum
|
|||
SPR_RCT1_WATER_MASK = SPR_CSG_BEGIN + 46787,
|
||||
SPR_RCT1_WATER_OVERLAY = SPR_CSG_BEGIN + 46792,
|
||||
};
|
||||
|
||||
std::optional<colour_t> GetPatrolAreaTileColour(const CoordsXY& pos);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "../entity/Litter.h"
|
||||
#include "../entity/MoneyEffect.h"
|
||||
#include "../entity/Particle.h"
|
||||
#include "../entity/PatrolArea.h"
|
||||
#include "../entity/Staff.h"
|
||||
#include "../interface/Viewport.h"
|
||||
#include "../interface/Window.h"
|
||||
|
@ -2027,11 +2028,18 @@ namespace OpenRCT2
|
|||
cs.ReadWriteVector(patrolArea, [&cs](TileCoordsXY& value) { cs.ReadWrite(value); });
|
||||
if (cs.GetMode() == OrcaStream::Mode::READING)
|
||||
{
|
||||
if (entity.PatrolInfo == nullptr)
|
||||
entity.PatrolInfo = new PatrolArea();
|
||||
if (patrolArea.empty())
|
||||
{
|
||||
entity.ClearPatrolArea();
|
||||
}
|
||||
else
|
||||
entity.PatrolInfo->Clear();
|
||||
entity.PatrolInfo->Union(patrolArea);
|
||||
{
|
||||
if (entity.PatrolInfo == nullptr)
|
||||
entity.PatrolInfo = new PatrolArea();
|
||||
else
|
||||
entity.PatrolInfo->Clear();
|
||||
entity.PatrolInfo->Union(patrolArea);
|
||||
}
|
||||
}
|
||||
|
||||
if (os.GetHeader().TargetVersion <= 1)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "../entity/Litter.h"
|
||||
#include "../entity/MoneyEffect.h"
|
||||
#include "../entity/Particle.h"
|
||||
#include "../entity/PatrolArea.h"
|
||||
#include "../entity/Peep.h"
|
||||
#include "../entity/Staff.h"
|
||||
#include "../interface/Window.h"
|
||||
|
@ -1260,7 +1261,7 @@ namespace RCT1
|
|||
void FixImportStaff()
|
||||
{
|
||||
// Only the individual patrol areas have been converted, so generate the combined patrol areas of each staff type
|
||||
staff_update_greyed_patrol_areas();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
}
|
||||
|
||||
void ImportPeep(::Peep* dst, const RCT1::Peep* src)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "../entity/Litter.h"
|
||||
#include "../entity/MoneyEffect.h"
|
||||
#include "../entity/Particle.h"
|
||||
#include "../entity/PatrolArea.h"
|
||||
#include "../entity/Staff.h"
|
||||
#include "../interface/Viewport.h"
|
||||
#include "../localisation/Date.h"
|
||||
|
@ -490,7 +491,7 @@ namespace RCT2
|
|||
FixLandOwnership();
|
||||
|
||||
research_determine_first_of_type();
|
||||
staff_update_greyed_patrol_areas();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
|
||||
CheatsReset();
|
||||
ClearRestrictedScenery();
|
||||
|
|
Loading…
Reference in New Issue