ScummVM API documentation
cookingpuzzle.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef NANCY_ACTION_COOKINGPUZZLE_H
23 #define NANCY_ACTION_COOKINGPUZZLE_H
24 
25 #include "engines/nancy/commontypes.h"
26 #include "engines/nancy/action/puzzlerecord.h"
27 
28 namespace Nancy {
29 namespace Action {
30 
31 // Nancy16 diner cooking puzzle (AR 194). Ingredients are taken from bins and put into
32 // processors (microwave, grill, burger buns), which turn them into other foods and cook
33 // them over time. Finished foods are put on the plates of the customers' order tickets
34 // and served. Leaving food to cook for too long sets off the fire alarm.
35 class CookingPuzzle : public PuzzleRecord {
36 public:
37  CookingPuzzle() : PuzzleRecord(7) {}
38  virtual ~CookingPuzzle();
39 
40  void init() override;
41 
42  void readData(Common::SeekableReadStream &stream) override;
43  void execute() override;
44  void handleInput(NancyInput &input) override;
45 
46  bool isViewportRelative() const override { return true; }
47 
48 protected:
49  Common::String getRecordTypeName() const override { return "CookingPuzzle"; }
50 
51  enum Doneness : byte {
52  kUnderDone = 0,
53  kWellDone = 1,
54  kOverDone = 2
55  };
56 
57  static const uint kNumDoneness = 3;
58 
59  struct FoodType {
60  Common::String name;
61  byte initialDoneness = kUnderDone;
62  // Seconds per doneness step, picked at random within the range
63  float minCookTime = 0;
64  float maxCookTime = 0;
65  uint16 hoverCursor = 0;
66  Common::Point cursorHotspot; // moves the held food away from the cursor's center
67  Common::Rect binHotspot; // empty for foods that only come out of a processor
68  Common::Rect cursorSrcs[kNumDoneness];
69  Common::Rect processorSrcs[kNumDoneness];
70  Common::Rect plateSrcs[kNumDoneness];
71  RandomSoundBlock cookSound;
72  };
73 
74  // A food in play. The ones standing in for the bins are never used up.
75  struct Food {
76  const FoodType *type = nullptr;
77  bool isBin = false;
78  byte doneness = kUnderDone;
79  int32 cookTicks = 0;
80  int32 ticksPerStep = 0;
81  bool visibleInProcessor = true;
82  Common::Array<Food *> ingredients; // sorted by name
83  };
84 
85  struct Recipe {
86  Common::String input;
87  Common::String output;
89  };
90 
91  struct Slot {
92  Common::Rect dropHotspot;
93  Common::Rect addHotspot; // where ingredients go, and where the food is drawn
94  Common::Rect takeHotspot;
95  Food *food = nullptr;
96  Common::String recipeInput;
97  };
98 
99  struct Processor {
100  Common::Array<Recipe> recipes;
101  bool cooks = false;
102  uint16 takeCursor = 0;
103  Common::Array<Slot> slots;
104  };
105 
106  struct IngredientFlag {
107  Common::String ingredient;
108  FlagDescription flag;
109  };
110 
111  struct Order {
112  Common::String food;
113  int32 minCount = 0;
114  int32 maxCount = 0;
115  int32 count = 0; // rolled between the two
116  Common::Rect countDest;
118  Common::Array<Order> required;
119  Common::Array<Order> optional;
120  };
121 
122  struct Plate {
123  Common::Rect ticketHotspot;
124  Common::Rect ticketSrc;
125  bool acceptsBadlyCooked = false;
126  FlagDescription badlyCookedFlag;
127  Common::Array<Order> orders;
128  Common::Array<Food *> foods; // sorted by name
129  };
130 
131  struct PlateLayout {
132  Common::String food;
134  };
135 
136  static void readSoundBank(Common::SeekableReadStream &stream, RandomSoundBlock &sound);
137  static void readFoodType(Common::SeekableReadStream &stream, FoodType &food);
138  static void readOrder(Common::SeekableReadStream &stream, Order &order);
139  static void rollOrderCounts(Order &order);
140 
141  const FoodType *findFoodType(const Common::String &name) const;
142  const Recipe *findRecipe(const Processor &processor, const Common::String &input) const;
143  static const Order *findOrder(const Common::Array<Order> &orders, const Common::String &food);
144 
145  Food *createFood(const Common::String &typeName, const Food *source);
146  static void deleteFood(Food *food);
147  static void insertSorted(Common::Array<Food *> &list, Food *food);
148 
149  void holdFood(Food *food);
150  void releaseHeldFood(bool discard);
151 
152  bool clickManual(const Common::Point &pos);
153  bool clickPlates(const Common::Point &pos);
154  bool clickProcessors(const Common::Point &pos);
155  bool clickBins(const Common::Point &pos);
156  bool clickGarbage(const Common::Point &pos);
157  bool putOnPlate(Plate &plate);
158  bool servePlate(Plate &plate);
159 
160  // Cheat: serves every order that is left, the way plates with just what they need
161  // would have been served
162  void serveAllPlates();
163  static void addRequiredIngredientFlags(const Order &order, Common::Array<FlagDescription> &flags);
164  bool foodMatches(const Food *food, const Order &order, Common::Array<FlagDescription> &flags,
165  bool checkDoneness, bool &allWellDone) const;
166 
167  bool updateCursor(const Common::Point &pos);
168  void update(int32 ticks);
169  bool cook(Food *food, int32 ticks);
170 
171  void redraw();
172  void drawFood(const Food *food, const Common::Rect &dest, bool jitter, uint32 &randSeed);
173  void drawOrderCounts(const Order &order, const Graphics::Font *font, uint32 color);
174 
175  void startEnding(const SceneChangeWithFlag &scene, const RandomSoundBlock &sound);
176 
177  // -- File data --
178  Common::Array<FoodType> _foodTypes;
179  Common::Array<Processor> _processors;
180 
181  Common::Path _plateImageName;
182  Common::Rect _plateSrc;
183  Common::Rect _plateDest;
184  Common::Rect _plateBarArea; // clicking it, or outside the plate, puts the plate away
185  Common::Rect _serveHotspot;
186  Common::Rect _ticketIconSrc;
187  Common::Array<PlateLayout> _plateLayouts;
188  uint16 _plateFoodCursor = 0;
189  uint16 _plateCloseCursor = 0;
190  uint16 _serveCursor = 0;
191  uint16 _ticketCursor = 0;
192  Common::Rect _ticketDest;
193  Common::String _countFontName;
194  uint32 _countColor = 0; // ARGB
195  float _captionTime = 0; // seconds the served-order caption stays up after its sound
196  RandomSoundBlock _orderRightSound;
197  RandomSoundBlock _orderWrongSound;
198  RandomSoundBlock _allServedSound;
199  Common::Array<Plate> _plates;
200 
201  Common::Array<Common::Path> _manualPageNames;
202  Common::Rect _manualPrevHotspot;
203  Common::Rect _manualNextHotspot;
204  Common::Rect _manualOpenHotspot;
205  Common::Rect _manualCloseHotspot;
206  Common::Rect _manualSrc;
207  Common::Rect _manualDest;
208  uint16 _manualPrevCursor = 0;
209  uint16 _manualNextCursor = 0;
210  uint16 _manualOpenCursor = 0;
211  uint16 _manualCloseCursor = 0;
212  RandomSoundBlock _pageFlipSound;
213  RandomSoundBlock _manualOpenSound;
214  RandomSoundBlock _manualCloseSound;
215 
216  Common::Rect _garbageHotspot;
217  RandomSoundBlock _garbageSound;
218  uint16 _heldCursor = 0;
219  SceneChangeWithFlag _fireScene;
220  RandomSoundBlock _fireSound;
221 
222  // -- Runtime state --
223  Common::Array<Food *> _bins;
224  Food *_heldFood = nullptr;
225  int _openPlate = -1;
226  bool _manualOpen = false;
227  uint _manualPage = 0;
228 
229  bool _rightSoundPending = false;
230  bool _wrongSoundPending = false;
231  int32 _captionTicks = 0;
232 
233  uint32 _lastTickTime = 0;
234  bool _isEnding = false;
235  bool _exitRequested = false;
236  SceneChangeWithFlag _endScene;
237  SoundDescription _endSound;
238  Common::Point _mousePos;
239 
240  Graphics::ManagedSurface _plateImage;
242 };
243 
244 } // End of namespace Action
245 } // End of namespace Nancy
246 
247 #endif // NANCY_ACTION_COOKINGPUZZLE_H
Definition: managed_surface.h:51
Definition: str.h:59
Definition: font.h:83
Definition: array.h:52
Definition: cookingpuzzle.h:99
Definition: rect.h:536
Definition: path.h:52
Definition: stream.h:745
Definition: input.h:41
Definition: cookingpuzzle.h:111
Definition: commontypes.h:206
Definition: cookingpuzzle.h:35
Definition: cookingpuzzle.h:131
Definition: cookingpuzzle.h:85
Definition: commontypes.h:324
Definition: rect.h:144
Definition: cookingpuzzle.h:91
Definition: cookingpuzzle.h:59
Definition: cookingpuzzle.h:106
Definition: puzzlerecord.h:37
Definition: commontypes.h:306
Definition: cookingpuzzle.h:75
Definition: commontypes.h:201
Definition: cookingpuzzle.h:122
Definition: actionmanager.h:32