1 /*****************************************************************************
2  * Copyright (c) 2014-2020 OpenRCT2 developers
3  *
4  * For a complete list of all authors, please refer to contributors.md
5  * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6  *
7  * OpenRCT2 is licensed under the GNU General Public License version 3.
8  *****************************************************************************/
9 
10 #pragma once
11 
12 #include "../common.h"
13 #include "../world/Map.h"
14 #include "Peep.h"
15 
16 class DataSerialiser;
17 
18 #define STAFF_MAX_COUNT 200
19 // The number of elements in the gStaffPatrolAreas array per staff member. Every bit in the array represents a 4x4 square.
20 // 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.
21 constexpr size_t STAFF_PATROL_AREA_BLOCKS_PER_LINE = MAXIMUM_MAP_SIZE_TECHNICAL / 4;
22 constexpr size_t STAFF_PATROL_AREA_SIZE = (STAFF_PATROL_AREA_BLOCKS_PER_LINE * STAFF_PATROL_AREA_BLOCKS_PER_LINE) / 32;
23 
24 struct PatrolArea
25 {
26     uint32_t Data[STAFF_PATROL_AREA_SIZE];
27 };
28 
29 struct Staff : Peep
30 {
31     static constexpr auto cEntityType = EntityType::Staff;
32 
33 public:
34     PatrolArea* PatrolInfo;
35     StaffType AssignedStaffType;
36     uint16_t MechanicTimeSinceCall; // time getting to ride to fix
37     int32_t HireDate;
38     uint8_t StaffOrders;
39     uint8_t StaffMowingTimeout;
40     union
41     {
42         uint16_t StaffLawnsMown;
43         uint16_t StaffRidesFixed;
44     };
45     union
46     {
47         uint16_t StaffGardensWatered;
48         uint16_t StaffRidesInspected;
49     };
50     union
51     {
52         uint16_t StaffLitterSwept;
53         uint16_t StaffVandalsStopped;
54     };
55     uint16_t StaffBinsEmptied;
56 
57     void UpdateStaff(uint32_t stepsToTake);
58     void Tick128UpdateStaff();
59     bool IsMechanic() const;
60     bool IsPatrolAreaSet(const CoordsXY& coords) const;
61     bool IsLocationInPatrol(const CoordsXY& loc) const;
62     bool IsLocationOnPatrolEdge(const CoordsXY& loc) const;
63     bool DoPathFinding();
64     uint8_t GetCostume() const;
65     void SetCostume(uint8_t value);
66     void SetHireDate(int32_t hireDate);
67     int32_t GetHireDate() const;
68 
69     bool CanIgnoreWideFlag(const CoordsXYZ& staffPos, TileElement* path) const;
70 
71     static void ResetStats();
72     void Serialise(DataSerialiser& stream);
73 
74     void ClearPatrolArea();
75     void SetPatrolArea(const CoordsXY& coords, bool value);
76     bool HasPatrolArea() const;
77 
78 private:
79     void UpdatePatrolling();
80     void UpdateMowing();
81     void UpdateSweeping();
82     void UpdateEmptyingBin();
83     void UpdateWatering();
84     void UpdateAnswering();
85     void UpdateFixing(int32_t steps);
86     bool UpdateFixingEnterStation(Ride* ride) const;
87     bool UpdateFixingMoveToBrokenDownVehicle(bool firstRun, const Ride* ride);
88     bool UpdateFixingFixVehicle(bool firstRun, const Ride* ride);
89     bool UpdateFixingFixVehicleMalfunction(bool firstRun, const Ride* ride);
90     bool UpdateFixingMoveToStationEnd(bool firstRun, const Ride* ride);
91     bool UpdateFixingFixStationEnd(bool firstRun);
92     bool UpdateFixingMoveToStationStart(bool firstRun, const Ride* ride);
93     bool UpdateFixingFixStationStart(bool firstRun, const Ride* ride);
94     bool UpdateFixingFixStationBrakes(bool firstRun, Ride* ride);
95     bool UpdateFixingMoveToStationExit(bool firstRun, const Ride* ride);
96     bool UpdateFixingFinishFixOrInspect(bool firstRun, int32_t steps, Ride* ride);
97     bool UpdateFixingLeaveByEntranceExit(bool firstRun, const Ride* ride);
98     void UpdateRideInspected(ride_id_t rideIndex);
99     void UpdateHeadingToInspect();
100 
101     bool DoHandymanPathFinding();
102     bool DoMechanicPathFinding();
103     bool DoEntertainerPathFinding();
104     bool DoMiscPathFinding();
105 
106     Direction HandymanDirectionRandSurface(uint8_t validDirections) const;
107 
108     void EntertainerUpdateNearbyPeeps() const;
109 
110     uint8_t GetValidPatrolDirections(const CoordsXY& loc) const;
111     Direction HandymanDirectionToNearestLitter() const;
112     uint8_t HandymanDirectionToUncutGrass(uint8_t valid_directions) const;
113     Direction DirectionSurface(Direction initialDirection) const;
114     Direction DirectionPath(uint8_t validDirections, PathElement* pathElement) const;
115     Direction MechanicDirectionSurface() const;
116     Direction MechanicDirectionPathRand(uint8_t pathDirections) const;
117     Direction MechanicDirectionPath(uint8_t validDirections, PathElement* pathElement);
118     bool UpdatePatrollingFindWatering();
119     bool UpdatePatrollingFindBin();
120     bool UpdatePatrollingFindSweeping();
121     bool UpdatePatrollingFindGrass();
122 };
123 static_assert(sizeof(Staff) <= 512);
124 
125 enum STAFF_ORDERS
126 {
127     STAFF_ORDERS_SWEEPING = (1 << 0),
128     STAFF_ORDERS_WATER_FLOWERS = (1 << 1),
129     STAFF_ORDERS_EMPTY_BINS = (1 << 2),
130     STAFF_ORDERS_MOWING = (1 << 3),
131     STAFF_ORDERS_INSPECT_RIDES = (1 << 0),
132     STAFF_ORDERS_FIX_RIDES = (1 << 1)
133 };
134 
135 enum class EntertainerCostume : uint8_t
136 {
137     Panda,
138     Tiger,
139     Elephant,
140     Roman,
141     Gorilla,
142     Snowman,
143     Knight,
144     Astronaut,
145     Bandit,
146     Sheriff,
147     Pirate,
148 
149     Count
150 };
151 
152 extern const rct_string_id StaffCostumeNames[static_cast<uint8_t>(EntertainerCostume::Count)];
153 
154 extern uint16_t gStaffDrawPatrolAreas;
155 extern colour_t gStaffHandymanColour;
156 extern colour_t gStaffMechanicColour;
157 extern colour_t gStaffSecurityColour;
158 
159 void staff_reset_modes();
160 void staff_set_name(uint16_t spriteIndex, const char* name);
161 bool staff_hire_new_member(StaffType staffType, EntertainerCostume entertainerType);
162 void staff_update_greyed_patrol_areas();
163 bool staff_is_patrol_area_set_for_type(StaffType type, const CoordsXY& coords);
164 colour_t staff_get_colour(StaffType staffType);
165 bool staff_set_colour(StaffType staffType, colour_t value);
166 uint32_t staff_get_available_entertainer_costumes();
167 int32_t staff_get_available_entertainer_costume_list(EntertainerCostume* costumeList);
168 
169 money32 GetStaffWage(StaffType type);
170 PeepSpriteType EntertainerCostumeToSprite(EntertainerCostume entertainerType);
171 
172 const PatrolArea& GetMergedPatrolArea(const StaffType type);
173