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 "../management/Finance.h"
13 #include "../ride/ShopItem.h"
14 #include "Peep.h"
15 
16 #include <bitset>
17 
18 #define PEEP_MAX_THOUGHTS 5
19 
20 #define PEEP_HUNGER_WARNING_THRESHOLD 25
21 #define PEEP_THIRST_WARNING_THRESHOLD 25
22 #define PEEP_TOILET_WARNING_THRESHOLD 28
23 #define PEEP_LITTER_WARNING_THRESHOLD 23
24 #define PEEP_DISGUST_WARNING_THRESHOLD 22
25 #define PEEP_VANDALISM_WARNING_THRESHOLD 15
26 #define PEEP_NOEXIT_WARNING_THRESHOLD 8
27 #define PEEP_LOST_WARNING_THRESHOLD 8
28 
29 #define PEEP_MAX_HAPPINESS 255
30 #define PEEP_MAX_HUNGER 255
31 #define PEEP_MAX_TOILET 255
32 #define PEEP_MAX_NAUSEA 255
33 #define PEEP_MAX_THIRST 255
34 
35 enum class PeepThoughtType : uint8_t
36 {
37     CantAffordRide = 0,   // "I can't afford"
38     SpentMoney = 1,       // "I've spent all my money"
39     Sick = 2,             // "I feel sick"
40     VerySick = 3,         // "I feel very sick"
41     MoreThrilling = 4,    // "I want to go on something more thrilling than X"
42     Intense = 5,          // "X looks too intense for me"
43     HaventFinished = 6,   // "I haven't finished my X yet"
44     Sickening = 7,        // "Just looking at X makes me feel sick"
45     BadValue = 8,         // "I'm not paying that much to go on X"
46     GoHome = 9,           // "I want to go home"
47     GoodValue = 10,       // "X is really good value"
48     AlreadyGot = 11,      // "I've already got"
49     CantAffordItem = 12,  // "I can't afford"
50     NotHungry = 13,       // "I'm not hungry"
51     NotThirsty = 14,      // "I'm not thirsty"
52     Drowning = 15,        // "Help! I'm drowning!"
53     Lost = 16,            // "I'm lost!"
54     WasGreat = 17,        // "X was great"
55     QueuingAges = 18,     // "I've been queuing for X for ages"
56     Tired = 19,           // "I'm tired"
57     Hungry = 20,          // "I'm hungry"
58     Thirsty = 21,         // "I'm thirsty"
59     Toilet = 22,          // "I need to go to the toilet"
60     CantFind = 23,        // "I can't find X"
61     NotPaying = 24,       // "I'm not paying that much to use X"
62     NotWhileRaining = 25, // "I'm not going on X while it's raining"
63     BadLitter = 26,       // "The litter here is really bad"
64     CantFindExit = 27,    // "I can't find the exit"
65     GetOff = 28,          // "I want to get off X"
66     GetOut = 29,          // "I want to get out of X"
67     NotSafe = 30,         // "I'm not going on X - it isn't safe"
68     PathDisgusting = 31,  // "This path is disgusting"
69     Crowded = 32,         // "It's too crowded here"
70     Vandalism = 33,       // "The vandalism here is really bad"
71     Scenery = 34,         // "Great scenery!"
72     VeryClean = 35,       // "This park is very clean and tidy"
73     Fountains = 36,       // "The jumping fountains are great"
74     Music = 37,           // "The music is nice here"
75     Balloon = 38,         // "This balloon from X is really good value"
76     Toy = 39,             // "This cuddly toy from X is really good value"
77     Map = 40,
78     Photo = 41, // "This on ride photo from X is really good value"
79     Umbrella = 42,
80     Drink = 43,
81     Burger = 44,
82     Chips = 45,
83     IceCream = 46,
84     Candyfloss = 47,
85 
86     Pizza = 51,
87 
88     Popcorn = 53,
89     HotDog = 54,
90     Tentacle = 55,
91     Hat = 56,
92     ToffeeApple = 57,
93     Tshirt = 58,
94     Doughnut = 59,
95     Coffee = 60,
96 
97     Chicken = 62,
98     Lemonade = 63,
99 
100     Wow = 67, // "Wow!"
101 
102     Wow2 = 70,        // "Wow!"
103     Watched = 71,     // "I have the strangest feeling someone is watching me"
104     BalloonMuch = 72, // "I'm not paying that much to get a balloon from X"
105     ToyMuch = 73,
106     MapMuch = 74,
107     PhotoMuch = 75,
108     UmbrellaMuch = 76,
109     DrinkMuch = 77,
110     BurgerMuch = 78,
111     ChipsMuch = 79,
112     IceCreamMuch = 80,
113     CandyflossMuch = 81,
114 
115     PizzaMuch = 85,
116 
117     PopcornMuch = 87,
118     HotDogMuch = 88,
119     TentacleMuch = 89,
120     HatMuch = 90,
121     ToffeeAppleMuch = 91,
122     TshirtMuch = 92,
123     DoughnutMuch = 93,
124     CoffeeMuch = 94,
125 
126     ChickenMuch = 96,
127     LemonadeMuch = 97,
128 
129     Photo2 = 104, // "This on-ride photo from X is really good value"
130     Photo3 = 105,
131     Photo4 = 106,
132     Pretzel = 107,
133     HotChocolate = 108,
134     IcedTea = 109,
135     FunnelCake = 110,
136     Sunglasses = 111,
137     BeefNoodles = 112,
138     FriedRiceNoodles = 113,
139     WontonSoup = 114,
140     MeatballSoup = 115,
141     FruitJuice = 116,
142     SoybeanMilk = 117,
143     Sujongkwa = 118,
144     SubSandwich = 119,
145     Cookie = 120,
146 
147     RoastSausage = 124,
148 
149     Photo2Much = 136,
150     Photo3Much = 137,
151     Photo4Much = 138,
152     PretzelMuch = 139,
153     HotChocolateMuch = 140,
154     IcedTeaMuch = 141,
155     FunnelCakeMuch = 142,
156     SunglassesMuch = 143,
157     BeefNoodlesMuch = 144,
158     FriedRiceNoodlesMuch = 145,
159     WontonSoupMuch = 146,
160     MeatballSoupMuch = 147,
161     FruitJuiceMuch = 148,
162     SoybeanMilkMuch = 149,
163     SujongkwaMuch = 150,
164     SubSandwichMuch = 151,
165     CookieMuch = 152,
166 
167     RoastSausageMuch = 156,
168 
169     Help = 168,               // "Help! Put me down!"
170     RunningOut = 169,         // "I'm running out of cash!"
171     NewRide = 170,            // "Wow! A new ride being built!"
172     NiceRideDeprecated = 171, // "Nice ride! But not as good as the Phoenix..."
173     ExcitedDeprecated = 172,  // "I'm so excited - It's an Intamin ride!"
174     HereWeAre = 173,          // "...and here we are on X!"
175 
176     None = 255
177 };
178 
179 enum class PeepNauseaTolerance : uint8_t
180 {
181     None,
182     Low,
183     Average,
184     High
185 };
186 
187 static constexpr uint16_t PeepThoughtItemNone = std::numeric_limits<uint16_t>::max();
188 
189 struct PeepThought
190 {
191     PeepThoughtType type;
192     union
193     {
194         ride_id_t rideId;
195         ShopItem shopItem;
196         uint16_t item;
197     };
198     uint8_t freshness;     // larger is less fresh
199     uint8_t fresh_timeout; // updates every tick
200 };
201 
202 struct Guest;
203 struct Staff;
204 
205 struct IntensityRange
206 {
207 private:
208     uint8_t _value{};
209 
210 public:
IntensityRangeIntensityRange211     explicit IntensityRange(uint8_t value)
212         : _value(value)
213     {
214     }
215 
IntensityRangeIntensityRange216     IntensityRange(uint8_t min, uint8_t max)
217         : _value(std::min<uint8_t>(min, 15) | (std::min<uint8_t>(max, 15) << 4))
218     {
219     }
220 
GetMinimumIntensityRange221     uint8_t GetMinimum() const
222     {
223         return _value & 0x0F;
224     }
225 
GetMaximumIntensityRange226     uint8_t GetMaximum() const
227     {
228         return _value >> 4;
229     }
230 
WithMinimumIntensityRange231     IntensityRange WithMinimum(uint8_t value) const
232     {
233         return IntensityRange(value, GetMaximum());
234     }
235 
WithMaximumIntensityRange236     IntensityRange WithMaximum(uint8_t value) const
237     {
238         return IntensityRange(GetMinimum(), value);
239     }
240 
uint8_tIntensityRange241     explicit operator uint8_t() const
242     {
243         return _value;
244     }
245 
246     friend bool operator==(const IntensityRange& lhs, const IntensityRange& rhs)
247     {
248         return lhs._value == rhs._value;
249     }
250 
251     friend bool operator!=(const IntensityRange& lhs, const IntensityRange& rhs)
252     {
253         return lhs._value != rhs._value;
254     }
255 };
256 
257 struct Guest : Peep
258 {
259     static constexpr auto cEntityType = EntityType::Guest;
260 
261 public:
262     uint8_t GuestNumRides;
263     uint16_t GuestNextInQueue;
264     int32_t ParkEntryTime;
265     ride_id_t GuestHeadingToRideId;
266     uint8_t GuestIsLostCountdown;
267     uint8_t GuestTimeOnRide;
268     money16 PaidToEnter;
269     money16 PaidOnRides;
270     money16 PaidOnFood;
271     money16 PaidOnDrink;
272     money16 PaidOnSouvenirs;
273     bool OutsideOfPark;
274     uint8_t Happiness;
275     uint8_t HappinessTarget;
276     uint8_t Nausea;
277     uint8_t NauseaTarget;
278     uint8_t Hunger;
279     uint8_t Thirst;
280     uint8_t Toilet;
281     uint8_t TimeToConsume;
282     IntensityRange Intensity{ 0 };
283     PeepNauseaTolerance NauseaTolerance;
284     uint16_t TimeInQueue;
285     money32 CashInPocket;
286     money32 CashSpent;
287     ride_id_t Photo1RideRef;
288     ride_id_t Photo2RideRef;
289     ride_id_t Photo3RideRef;
290     ride_id_t Photo4RideRef;
291 
292     int8_t RejoinQueueTimeout; // whilst waiting for a free vehicle (or pair) in the entrance
293     ride_id_t PreviousRide;
294     uint16_t PreviousRideTimeOut;
295     std::array<PeepThought, PEEP_MAX_THOUGHTS> Thoughts;
296     // 0x3F Litter Count split into lots of 3 with time, 0xC0 Time since last recalc
297     uint8_t LitterCount;
298     // 0x3F Sick Count split into lots of 3 with time, 0xC0 Time since last recalc
299     uint8_t DisgustingCount;
300     uint8_t AmountOfFood;
301     uint8_t AmountOfDrinks;
302     uint8_t AmountOfSouvenirs;
303     uint8_t VandalismSeen; // 0xC0 vandalism thought timeout, 0x3F vandalism tiles seen
304     uint8_t VoucherType;
305     union
306     {
307         ride_id_t VoucherRideId;
308         ShopItemIndex VoucherShopItem;
309     };
310     uint8_t SurroundingsThoughtTimeout;
311     uint8_t Angriness;
312     uint8_t TimeLost; // the time the peep has been lost when it reaches 254 generates the lost thought
313     uint8_t DaysInQueue;
314     uint8_t BalloonColour;
315     uint8_t UmbrellaColour;
316     uint8_t HatColour;
317     ride_id_t FavouriteRide;
318     uint8_t FavouriteRideRating;
319     uint64_t ItemFlags;
320 
321     void UpdateGuest();
322     void Tick128UpdateGuest(int32_t index);
323     int64_t GetFoodOrDrinkFlags() const;
324     int64_t GetEmptyContainerFlags() const;
325     bool HasDrink() const;
326     bool HasFoodOrDrink() const;
327     bool HasEmptyContainer() const;
328     void OnEnterRide(Ride* ride);
329     void OnExitRide(Ride* ride);
330     void UpdateSpriteType();
331     bool HeadingForRideOrParkExit() const;
332     void StopPurchaseThought(uint8_t ride_type);
333     void TryGetUpFromSitting();
334     void ChoseNotToGoOnRide(Ride* ride, bool peepAtRide, bool updateLastRide);
335     void PickRideToGoOn();
336     void ReadMap();
337     bool ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool thinking);
338     bool ShouldGoToShop(Ride* ride, bool peepAtShop);
339     bool ShouldFindBench();
340     bool UpdateWalkingFindBench();
341     bool UpdateWalkingFindBin();
342     void SpendMoney(money16& peep_expend_type, money32 amount, ExpenditureType type);
343     void SpendMoney(money32 amount, ExpenditureType type);
344     void SetHasRidden(const Ride* ride);
345     bool HasRidden(const Ride* ride) const;
346     void SetHasRiddenRideType(int32_t rideType);
347     bool HasRiddenRideType(int32_t rideType) const;
348     void SetParkEntryTime(int32_t entryTime);
349     int32_t GetParkEntryTime() const;
350     void CheckIfLost();
351     void CheckCantFindRide();
352     void CheckCantFindExit();
353     bool DecideAndBuyItem(Ride* ride, ShopItem shopItem, money32 price);
354     void SetSpriteType(PeepSpriteType new_sprite_type);
355     void HandleEasterEggName();
356     int32_t GetEasterEggNameId() const;
357     void UpdateEasterEggInteractions();
358     void InsertNewThought(PeepThoughtType thought_type);
359     void InsertNewThought(PeepThoughtType thought_type, ShopItem thought_arguments);
360     void InsertNewThought(PeepThoughtType thought_type, ride_id_t rideId);
361     void InsertNewThought(PeepThoughtType thought_type, uint16_t thought_arguments);
362     static Guest* Generate(const CoordsXYZ& coords);
363     bool UpdateQueuePosition(PeepActionType previous_action);
364     void RemoveFromQueue();
365 
366     uint64_t GetItemFlags() const;
367     void SetItemFlags(uint64_t itemFlags);
368     void RemoveAllItems();
369     void RemoveItem(ShopItem item);
370     void GiveItem(ShopItem item);
371     bool HasItem(ShopItem peepItem) const;
372     void Serialise(DataSerialiser& stream);
373 
374     // Removes the ride from the guests memory, this includes
375     // the history, thoughts, etc.
376     void RemoveRideFromMemory(ride_id_t rideId);
377 
378 private:
379     void UpdateRide();
UpdateOnRideGuest380     void UpdateOnRide(){}; // TODO
381     void UpdateWalking();
382     void UpdateQueuing();
383     void UpdateSitting();
384     void UpdateEnteringPark();
385     void UpdateLeavingPark();
386     void UpdateBuying();
387     void UpdateWatching();
388     void UpdateUsingBin();
389     void UpdateRideAtEntrance();
390     void UpdateRideAdvanceThroughEntrance();
391     void UpdateRideLeaveEntranceWaypoints(const Ride& ride);
392     uint8_t GetWaypointedSeatLocation(const Ride& ride, rct_ride_entry_vehicle* vehicle_type, uint8_t track_direction) const;
393     void UpdateRideFreeVehicleCheck();
394     void UpdateRideFreeVehicleEnterRide(Ride* ride);
395     void UpdateRideApproachVehicle();
396     void UpdateRideEnterVehicle();
397     void UpdateRideLeaveVehicle();
398     void UpdateRideApproachExit();
399     void UpdateRideInExit();
400     void UpdateRideApproachVehicleWaypoints();
401     void UpdateRideApproachExitWaypoints();
402     void UpdateRideApproachSpiralSlide();
403     void UpdateRideOnSpiralSlide();
404     void UpdateRideLeaveSpiralSlide();
405     void UpdateRideMazePathfinding();
406     void UpdateRideLeaveExit();
407     void UpdateRideShopApproach();
408     void UpdateRideShopInteract();
409     void UpdateRideShopLeave();
410     void UpdateRidePrepareForExit();
411     void loc_68F9F3();
412     void loc_68FA89();
413     int32_t CheckEasterEggName(int32_t index) const;
414     bool GuestHasValidXY() const;
415     void GivePassingPeepsPurpleClothes(Guest* passingPeep);
416     void GivePassingPeepsPizza(Guest* passingPeep);
417     void MakePassingPeepsSick(Guest* passingPeep);
418     void GivePassingPeepsIceCream(Guest* passingPeep);
419     Ride* FindBestRideToGoOn();
420     std::bitset<MAX_RIDES> FindRidesToGoOn();
421     bool FindVehicleToEnter(Ride* ride, std::vector<uint8_t>& car_array);
422     void GoToRideEntrance(Ride* ride);
423 };
424 
425 static_assert(sizeof(Guest) <= 512);
426 
427 enum
428 {
429     EASTEREGG_PEEP_NAME_MICHAEL_SCHUMACHER,
430     EASTEREGG_PEEP_NAME_JACQUES_VILLENEUVE,
431     EASTEREGG_PEEP_NAME_DAMON_HILL,
432     EASTEREGG_PEEP_NAME_MR_BEAN,
433     EASTEREGG_PEEP_NAME_CHRIS_SAWYER,
434     EASTEREGG_PEEP_NAME_KATIE_BRAYSHAW,
435     EASTEREGG_PEEP_NAME_MELANIE_WARN,
436     EASTEREGG_PEEP_NAME_SIMON_FOSTER,
437     EASTEREGG_PEEP_NAME_JOHN_WARDLEY,
438     EASTEREGG_PEEP_NAME_LISA_STIRLING,
439     EASTEREGG_PEEP_NAME_DONALD_MACRAE,
440     EASTEREGG_PEEP_NAME_KATHERINE_MCGOWAN,
441     EASTEREGG_PEEP_NAME_FRANCES_MCGOWAN,
442     EASTEREGG_PEEP_NAME_CORINA_MASSOURA,
443     EASTEREGG_PEEP_NAME_CAROL_YOUNG,
444     EASTEREGG_PEEP_NAME_MIA_SHERIDAN,
445     EASTEREGG_PEEP_NAME_KATIE_RODGER,
446     EASTEREGG_PEEP_NAME_EMMA_GARRELL,
447     EASTEREGG_PEEP_NAME_JOANNE_BARTON,
448     EASTEREGG_PEEP_NAME_FELICITY_ANDERSON,
449     EASTEREGG_PEEP_NAME_KATIE_SMITH,
450     EASTEREGG_PEEP_NAME_EILIDH_BELL,
451     EASTEREGG_PEEP_NAME_NANCY_STILLWAGON,
452     EASTEREGG_PEEP_NAME_DAVID_ELLIS
453 };
454 
455 extern uint8_t gGuestChangeModifier;
456 extern uint32_t gNumGuestsInPark;
457 extern uint32_t gNumGuestsInParkLastWeek;
458 extern uint32_t gNumGuestsHeadingForPark;
459 
460 extern money16 gGuestInitialCash;
461 extern uint8_t gGuestInitialHappiness;
462 extern uint8_t gGuestInitialHunger;
463 extern uint8_t gGuestInitialThirst;
464 
465 extern uint32_t gNextGuestNumber;
466 
467 void guest_set_name(uint16_t spriteIndex, const char* name);
468 
469 void peep_thought_set_format_args(const PeepThought* thought, Formatter& ft);
470 
471 void increment_guests_in_park();
472 void increment_guests_heading_for_park();
473 void decrement_guests_in_park();
474 void decrement_guests_heading_for_park();
475