diff --git a/CMakeLists.txt b/CMakeLists.txt
index e07d4510cd..90b62508cc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,9 +50,9 @@ set(OBJECTS_VERSION "1.0.21")
set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip")
set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5")
-set(REPLAYS_VERSION "0.0.54")
+set(REPLAYS_VERSION "0.0.55")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip")
-set(REPLAYS_SHA1 "FF54C3699C3A0DF02269C5EB4C4A9C8E6D5C4EB4")
+set(REPLAYS_SHA1 "70B4B7CB26A428801676BCC615F3881E72A45406")
option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.")
option(WITH_TESTS "Build tests")
diff --git a/openrct2.proj b/openrct2.proj
index f46863f90e..d8fcfb7bc1 100644
--- a/openrct2.proj
+++ b/openrct2.proj
@@ -48,8 +48,8 @@
304d13a126c15bf2c86ff13b81a2f2cc1856ac8d
https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip
c38af45d51a6e440386180feacf76c64720b6ac5
- https://github.com/OpenRCT2/replays/releases/download/v0.0.54/replays.zip
- FF54C3699C3A0DF02269C5EB4C4A9C8E6D5C4EB4
+ https://github.com/OpenRCT2/replays/releases/download/v0.0.55/replays.zip
+ 70B4B7CB26A428801676BCC615F3881E72A45406
diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp
index 422dd64116..9e208678c5 100644
--- a/src/openrct2-ui/windows/Staff.cpp
+++ b/src/openrct2-ui/windows/Staff.cpp
@@ -567,11 +567,10 @@ void window_staff_overview_dropdown(rct_window* w, rct_widgetindex widgetIndex,
{
return;
}
- // TODO: THIS SHOULD BE NETWORKED
- peep->ClearPatrolArea();
- gfx_invalidate_screen();
- staff_update_greyed_patrol_areas();
+ auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(
+ peep->sprite_index, {}, StaffSetPatrolAreaMode::ClearAll);
+ GameActions::Execute(&staffSetPatrolAreaAction);
}
else
{
@@ -1241,7 +1240,9 @@ void window_staff_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex,
{
_staffPatrolAreaPaintValue = PatrolAreaValue::SET;
}
- auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(w->number, destCoords);
+ auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(
+ w->number, destCoords,
+ _staffPatrolAreaPaintValue == PatrolAreaValue::SET ? StaffSetPatrolAreaMode::Set : StaffSetPatrolAreaMode::Unset);
GameActions::Execute(&staffSetPatrolAreaAction);
}
}
@@ -1275,7 +1276,9 @@ void window_staff_overview_tool_drag(rct_window* w, rct_widgetindex widgetIndex,
if (_staffPatrolAreaPaintValue == PatrolAreaValue::UNSET && !patrolAreaValue)
return; // Since area is already the value we want, skip...
- auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(w->number, destCoords);
+ auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(
+ w->number, destCoords,
+ _staffPatrolAreaPaintValue == PatrolAreaValue::SET ? StaffSetPatrolAreaMode::Set : StaffSetPatrolAreaMode::Unset);
GameActions::Execute(&staffSetPatrolAreaAction);
}
diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.cpp b/src/openrct2/actions/StaffSetPatrolAreaAction.cpp
index fce035a3b2..bee0769e31 100644
--- a/src/openrct2/actions/StaffSetPatrolAreaAction.cpp
+++ b/src/openrct2/actions/StaffSetPatrolAreaAction.cpp
@@ -14,9 +14,10 @@
#include "../peep/Staff.h"
#include "../world/Entity.h"
-StaffSetPatrolAreaAction::StaffSetPatrolAreaAction(uint16_t spriteId, const CoordsXY& loc)
+StaffSetPatrolAreaAction::StaffSetPatrolAreaAction(uint16_t spriteId, const CoordsXY& loc, const StaffSetPatrolAreaMode mode)
: _spriteId(spriteId)
, _loc(loc)
+ , _mode(mode)
{
}
@@ -28,7 +29,7 @@ uint16_t StaffSetPatrolAreaAction::GetActionFlags() const
void StaffSetPatrolAreaAction::Serialise(DataSerialiser& stream)
{
GameAction::Serialise(stream);
- stream << DS_TAG(_spriteId) << DS_TAG(_loc);
+ stream << DS_TAG(_spriteId) << DS_TAG(_loc) << DS_TAG(_mode);
}
GameActions::Result::Ptr StaffSetPatrolAreaAction::Query() const
@@ -54,19 +55,10 @@ GameActions::Result::Ptr StaffSetPatrolAreaAction::Query() const
return MakeResult();
}
-GameActions::Result::Ptr StaffSetPatrolAreaAction::Execute() const
+static void UpdateStaffMode(const Staff& staff)
{
- auto staff = TryGetEntity(_spriteId);
- if (staff == nullptr)
- {
- log_error("Invalid spriteId. spriteId = %u", _spriteId);
- return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
- }
-
- staff->TogglePatrolArea(_loc);
-
bool isPatrolling = false;
- const auto peepOffset = staff->StaffId * STAFF_PATROL_AREA_SIZE;
+ const auto peepOffset = staff.StaffId * STAFF_PATROL_AREA_SIZE;
for (size_t i = peepOffset; i < peepOffset + STAFF_PATROL_AREA_SIZE; i++)
{
if (gStaffPatrolAreas[i] != 0)
@@ -78,20 +70,54 @@ GameActions::Result::Ptr StaffSetPatrolAreaAction::Execute() const
if (isPatrolling)
{
- gStaffModes[staff->StaffId] = StaffMode::Patrol;
+ gStaffModes[staff.StaffId] = StaffMode::Patrol;
}
- else if (gStaffModes[staff->StaffId] == StaffMode::Patrol)
+ else if (gStaffModes[staff.StaffId] == StaffMode::Patrol)
{
- gStaffModes[staff->StaffId] = StaffMode::Walk;
+ gStaffModes[staff.StaffId] = StaffMode::Walk;
}
+}
+static void InvalidatePatrolTile(const CoordsXY& loc)
+{
+ // Align the location to the top left of the patrol square
+ const auto alignedLoc = CoordsXY{ loc.x & 0x1F80, loc.y & 0x1F80 };
for (int32_t y = 0; y < 4 * COORDS_XY_STEP; y += COORDS_XY_STEP)
{
for (int32_t x = 0; x < 4 * COORDS_XY_STEP; x += COORDS_XY_STEP)
{
- map_invalidate_tile_full({ (_loc.x & 0x1F80) + x, (_loc.y & 0x1F80) + y });
+ map_invalidate_tile_full(alignedLoc + CoordsXY{ x, y });
}
}
+}
+
+GameActions::Result::Ptr StaffSetPatrolAreaAction::Execute() const
+{
+ auto staff = TryGetEntity(_spriteId);
+ if (staff == nullptr)
+ {
+ log_error("Invalid spriteId. spriteId = %u", _spriteId);
+ return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
+ }
+
+ switch (_mode)
+ {
+ case StaffSetPatrolAreaMode::Set:
+ staff->SetPatrolArea(_loc, true);
+ UpdateStaffMode(*staff);
+ InvalidatePatrolTile(_loc);
+ break;
+ case StaffSetPatrolAreaMode::Unset:
+ staff->SetPatrolArea(_loc, false);
+ UpdateStaffMode(*staff);
+ InvalidatePatrolTile(_loc);
+ break;
+ case StaffSetPatrolAreaMode::ClearAll:
+ staff->ClearPatrolArea();
+ gfx_invalidate_screen();
+ break;
+ }
+
staff_update_greyed_patrol_areas();
return MakeResult();
diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.h b/src/openrct2/actions/StaffSetPatrolAreaAction.h
index 7d43239aa7..d6b31ce52a 100644
--- a/src/openrct2/actions/StaffSetPatrolAreaAction.h
+++ b/src/openrct2/actions/StaffSetPatrolAreaAction.h
@@ -11,15 +11,23 @@
#include "GameAction.h"
+enum class StaffSetPatrolAreaMode : uint8_t
+{
+ Set,
+ Unset,
+ ClearAll
+};
+
DEFINE_GAME_ACTION(StaffSetPatrolAreaAction, GameCommand::SetStaffPatrol, GameActions::Result)
{
private:
uint16_t _spriteId{ SPRITE_INDEX_NULL };
CoordsXY _loc;
+ StaffSetPatrolAreaMode _mode;
public:
StaffSetPatrolAreaAction() = default;
- StaffSetPatrolAreaAction(uint16_t spriteId, const CoordsXY& loc);
+ StaffSetPatrolAreaAction(uint16_t spriteId, const CoordsXY& loc, const StaffSetPatrolAreaMode mode);
uint16_t GetActionFlags() const override;
diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp
index f045992fc0..6e7564d2a1 100644
--- a/src/openrct2/network/NetworkBase.cpp
+++ b/src/openrct2/network/NetworkBase.cpp
@@ -38,7 +38,7 @@
// This string specifies which version of network stream current build uses.
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
-#define NETWORK_STREAM_VERSION "12"
+#define NETWORK_STREAM_VERSION "13"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
static Peep* _pickup_peep = nullptr;