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 #include "engines/nancy/puzzledata.h"
28 
29 namespace Nancy {
30 
31 class NancyEngine;
32 
33 namespace Action {
34 
35 // Changes the palette for the current scene's background. TVD only.
37 public:
38  void readData(Common::SeekableReadStream &stream) override;
39  void execute() override;
40 
41  byte _paletteID;
42  byte _unknownEnum; // enum w values 1-3
43  uint16 _paletteStart;
44  uint16 _paletteSize;
45 
46 protected:
47  Common::String getRecordTypeName() const override { return "PaletteThisScene"; }
48 };
49 
50 // Changes the palette for the next scene's background. TVD only.
52 public:
53  void readData(Common::SeekableReadStream &stream) override;
54  void execute() override;
55 
56  byte _paletteID;
57 
58 protected:
59  Common::String getRecordTypeName() const override { return "PaletteNextScene"; }
60 };
61 
62 // Turns on (temporary) lightning effect. TVD Only.
63 class LightningOn : public ActionRecord {
64 public:
65  void readData(Common::SeekableReadStream &stream) override;
66  void execute() override;
67 
68  int16 _distance;
69  uint16 _pulseTime;
70  int16 _rgbPercent;
71 
72 protected:
73  Common::String getRecordTypeName() const override { return "LightningOn"; }
74 };
75 
76 // Requests either a fade between two scenes, or a fade to black; fade executes when scene is changed. Nancy2 and up.
77 class SpecialEffect : public ActionRecord {
78 public:
79  void readData(Common::SeekableReadStream &stream) override;
80  void execute() override;
81 
82  byte _type = 1;
83  uint16 _fadeToBlackTime = 0;
84  uint16 _frameTime = 0;
85  uint16 _totalTime = 0;
86  Common::Rect _rect;
87 
88 protected:
89  Common::String getRecordTypeName() const override { return "SpecialEffect"; }
90 };
91 
92 // Adds a caption to the textbox. The Nancy 11+ "autotext" variant (AR 81),
93 // carries an extra header that makes the record wait for a sound to finish
94 // or a timer to elapse before it completes; in both variants the body is
95 // either inline text or resolved from an AUTOTEXT key.
96 class TextBoxWrite : public ActionRecord {
97 public:
98  enum WaitMode { kWaitNone = 0, kWaitForSound = 1, kWaitForTimer = 2 };
99  enum WriteType { kTextBoxWrite, kAutotextWrite };
100 
101  TextBoxWrite(WriteType writeType) : _writeType(writeType) {}
102 
103  void readData(Common::SeekableReadStream &stream) override;
104  void execute() override;
105 
106  Common::String _text;
107 
108  // Nancy 11+ AR 81 only
109  WriteType _writeType;
110  int16 _waitMode = 0;
111  uint16 _soundChannel = 0;
112  uint32 _waitTimeMs = 0;
113 
114 protected:
115  Common::String getRecordTypeName() const override { return _writeType == kAutotextWrite ? "AutotextTextBoxWrite" : "TextBoxWrite"; }
116 
117 private:
118  uint32 _endTime = 0;
119 };
120 
121 // Clears the textbox. Used very rarely.
122 class TextboxClear : public ActionRecord {
123 public:
124  void readData(Common::SeekableReadStream &stream) override;
125  void execute() override;
126 
127 protected:
128  Common::String getRecordTypeName() const override { return "TextboxClear"; }
129 };
130 
131 // Nancy 10+ replacement for TextBoxWrite. Pushes a line of conversation
132 // text into the new (UICO-driven) textbox
133 class FrameTextBox : public ActionRecord {
134 public:
135  enum BoxMode { kNormalBox, kFullBox };
136 
137  FrameTextBox(BoxMode boxMode) : _boxMode(boxMode) {}
138 
139  void readData(Common::SeekableReadStream &stream) override;
140  void execute() override;
141 
142  BoxMode _boxMode;
143  Common::String _text;
144 
145 protected:
146  Common::String getRecordTypeName() const override { return "FrameTextBox"; }
147 };
148 
149 // Nancy 10+ opcode 29. Toggles whether one of the taskbar popups
150 // (inventory / notebook / cellphone) is enabled.
151 class ControlUIItems : public ActionRecord {
152 public:
153  void readData(Common::SeekableReadStream &stream) override;
154  void execute() override;
155 
156  uint16 _uiButton = 0;
157  byte _characterIndex = kPlayerCharacterActive; // Nancy15+: whose taskbar the disable applies to
158  byte _autoOpenOrBadgeSound = 0; // 1 = auto-open popup; 0/10 = notification-badge click-sound selector
159  byte _flagB = 0; // 0 = clear, 1 = enable+remember scene
160  int16 _startScene = 0; // start scene id (9999 = none); also the auto-open cell phone's call target
161  int16 _endScene = 0; // end scene id (9999 = none)
162 
163  Common::String getRecordExtraInfo() const override {
164  return Common::String::format("uiButton: %d, character: %d, autoOpenOrBadgeSound: %d, flagB: %d, startScene: %d, endScene: %d",
165  _uiButton, _characterIndex, _autoOpenOrBadgeSound, _flagB, _startScene, _endScene);
166  }
167 
168 protected:
169  Common::String getRecordTypeName() const override { return "ControlUIItems"; }
170 };
171 
172 // Nancy 10+ opcode 32. Prepares a UI popup
174 public:
175  void readData(Common::SeekableReadStream &stream) override;
176  void execute() override;
177 
178  int32 _uiType = 0;
179  int32 _signalValue = 0;
180 
181 protected:
182  Common::String getRecordTypeName() const override { return "UIPopupPrepScene"; }
183 };
184 
185 // Nancy 10+ opcode 131. Pushes a new entry into either the cellphone
186 // search-results list (mode 0) or the URL link list (mode 1).
187 class AddSearchLink : public ActionRecord {
188 public:
189  void readData(Common::SeekableReadStream &stream) override;
190  void execute() override;
191 
192  int16 _mode = 0;
193  SearchLink _link;
194 
195  Common::String getRecordExtraInfo() const override {
196  return Common::String::format("Key: %s, Value: %s, Mode: %d, Extra: %d, Flag: %d, EventFlag: %d",
197  _link.key.c_str(), _link.value.c_str(), _mode, _link.extra, _link.flag, _link.eventFlag);
198  }
199 
200 protected:
201  Common::String getRecordTypeName() const override { return "AddSearchLink"; }
202 };
203 
204 // Sets the cellphone's battery/signal indicators. Modes 0/1 toggle the
205 // battery (normal / low) and 2/3 toggle the signal (normal / no signal).
207 public:
208  void readData(Common::SeekableReadStream &stream) override;
209  void execute() override;
210 
211  uint16 _mode = 0;
212 
213 protected:
214  Common::String getRecordTypeName() const override { return "SetCellPhoneBatteryAndSignal"; }
215 };
216 
217 // Adds a new entry to the cellphone directory, or overwrites an existing
218 // one matched by dial pattern. Used to unlock contacts as the player
219 // progresses (Nancy 10+).
221 public:
222  void readData(Common::SeekableReadStream &stream) override;
223  void execute() override;
224 
225  UICL::Contact _contact;
226 
227  Common::String getRecordExtraInfo() const override {
228  return Common::String::format("Contact: %s", _contact.name.c_str());
229  }
230 
231 protected:
232  Common::String getRecordTypeName() const override { return "ChangeCellPhoneInfo"; }
233 };
234 
235 // Returns from a cellphone-driven conversation scene to the pre-call scene.
236 // sceneID == kNoScene pops the saved scene; any other sceneID overrides it.
238 public:
239  void readData(Common::SeekableReadStream &stream) override;
240  void execute() override;
241 
242  SceneChangeDescription _sceneChange;
243 
244 protected:
245  Common::String getRecordTypeName() const override { return "CellPhonePopCellSceneFromStack"; }
246 };
247 
248 // Changes the in-game time. Used prior to the introduction of SetPlayerClock.
250 public:
251  void readData(Common::SeekableReadStream &stream) override;
252  void execute() override;
253 
254  byte _relative;
255  int16 _hours;
256  int16 _minutes;
257 
258 protected:
259  Common::String getRecordTypeName() const override { return "BumpPlayerClock"; }
260 };
261 
262 // Creates a Second Chance save.
264 public:
265  void readData(Common::SeekableReadStream &stream) override;
266  void execute() override;
267 
268 protected:
269  Common::String getRecordTypeName() const override { return "SaveContinueGame"; }
270 };
271 
272 // Nancy9 AR 148, moved to AR 141 in Nancy12. Saves a cropped picture of the
273 // current frame to a PNG file. Used as an easter egg, e.g. on the sandcastle
274 // screen in Danger on Deception Island.
275 class MakeScreenFile : public ActionRecord {
276 public:
277  void readData(Common::SeekableReadStream &stream) override;
278  void execute() override;
279 
280  Common::String _filename;
281  Common::Rect _cropRect;
282 
283  Common::String getRecordExtraInfo() const override {
284  return Common::String::format("Filename: %s.png, crop rect: (%d, %d, %d, %d)",
285  _filename.c_str(), _cropRect.left, _cropRect.top, _cropRect.right, _cropRect.bottom);
286  }
287 
288 protected:
289  Common::String getRecordTypeName() const override { return "MakeScreenFile"; }
290 };
291 
292 // Stops the screen from rendering. Our rendering system is different from the original engine's,
293 // so we have no use for this.
295 public:
296  void readData(Common::SeekableReadStream &stream) override;
297 
298 protected:
299  Common::String getRecordTypeName() const override { return "TurnOffMainRendering"; }
300 };
301 
302 // Restarts screen rendering. Our rendering system is different from the original engine's,
303 // so we have no use for this.
305 public:
306  void readData(Common::SeekableReadStream &stream) override;
307 
308 protected:
309  Common::String getRecordTypeName() const override { return "TurnOnMainRendering"; }
310 };
311 
312 // Starts the timer. Used in combination with Dependency types that check for
313 // how much time has passed since the timer was started. Nancy 11 also carries a
314 // software-timer slot index (see TimerControl). From Nancy 12 the record became
315 // a general "Control a Timer" command: a slot index plus a command whose value
316 // selects a variable-size payload.
318 public:
319  enum Command {
320  kStart = 0, // Begin counting up from the current time
321  kClear = 1, // Reset the slot back to idle
322  kConfigOneShot = 2, // Set target/payload; fire once, then reset
323  kConfigRepeating = 3, // Set target/payload; fire once, then keep counting
324  kPause = 4, // Suspend counting
325  kAddTime = 5, // Add the duration to the elapsed time
326  kSubtractTime = 6, // Subtract the duration from the elapsed time
327  kSetTime = 7 // Set the elapsed time to the duration
328  };
329 
330  void readData(Common::SeekableReadStream &stream) override;
331  void execute() override;
332 
333  int16 _timerIndex = 0; // Software-timer slot (Nancy 11+)
334  int16 _command = kStart; // Nancy 12+
335  int16 _hours = 0;
336  int16 _minutes = 0;
337  int16 _seconds = 0;
338  int16 _milliseconds = 0;
339  SoundDescription _sound; // Played on expiry when configured
340  Common::Array<FlagDescription> _flags; // Fired on expiry when configured
341 
342 protected:
343  Common::String getRecordTypeName() const override { return "ResetAndStartTimer"; }
344 };
345 
346 // Stops the timer.
347 class StopTimer : public ActionRecord {
348 public:
349  void readData(Common::SeekableReadStream &stream) override;
350  void execute() override;
351 
352  byte _timerIndex = 0; // Nancy 11+ software-timer slot
353 
354 protected:
355  Common::String getRecordTypeName() const override { return "StopTimer"; }
356 };
357 
358 // Nancy 11+ AR 69 (AT_TIMER_CONTROL). Issues a command to one of the 10
359 // software-timer slots (see TimerData::Timer). The fixed-size chunk
360 // (0xc4 header + count*4 flag entries) carries a slot index, a command, a
361 // target duration, an optional sound + caption, and the event flags to fire
362 // when the timer expires.
363 class TimerControl : public ActionRecord {
364 public:
365  enum Command {
366  kReset = 0, // Clear the slot back to idle
367  kStart = 1, // Begin counting, with no target
368  kPause = 2, // Suspend counting
369  kAddTime = 3, // Add the duration to the elapsed time
370  kSubtractTime = 4, // Subtract the duration from the elapsed time
371  kConfigOneShot = 5, // Set target/payload; fire once, then reset
372  kConfigRepeating = 6 // Set target/payload; fire once, then keep running
373  };
374 
375  void readData(Common::SeekableReadStream &stream) override;
376  void execute() override;
377 
378  int16 _timerIndex = 0;
379  int16 _command = 0;
380  int16 _hours = 0;
381  int16 _minutes = 0;
382  int16 _seconds = 0;
383 
384  SoundDescription _sound;
385  Common::String _autotextKey;
386  Common::String _caption;
388 
389 protected:
390  Common::String getRecordTypeName() const override { return "TimerControl"; }
391 };
392 
393 // Nancy 11+ AR 30. Disables the player's ability to scroll/pan the viewport
394 // (both mouse-edge and keyboard movement). State persists across scene changes.
396 public:
397  void readData(Common::SeekableReadStream &stream) override;
398  void execute() override;
399 
400 protected:
401  Common::String getRecordTypeName() const override { return "StopPlayerScrolling"; }
402 };
403 
404 // Nancy 11+ AR 31. Re-enables the player's ability to scroll/pan the viewport.
406 public:
407  void readData(Common::SeekableReadStream &stream) override;
408  void execute() override;
409 
410 protected:
411  Common::String getRecordTypeName() const override { return "StartPlayerScrolling"; }
412 };
413 
414 // Returns the player back to the main menu
415 class GotoMenu : public ActionRecord {
416 public:
417  void readData(Common::SeekableReadStream &stream) override;
418  void execute() override;
419 
420 protected:
421  Common::String getRecordTypeName() const override { return "GotoMenu"; }
422 };
423 
424 // Stops the game and boots the player back to the Menu screen, while also making sure
425 // they can't Continue. The devs took care to add Second Chance saves before every one
426 // of these, to make sure the player can return to a state just before the dangerous part.
427 class LoseGame : public ActionRecord {
428 public:
429  void readData(Common::SeekableReadStream &stream) override;
430  void execute() override;
431 
432 protected:
433  Common::String getRecordTypeName() const override { return "LoseGame"; }
434 };
435 
436 // Nancy16+. Hides the cursor and blocks mouse input for as long as the record exists.
437 class HideCursor : public ActionRecord {
438 public:
439  ~HideCursor() override;
440 
441  void readData(Common::SeekableReadStream &stream) override {}
442  void execute() override;
443 
444 protected:
445  Common::String getRecordTypeName() const override { return "HideCursor"; }
446 
447  bool _isHiding = false;
448 };
449 
450 // Nancy16 record that sends an action to a panel or control of the UI, the same way
451 // the UI's own controls do when they are clicked
452 class UIControl : public ActionRecord {
453 public:
454  void readData(Common::SeekableReadStream &stream) override;
455  void execute() override;
456 
457 protected:
458  Common::String getRecordTypeName() const override { return "UIControl"; }
459 
460  int32 _actionType = 0;
461  Common::String _target;
462  Common::String _textKey; // AUTOTEXT key
463  double _value = 0;
464 };
465 
466 // Nancy16 journal entry. The page names a panel of the journal, and its text is the
467 // title of the page.
469 public:
470  void readData(Common::SeekableReadStream &stream) override;
471  void execute() override;
472 
473 protected:
474  Common::String getRecordTypeName() const override { return "AddJournalEntry"; }
475 
476  Common::String _pageName;
477  Common::String _textKey; // AUTOTEXT key
478 };
479 
480 // Nancy16 task list entry, which can be checked off once its flag is set
482 public:
483  void readData(Common::SeekableReadStream &stream) override;
484  void execute() override;
485 
486 protected:
487  Common::String getRecordTypeName() const override { return "AddTasklistEntry"; }
488 
489  Common::String _textKey; // AUTOTEXT key
490  int16 _flag = kEvNoEvent;
491 };
492 
493 // Nancy16 fade of the viewport to a solid color and back, covering the next scene
494 // change. The fade itself is owned by the scene; the record only arms it, waiting
495 // for any previous fade to end first.
496 class Fader : public ActionRecord {
497 public:
498  void readData(Common::SeekableReadStream &stream) override;
499  void execute() override;
500 
501 protected:
502  Common::String getRecordTypeName() const override { return "Fader"; }
503 
504  uint32 _holdTime = 0; // ms
505  uint32 _color = 0; // RGB
506 };
507 
508 // Adds a scene to the "stack" (which is just a single value). Used in combination with PopScene.
509 class PushScene : public ActionRecord {
510 public:
511  void readData(Common::SeekableReadStream &stream) override;
512  void execute() override;
513 
514 protected:
515  Common::String getRecordTypeName() const override { return "PushScene"; }
516 };
517 
518 // Changes to the scene pushed onto the "stack". Scenes can be pushed via PushScene, or Conversation types.
519 class PopScene : public ActionRecord {
520 public:
521  void readData(Common::SeekableReadStream &stream) override;
522  void execute() override;
523 
524 protected:
525  Common::String getRecordTypeName() const override { return "PopScene"; }
526 };
527 
528 // Ends the game and boots the player to the Credits screen.
529 // TODO: The original engine also sets a config option called PlayerWonTheGame,
530 // which in turn is used to trigger whichever event flag marks that the player
531 // has beat the game at least once, which in turn allows easter eggs to be shown.
532 // We currently support none of this.
533 class WinGame : public ActionRecord {
534 public:
535  void readData(Common::SeekableReadStream &stream) override;
536  void execute() override;
537 
538 protected:
539  Common::String getRecordTypeName() const override { return "WinGame"; }
540 };
541 
542 // Checks how many hints the player is allowed to get. If they are still allowed hints,
543 // it selects an appropriate one and plays its sound/displays its caption in the Textbox.
544 // The hint system was _only_ used in nancy1, since it's pretty limited and overly punishing.
545 class HintSystem : public ActionRecord {
546 public:
547  void readData(Common::SeekableReadStream &stream) override;
548  void execute() override;
549 
550  byte _characterID; // 0x00
551  SoundDescription _genericSound; // 0x01
552 
553  const Hint *selectedHint;
554  int16 _hintID;
555 
556  void selectHint();
557 
558 protected:
559  Common::String getRecordTypeName() const override { return "HintSystem"; }
560 };
561 
562 // Added in Nancy12 (AR 132). Adjusts a UI overlay resource (from the UIRC boot
563 // chunk) at runtime -- e.g. paying coins from the purse (resource 0). Applying
564 // the change plays a sound, optionally shows a transient overlay (a sprite and/or
565 // the resource's numeric value) and can change scene on success.
567 public:
569 
570  void init() override;
571  void readData(Common::SeekableReadStream &stream) override;
572  void execute() override;
573  void handleInput(NancyInput &input) override;
574 
575  bool isViewportRelative() const override { return true; }
576 
577 protected:
578  Common::String getRecordTypeName() const override { return "ResourceUse"; }
579 
580  // Applies the resource change (respecting affordability), sets the event
581  // flag and starts the matching outcome sound.
582  void applyChange();
583 
584  // The protagonist whose resources this record changes
585  byte getCharacterIndex() const;
586 
587  enum ResourceUseMode : byte {
588  kSetValue = 0, // set the resource to _amount
589  kAddValue = 1, // add _amount, if the resource can cover it
590  kAddTableValue = 2, // same, with the amount taken from the table
591  kSetTableValue = 3 // set to the table value at _amount
592  };
593 
594  // Nancy15 pays from a named protagonist's resources; kPlayerCharacterActive
595  // (and every earlier game) means whoever is being played.
596  byte _characterIndex = kPlayerCharacterActive;
597 
598  int16 _resourceIndex = 0;
599  int16 _amount = 0; // an amount, or a table index in the table modes
600  byte _mode = kSetValue;
601  FlagDescription _flag; // event flag set when the change is applied
602 
603  Common::String _failSoundName; // played when the change can't be applied
604  Common::String _successSoundName; // played when it is applied
605 
606  // When this rect is non-degenerate the change is interactive: the player
607  // clicks it (e.g. a coin slot) to pay. A degenerate rect applies at once.
608  Common::Rect _paymentHotspot;
609  byte _useResourceCursor = 0; // 0 = normal cursor, else the resource's own hover cursor
610 
611  uint16 _sceneID = kNoScene; // scene entered on success (9999 = none)
612  uint16 _continueSceneSound = 0;
613 
614  bool _drawResourceOverlay = false; // blit the resource's UIRC sprite
615  Common::Point _overlayDest;
616  bool _drawResourceValue = false; // draw the resource's numeric value
617  Common::Point _valueDest;
618 
619  SoundDescription _sound;
620  bool _hasSound = false;
621  bool _interactive = false;
622  bool _paymentResolved = false;
623  bool _paymentApplied = false;
624 };
625 
626 // Added in Nancy15 (AR 134). Hands control to one of the game's protagonists
627 // (Nancy, Frank or Joe), which swaps in that character's own copy of the popup
628 // UI, and optionally replaces the current scene's background with one showing
629 // the location from the incoming character's point of view.
630 class PlayChar : public ActionRecord {
631 public:
632  void readData(Common::SeekableReadStream &stream) override;
633  void execute() override;
634 
635 protected:
636  Common::String getRecordTypeName() const override { return "PlayChar"; }
637 
638  byte _characterIndex = 0; // index into the PCUI character list
639  Common::Path _videoFile; // replacement scene background, empty to keep the current one
640 };
641 
642 // Nancy17. Covers a part of the viewport with a color that changes into another
643 // one over time, e.g. from transparent to black. It stays at the last color for
644 // as long as the scene does.
646 public:
648 
649  void readData(Common::SeekableReadStream &stream) override;
650  void execute() override;
651 
652  bool isViewportRelative() const override { return true; }
653 
654 protected:
655  Common::String getRecordTypeName() const override { return "FadeOverlay"; }
656 
657  float _seconds = 0;
658  uint32 _fromColor = 0; // ARGB
659  uint32 _toColor = 0; // ARGB
660  Common::Rect _bounds;
661  FlagDescription _doneFlag;
662 
663  uint32 _startTime = 0;
664  bool _hasEnded = false;
665 };
666 
667 // Nancy17. Sets one of several flags, each of which has a percent chance to be the one
668 class SetRandomFlag : public ActionRecord {
669 public:
670  void readData(Common::SeekableReadStream &stream) override;
671  void execute() override;
672 
673 protected:
674  Common::String getRecordTypeName() const override { return "SetRandomFlag"; }
675 
676  struct Choice {
677  FlagDescription flag;
678  int32 percent = 0;
679  };
680 
681  Common::Array<Choice> _choices;
682 };
683 
684 // Nancy17. A collection is a named list of numbers (or of names, from Nancy18 on),
685 // which keeps the most recent ones once it is full. Scenes use them for combinations, e.g. to add every
686 // button the player presses and check the last few against the solution.
688 public:
689  void readData(Common::SeekableReadStream &stream) override;
690  void execute() override;
691 
692 protected:
693  enum Operation { kCreate = 0, kDelete = 1 };
694 
695  Common::String getRecordTypeName() const override { return "CollectionControl"; }
696 
697  byte _operation = kCreate;
698  Common::String _name;
699  bool _replaceExisting = false;
700  uint32 _maxSize = 0;
701 };
702 
703 // Nancy17. Adds numbers to a collection
704 class CollectionEdit : public ActionRecord {
705 public:
706  void readData(Common::SeekableReadStream &stream) override;
707  void execute() override;
708 
709 protected:
710  Common::String getRecordTypeName() const override { return "CollectionEdit"; }
711 
712  Common::String _name;
713  CollectionData::Values _values;
714 };
715 
716 // Nancy17. Compares a collection against a list of numbers or a size, and sets
717 // one of its flags by the result
719 public:
720  void readData(Common::SeekableReadStream &stream) override;
721  void execute() override;
722 
723 protected:
724  enum CheckType {
725  kContainsAll = 0, // every listed number is in the collection, in any order
726  kIsEqual = 1,
727  kSize = 2,
728  kFollowsPattern = 3 // the collection goes through the list, over and over
729  };
730 
731  Common::String getRecordTypeName() const override { return "CollectionCheck"; }
732 
733  bool check(const CollectionData::Values &collection) const;
734 
735  byte _checkType = kContainsAll;
736  Common::String _name;
737 
738  // Match and mismatch; the size check has one for a bigger, an equal and a
739  // smaller collection
740  FlagDescription _flags[3];
741  int32 _size = 0;
742  CollectionData::Values _values;
743 };
744 
745 // Nancy17. Adds a contact to the cell phone of the character being played
746 class AddPhoneEntry : public ActionRecord {
747 public:
748  void readData(Common::SeekableReadStream &stream) override;
749  void execute() override;
750 
751 protected:
752  Common::String getRecordTypeName() const override { return "AddPhoneEntry"; }
753 
754  PhoneBookData::Entry _entry;
755 };
756 
757 // Nancy17. A hotspot that sets a different event flag for every item it can get
758 // clicked with, one for any other item, and one for an empty hand
759 class HeldItemFlags : public ActionRecord {
760 public:
761  void readData(Common::SeekableReadStream &stream) override;
762  void execute() override;
763 
764  CursorManager::CursorType getHoverCursor() const override { return _hoverCursor; }
765  bool canHaveHotspot() const override { return true; }
766 
767 protected:
768  Common::String getRecordTypeName() const override { return "HeldItemFlags"; }
769 
770  struct ItemFlag {
771  int16 itemID = -1;
772  FlagDescription flag;
773  };
774 
775  CursorManager::CursorType _hoverCursor = CursorManager::kHotspot;
776  FlagDescription _noItemFlag;
777  Common::Array<ItemFlag> _itemFlags;
778  FlagDescription _otherItemFlag;
780 };
781 
782 // Nancy17. Rain over a part of the viewport: a number of drops, which get placed
783 // anew a few times a second. The further away a drop is, the shorter and the
784 // fainter it gets drawn.
785 class Rain : public RenderActionRecord {
786 public:
787  Rain() : RenderActionRecord(7) {}
788 
789  void readData(Common::SeekableReadStream &stream) override;
790  void execute() override;
791 
792  bool isViewportRelative() const override { return true; }
793 
794 protected:
795  Common::String getRecordTypeName() const override { return "Rain"; }
796 
797  void drawDrops();
798  void drawDrop(const Common::Rect &src, const Common::Point &pos, int height, byte alpha);
799 
800  Common::Path _imageName;
801  Common::Array<Common::Rect> _dropSrcs;
802  Common::Array<HotspotDescription> _areas; // where it rains, for every frame of the scene
803  float _minDistance = 0;
804  float _maxDistance = 1;
805  int32 _numDrops = 0;
806  uint32 _interval = 0;
807 
809  int _areaIndex = -1;
810  uint32 _nextDrawTime = 0;
811 };
812 
813 // Nancy18. A hotspot that turns the player around to face the opposite way
814 class UTurn : public ActionRecord {
815 public:
816  void readData(Common::SeekableReadStream &stream) override;
817  void execute() override;
818 
819  CursorManager::CursorType getHoverCursor() const override { return _hoverCursor; }
820  bool canHaveHotspot() const override { return true; }
821 
822 protected:
823  Common::String getRecordTypeName() const override { return "UTurn"; }
824 
825  bool isActiveOnFrame(uint16 frame) const;
826 
827  Common::Rect _hotspotRect;
828  CursorManager::CursorType _hoverCursor = CursorManager::kHotspot;
829  bool _excludesFrames = false; // the hotspot is on every frame but the listed ones
830  Common::Array<int16> _frames;
831 };
832 
833 // Nancy18. A chase over a map: the places are linked to each other, and the
834 // record moves the one being chased to a place next to theirs, picked at random,
835 // that the player isn't at. Both places are kept in the value table, and the
836 // kind of link that got taken sets one of three event flags.
837 class GraphChase : public ActionRecord {
838 public:
839  void readData(Common::SeekableReadStream &stream) override;
840  void execute() override;
841 
842 protected:
843  static const uint kNumLinkTypes = 3;
844 
845  struct Link {
846  int32 nodeID = 0; // counted from 1, as are the places in the value table
847  byte type = 0;
848  };
849 
850  typedef Common::Array<Link> Node;
851 
852  Common::String getRecordTypeName() const override { return "GraphChase"; }
853 
854  bool canMoveTo(const Link &link, int16 chaserNode) const;
855 
856  int16 _chaserTableIndex = 0;
857  int16 _chasedTableIndex = 0;
858  bool _avoidsAdjacentNodes = false; // keeps a place away from the player's, while it can
859  int16 _linkTypeFlags[kNumLinkTypes] = { -1, -1, -1 };
860  Common::Array<Node> _nodes;
861 };
862 
863 // Nancy18. Throws away what a puzzle has kept under a name
864 class ClearSavedData : public ActionRecord {
865 public:
866  void readData(Common::SeekableReadStream &stream) override;
867  void execute() override;
868 
869 protected:
870  Common::String getRecordTypeName() const override { return "ClearSavedData"; }
871 
872  Common::String _name;
873 };
874 
875 // Nancy18. Saves the game under a name, replacing the save that has it. The
876 // scenes make their own second chance saves with it.
877 class SaveNamedGame : public ActionRecord {
878 public:
879  void readData(Common::SeekableReadStream &stream) override;
880  void execute() override;
881 
882 protected:
883  Common::String getRecordTypeName() const override { return "SaveNamedGame"; }
884 
885  Common::String _name;
886 };
887 
888 // Nancy18. Loads the game that was saved under a name
889 class LoadNamedGame : public ActionRecord {
890 public:
891  void readData(Common::SeekableReadStream &stream) override;
892  void execute() override;
893 
894 protected:
895  Common::String getRecordTypeName() const override { return "LoadNamedGame"; }
896 
897  Common::String _name;
898 };
899 
900 } // End of namespace Action
901 } // End of namespace Nancy
902 
903 #endif // NANCY_ACTION_MISCRECORDS_H
Definition: managed_surface.h:51
Definition: miscrecords.h:275
Definition: miscrecords.h:645
Definition: miscrecords.h:63
Definition: miscrecords.h:151
Definition: miscrecords.h:687
Definition: str.h:59
Definition: puzzledata.h:657
Definition: miscrecords.h:759
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
Definition: miscrecords.h:427
Definition: miscrecords.h:481
T left
Definition: rect.h:170
Definition: commontypes.h:186
Definition: miscrecords.h:668
Definition: array.h:52
Definition: miscrecords.h:770
Definition: miscrecords.h:395
Definition: enginedata.h:645
Definition: commontypes.h:368
Definition: miscrecords.h:509
Definition: miscrecords.h:533
Definition: miscrecords.h:496
Definition: miscrecords.h:877
Definition: miscrecords.h:437
Definition: miscrecords.h:304
Definition: rect.h:536
Definition: path.h:52
Definition: actionrecord.h:182
Definition: miscrecords.h:96
Definition: stream.h:745
Definition: input.h:41
Definition: miscrecords.h:837
Definition: miscrecords.h:566
Definition: miscrecords.h:77
Definition: miscrecords.h:785
Definition: miscrecords.h:122
Definition: actionrecord.h:169
Definition: miscrecords.h:630
Definition: miscrecords.h:347
Definition: miscrecords.h:36
Definition: miscrecords.h:415
Definition: miscrecords.h:405
Definition: miscrecords.h:294
T right
Definition: rect.h:171
Definition: actionrecord.h:107
Definition: miscrecords.h:718
Definition: miscrecords.h:468
Definition: miscrecords.h:206
Definition: rect.h:144
Definition: miscrecords.h:173
Definition: miscrecords.h:519
Definition: miscrecords.h:133
Definition: miscrecords.h:263
Definition: miscrecords.h:363
Definition: miscrecords.h:704
Definition: commontypes.h:306
Definition: miscrecords.h:452
Definition: miscrecords.h:814
Definition: miscrecords.h:746
Definition: miscrecords.h:889
Definition: miscrecords.h:864
Definition: commontypes.h:201
Definition: miscrecords.h:317
Definition: miscrecords.h:51
Definition: miscrecords.h:249
Definition: miscrecords.h:220
Definition: puzzledata.h:726
Definition: miscrecords.h:676
Definition: miscrecords.h:545
Definition: actionmanager.h:32