ScummVM API documentation
miscrecords.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_RECORDTYPES_H
23 #define NANCY_ACTION_RECORDTYPES_H
24 
25 #include "engines/nancy/action/actionrecord.h"
26 #include "engines/nancy/enginedata.h"
27 
28 namespace Nancy {
29 
30 class NancyEngine;
31 
32 namespace Action {
33 
34 // Changes the palette for the current scene's background. TVD only.
36 public:
37  void readData(Common::SeekableReadStream &stream) override;
38  void execute() override;
39 
40  byte _paletteID;
41  byte _unknownEnum; // enum w values 1-3
42  uint16 _paletteStart;
43  uint16 _paletteSize;
44 
45 protected:
46  Common::String getRecordTypeName() const override { return "PaletteThisScene"; }
47 };
48 
49 // Changes the palette for the next scene's background. TVD only.
51 public:
52  void readData(Common::SeekableReadStream &stream) override;
53  void execute() override;
54 
55  byte _paletteID;
56 
57 protected:
58  Common::String getRecordTypeName() const override { return "PaletteNextScene"; }
59 };
60 
61 // Turns on (temporary) lightning effect. TVD Only.
62 class LightningOn : public ActionRecord {
63 public:
64  void readData(Common::SeekableReadStream &stream) override;
65  void execute() override;
66 
67  int16 _distance;
68  uint16 _pulseTime;
69  int16 _rgbPercent;
70 
71 protected:
72  Common::String getRecordTypeName() const override { return "LightningOn"; }
73 };
74 
75 // Requests either a fade between two scenes, or a fade to black; fade executes when scene is changed. Nancy2 and up.
76 class SpecialEffect : public ActionRecord {
77 public:
78  void readData(Common::SeekableReadStream &stream) override;
79  void execute() override;
80 
81  byte _type = 1;
82  uint16 _fadeToBlackTime = 0;
83  uint16 _frameTime = 0;
84  uint16 _totalTime = 0;
85  Common::Rect _rect;
86 
87 protected:
88  Common::String getRecordTypeName() const override { return "SpecialEffect"; }
89 };
90 
91 // Adds a caption to the textbox. The Nancy 11+ "autotext" variant (AR 81),
92 // carries an extra header that makes the record wait for a sound to finish
93 // or a timer to elapse before it completes; in both variants the body is
94 // either inline text or resolved from an AUTOTEXT key.
95 class TextBoxWrite : public ActionRecord {
96 public:
97  enum WaitMode { kWaitNone = 0, kWaitForSound = 1, kWaitForTimer = 2 };
98 
99  TextBoxWrite(bool isAutotext = false) : _isAutotext(isAutotext) {}
100 
101  void readData(Common::SeekableReadStream &stream) override;
102  void execute() override;
103 
104  Common::String _text;
105 
106  // Nancy 11+ AR 81 only
107  bool _isAutotext;
108  int16 _waitMode = 0;
109  uint16 _soundChannel = 0;
110  uint32 _waitTimeMs = 0;
111 
112 protected:
113  Common::String getRecordTypeName() const override { return _isAutotext ? "AutotextTextBoxWrite" : "TextBoxWrite"; }
114 
115 private:
116  uint32 _endTime = 0;
117 };
118 
119 // Clears the textbox. Used very rarely.
120 class TextboxClear : public ActionRecord {
121 public:
122  void readData(Common::SeekableReadStream &stream) override;
123  void execute() override;
124 
125 protected:
126  Common::String getRecordTypeName() const override { return "TextboxClear"; }
127 };
128 
129 // Nancy 10+ replacement for TextBoxWrite. Pushes a line of conversation
130 // text into the new (UICO-driven) textbox
131 class FrameTextBox : public ActionRecord {
132 public:
133  FrameTextBox(bool fullMode) : _fullMode(fullMode) {}
134 
135  void readData(Common::SeekableReadStream &stream) override;
136  void execute() override;
137 
138  bool _fullMode;
139  Common::String _text;
140 
141 protected:
142  Common::String getRecordTypeName() const override { return "FrameTextBox"; }
143 };
144 
145 // Nancy 10+ opcode 29. Toggles whether one of the taskbar popups
146 // (inventory / notebook / cellphone) is enabled.
147 class ControlUIItems : public ActionRecord {
148 public:
149  void readData(Common::SeekableReadStream &stream) override;
150  void execute() override;
151 
152  uint16 _uiButton = 0;
153  byte _autoOpenOrBadgeSound = 0; // 1 = auto-open popup; 0/10 = notification-badge click-sound selector
154  byte _flagB = 0; // 0 = clear, 1 = enable+remember scene
155  int16 _startScene = 0; // start scene id (9999 = none); also the auto-open cell phone's call target
156  int16 _endScene = 0; // end scene id (9999 = none)
157 
158  Common::String getRecordExtraInfo() const override {
159  return Common::String::format("uiButton: %d, autoOpenOrBadgeSound: %d, flagB: %d, startScene: %d, endScene: %d",
160  _uiButton, _autoOpenOrBadgeSound, _flagB, _startScene, _endScene);
161  }
162 
163 protected:
164  Common::String getRecordTypeName() const override { return "ControlUIItems"; }
165 };
166 
167 // Nancy 10+ opcode 32. Prepares a UI popup
169 public:
170  void readData(Common::SeekableReadStream &stream) override;
171  void execute() override;
172 
173  int32 _uiType = 0;
174  int32 _signalValue = 0;
175 
176 protected:
177  Common::String getRecordTypeName() const override { return "UIPopupPrepScene"; }
178 };
179 
180 // Nancy 10+ opcode 131. Pushes a new entry into either the cellphone
181 // search-results list (mode 0) or the URL link list (mode 1).
182 class AddSearchLink : public ActionRecord {
183 public:
184  void readData(Common::SeekableReadStream &stream) override;
185  void execute() override;
186 
187  int16 _mode = 0;
188  SearchLink _link;
189 
190  Common::String getRecordExtraInfo() const override {
191  return Common::String::format("Key: %s, Value: %s, Mode: %d, Extra: %d, Flag: %d, EventFlag: %d",
192  _link.key.c_str(), _link.value.c_str(), _mode, _link.extra, _link.flag, _link.eventFlag);
193  }
194 
195 protected:
196  Common::String getRecordTypeName() const override { return "AddSearchLink"; }
197 };
198 
199 // Sets the cellphone's battery/signal indicators. Modes 0/1 toggle the
200 // battery (normal / low) and 2/3 toggle the signal (normal / no signal).
202 public:
203  void readData(Common::SeekableReadStream &stream) override;
204  void execute() override;
205 
206  uint16 _mode = 0;
207 
208 protected:
209  Common::String getRecordTypeName() const override { return "SetCellPhoneBatteryAndSignal"; }
210 };
211 
212 // Adds a new entry to the cellphone directory, or overwrites an existing
213 // one matched by dial pattern. Used to unlock contacts as the player
214 // progresses (Nancy 10+).
216 public:
217  void readData(Common::SeekableReadStream &stream) override;
218  void execute() override;
219 
220  UICL::Contact _contact;
221 
222  Common::String getRecordExtraInfo() const override {
223  return Common::String::format("Contact: %s", _contact.name.c_str());
224  }
225 
226 protected:
227  Common::String getRecordTypeName() const override { return "ChangeCellPhoneInfo"; }
228 };
229 
230 // Returns from a cellphone-driven conversation scene to the pre-call scene.
231 // sceneID == kNoScene pops the saved scene; any other sceneID overrides it.
233 public:
234  void readData(Common::SeekableReadStream &stream) override;
235  void execute() override;
236 
237  SceneChangeDescription _sceneChange;
238 
239 protected:
240  Common::String getRecordTypeName() const override { return "CellPhonePopCellSceneFromStack"; }
241 };
242 
243 // Changes the in-game time. Used prior to the introduction of SetPlayerClock.
245 public:
246  void readData(Common::SeekableReadStream &stream) override;
247  void execute() override;
248 
249  byte _relative;
250  uint16 _hours;
251  uint16 _minutes;
252 
253 protected:
254  Common::String getRecordTypeName() const override { return "BumpPlayerClock"; }
255 };
256 
257 // Creates a Second Chance save.
259 public:
260  void readData(Common::SeekableReadStream &stream) override;
261  void execute() override;
262 
263 protected:
264  Common::String getRecordTypeName() const override { return "SaveContinueGame"; }
265 };
266 
267 // Stops the screen from rendering. Our rendering system is different from the original engine's,
268 // so we have no use for this.
270 public:
271  void readData(Common::SeekableReadStream &stream) override;
272 
273 protected:
274  Common::String getRecordTypeName() const override { return "TurnOffMainRendering"; }
275 };
276 
277 // Restarts screen rendering. Our rendering system is different from the original engine's,
278 // so we have no use for this.
280 public:
281  void readData(Common::SeekableReadStream &stream) override;
282 
283 protected:
284  Common::String getRecordTypeName() const override { return "TurnOnMainRendering"; }
285 };
286 
287 // Starts the timer. Used in combination with Dependency types that check for
288 // how much time has passed since the timer was started. Nancy 11 also carries a
289 // software-timer slot index (see TimerControl). From Nancy 12 the record became
290 // a general "Control a Timer" command: a slot index plus a command whose value
291 // selects a variable-size payload.
293 public:
294  enum Command {
295  kStart = 0, // Begin counting up from the current time
296  kClear = 1, // Reset the slot back to idle
297  kConfigOneShot = 2, // Set target/payload; fire once, then reset
298  kConfigRepeating = 3, // Set target/payload; fire once, then keep counting
299  kPause = 4, // Suspend counting
300  kAddTime = 5, // Add the duration to the elapsed time
301  kSubtractTime = 6, // Subtract the duration from the elapsed time
302  kSetTime = 7 // Set the elapsed time to the duration
303  };
304 
305  void readData(Common::SeekableReadStream &stream) override;
306  void execute() override;
307 
308  int16 _timerIndex = 0; // Software-timer slot (Nancy 11+)
309  int16 _command = kStart; // Nancy 12+
310  int16 _hours = 0;
311  int16 _minutes = 0;
312  int16 _seconds = 0;
313  SoundDescription _sound; // Played on expiry when configured
314  Common::Array<FlagDescription> _flags; // Fired on expiry when configured
315 
316 protected:
317  Common::String getRecordTypeName() const override { return "ResetAndStartTimer"; }
318 };
319 
320 // Stops the timer.
321 class StopTimer : public ActionRecord {
322 public:
323  void readData(Common::SeekableReadStream &stream) override;
324  void execute() override;
325 
326  byte _timerIndex = 0; // Nancy 11+ software-timer slot
327 
328 protected:
329  Common::String getRecordTypeName() const override { return "StopTimer"; }
330 };
331 
332 // Nancy 11+ AR 69 (AT_TIMER_CONTROL). Issues a command to one of the 10
333 // software-timer slots (see TimerData::Timer). The fixed-size chunk
334 // (0xc4 header + count*4 flag entries) carries a slot index, a command, a
335 // target duration, an optional sound + caption, and the event flags to fire
336 // when the timer expires.
337 class TimerControl : public ActionRecord {
338 public:
339  enum Command {
340  kReset = 0, // Clear the slot back to idle
341  kStart = 1, // Begin counting, with no target
342  kPause = 2, // Suspend counting
343  kAddTime = 3, // Add the duration to the elapsed time
344  kSubtractTime = 4, // Subtract the duration from the elapsed time
345  kConfigOneShot = 5, // Set target/payload; fire once, then reset
346  kConfigRepeating = 6 // Set target/payload; fire once, then keep running
347  };
348 
349  void readData(Common::SeekableReadStream &stream) override;
350  void execute() override;
351 
352  int16 _timerIndex = 0;
353  int16 _command = 0;
354  int16 _hours = 0;
355  int16 _minutes = 0;
356  int16 _seconds = 0;
357 
358  SoundDescription _sound;
359  Common::String _autotextKey;
360  Common::String _caption;
362 
363 protected:
364  Common::String getRecordTypeName() const override { return "TimerControl"; }
365 };
366 
367 // Nancy 11+ AR 30. Disables the player's ability to scroll/pan the viewport
368 // (both mouse-edge and keyboard movement). State persists across scene changes.
370 public:
371  void readData(Common::SeekableReadStream &stream) override;
372  void execute() override;
373 
374 protected:
375  Common::String getRecordTypeName() const override { return "StopPlayerScrolling"; }
376 };
377 
378 // Nancy 11+ AR 31. Re-enables the player's ability to scroll/pan the viewport.
380 public:
381  void readData(Common::SeekableReadStream &stream) override;
382  void execute() override;
383 
384 protected:
385  Common::String getRecordTypeName() const override { return "StartPlayerScrolling"; }
386 };
387 
388 // Returns the player back to the main menu
389 class GotoMenu : public ActionRecord {
390 public:
391  void readData(Common::SeekableReadStream &stream) override;
392  void execute() override;
393 
394 protected:
395  Common::String getRecordTypeName() const override { return "GotoMenu"; }
396 };
397 
398 // Stops the game and boots the player back to the Menu screen, while also making sure
399 // they can't Continue. The devs took care to add Second Chance saves before every one
400 // of these, to make sure the player can return to a state just before the dangerous part.
401 class LoseGame : public ActionRecord {
402 public:
403  void readData(Common::SeekableReadStream &stream) override;
404  void execute() override;
405 
406 protected:
407  Common::String getRecordTypeName() const override { return "LoseGame"; }
408 };
409 
410 // Adds a scene to the "stack" (which is just a single value). Used in combination with PopScene.
411 class PushScene : public ActionRecord {
412 public:
413  void readData(Common::SeekableReadStream &stream) override;
414  void execute() override;
415 
416 protected:
417  Common::String getRecordTypeName() const override { return "PushScene"; }
418 };
419 
420 // Changes to the scene pushed onto the "stack". Scenes can be pushed via PushScene, or Conversation types.
421 class PopScene : public ActionRecord {
422 public:
423  void readData(Common::SeekableReadStream &stream) override;
424  void execute() override;
425 
426 protected:
427  Common::String getRecordTypeName() const override { return "PopScene"; }
428 };
429 
430 // Ends the game and boots the player to the Credits screen.
431 // TODO: The original engine also sets a config option called PlayerWonTheGame,
432 // which in turn is used to trigger whichever event flag marks that the player
433 // has beat the game at least once, which in turn allows easter eggs to be shown.
434 // We currently support none of this.
435 class WinGame : public ActionRecord {
436 public:
437  void readData(Common::SeekableReadStream &stream) override;
438  void execute() override;
439 
440 protected:
441  Common::String getRecordTypeName() const override { return "WinGame"; }
442 };
443 
444 // Checks how many hints the player is allowed to get. If they are still allowed hints,
445 // it selects an appropriate one and plays its sound/displays its caption in the Textbox.
446 // The hint system was _only_ used in nancy1, since it's pretty limited and overly punishing.
447 class HintSystem : public ActionRecord {
448 public:
449  void readData(Common::SeekableReadStream &stream) override;
450  void execute() override;
451 
452  byte _characterID; // 0x00
453  SoundDescription _genericSound; // 0x01
454 
455  const Hint *selectedHint;
456  int16 _hintID;
457 
458  void selectHint();
459 
460 protected:
461  Common::String getRecordTypeName() const override { return "HintSystem"; }
462 };
463 
464 // Added in Nancy12 (AR 132). Adjusts a UI overlay resource (from the UIRC boot
465 // chunk) at runtime -- e.g. paying coins from the purse (resource 0). Applying
466 // the change plays a sound, optionally shows a transient overlay (a sprite and/or
467 // the resource's numeric value) and can change scene on success.
469 public:
471 
472  void init() override;
473  void readData(Common::SeekableReadStream &stream) override;
474  void execute() override;
475  void handleInput(NancyInput &input) override;
476 
477  bool isViewportRelative() const override { return true; }
478 
479 protected:
480  Common::String getRecordTypeName() const override { return "ResourceUse"; }
481 
482  // Applies the resource change (respecting affordability), sets the event
483  // flag and starts the matching outcome sound.
484  void applyChange();
485 
486  int16 _resourceIndex = 0;
487  int16 _amount = 0;
488  byte _mode = 0; // 0 = set the resource, non-zero = add (clamped to >= 0)
489  FlagDescription _flag; // event flag set when the change is applied
490 
491  Common::String _failSoundName; // played when the change can't be applied
492  Common::String _successSoundName; // played when it is applied
493 
494  // When this rect is non-degenerate the change is interactive: the player
495  // clicks it (e.g. a coin slot) to pay. A degenerate rect applies at once.
496  Common::Rect _paymentHotspot;
497  byte _useResourceCursor = 0; // 0 = normal cursor, else the resource's own hover cursor
498 
499  uint16 _sceneID = kNoScene; // scene entered on success (9999 = none)
500  uint16 _continueSceneSound = 0;
501 
502  bool _drawResourceOverlay = false; // blit the resource's UIRC sprite
503  Common::Point _overlayDest;
504  bool _drawResourceValue = false; // draw the resource's numeric value
505  Common::Point _valueDest;
506 
507  SoundDescription _sound;
508  bool _hasSound = false;
509  bool _interactive = false;
510  bool _paymentResolved = false;
511  bool _paymentApplied = false;
512 };
513 
514 } // End of namespace Action
515 } // End of namespace Nancy
516 
517 #endif // NANCY_ACTION_MISCRECORDS_H
Definition: miscrecords.h:62
Definition: miscrecords.h:147
Definition: str.h:59
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
Definition: miscrecords.h:401
Definition: commontypes.h:165
Definition: array.h:52
Definition: miscrecords.h:369
Definition: enginedata.h:601
Definition: commontypes.h:339
Definition: miscrecords.h:411
Definition: miscrecords.h:435
Definition: miscrecords.h:279
Definition: rect.h:536
Definition: actionrecord.h:174
Definition: miscrecords.h:95
Definition: stream.h:745
Definition: input.h:41
Definition: miscrecords.h:468
Definition: miscrecords.h:76
Definition: miscrecords.h:120
Definition: actionrecord.h:161
Definition: miscrecords.h:321
Definition: miscrecords.h:35
Definition: miscrecords.h:389
Definition: miscrecords.h:379
Definition: miscrecords.h:269
Definition: actionrecord.h:98
Definition: miscrecords.h:201
Definition: rect.h:144
Definition: miscrecords.h:168
Definition: miscrecords.h:421
Definition: miscrecords.h:131
Definition: miscrecords.h:258
Definition: miscrecords.h:337
Definition: commontypes.h:282
Definition: commontypes.h:180
Definition: miscrecords.h:292
Definition: miscrecords.h:50
Definition: miscrecords.h:244
Definition: miscrecords.h:215
Definition: miscrecords.h:447
Definition: actionmanager.h:32