ScummVM API documentation
cardgamepuzzle.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_CARDGAMEPUZZLE_H
23 #define NANCY_ACTION_CARDGAMEPUZZLE_H
24 
25 #include "engines/nancy/action/actionrecord.h"
26 
27 namespace Nancy {
28 namespace Action {
29 
30 // Two-player card game versus an AI opponent, new in Nancy 11 (Curse of Blackmoor Manor, AR 246).
31 // Cards are dealt into a shared grid; each player stacks up to three cards per column, and a full
32 // column scores a "set". Implementation is staged: this currently parses the data chunk and sets up
33 // the board; the deal/match/AI gameplay is being filled in incrementally.
35 public:
37  virtual ~CardGamePuzzle() {}
38 
39  void init() override;
40  void updateGraphics() 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  // Up to 13 columns / 4 rows are addressable in the data (per-row stride is 13 card rects).
50  static const int kMaxCols = 13;
51  static const int kMaxRows = 4;
52 
53  // Per-side board: a grid of dealt cards, per-column counts (capped at 3), per-column "complete"
54  // flags (a full column of 3 scores a set) and the running score.
55  struct PlayerBoard {
56  int grid[kMaxRows][kMaxCols];
57  int colCount[kMaxCols];
58  int colComplete[kMaxCols];
59  int score;
60  };
61 
62  Common::String getRecordTypeName() const override { return "CardGamePuzzle"; }
63 
64  bool dealOne(int player); // draw a card from the deck to a side; false if the deck is empty
65  void drawBoard();
66  // Current side takes every opponent card in the given column; returns true if a card moved.
67  bool playColumn(int col);
68  int aiPickColumn(); // the AI's column choice, or -1 if it has no productive move
69  void finishMove(); // draw a card, pass the turn, run the AI, detect the end of the game
70  void endGame();
71  // Compare side 1's grid against a pre-move snapshot and start sliding the changed cards.
72  void startMoveAnimation(const bool beforeGrid[kMaxRows][kMaxCols]);
73  void playVoice(const Common::String &name); // play a voiced line / SFX on the card-game channel
74 
75  Common::Path _imageName;
76 
77  // Header flags / dimensions
78  byte _unknown21 = 0;
79  byte _switchTurnRule = 0; // data+0x22: how the turn passes after a play
80  byte _startPlayer = 0; // data+0x23: which side plays first (also the human side)
81  byte _dealMode = 0; // data+0x24: deal/scoring variant (0, 2 or 0xff)
82  uint16 _numCols = 0; // data+0x25
83  uint16 _numRows = 0; // data+0x27
84  uint16 _dealRounds = 0; // data+0x29
85 
86  // Source/destination rects (all addressed [row * kMaxCols + col] or [side * kMaxCols + col])
87  Common::Rect _turnHighlightSrc[2]; // data+0x2b
88  Common::Rect _turnHighlightDest[2]; // data+0x4b
89  Common::Array<Common::Rect> _faceUpSrc; // data+0x6b, 4 rows
90  Common::Rect _suitScoreSrc; // data+0x47b
91  Common::Array<Common::Rect> _scoreDest; // data+0x48b, 2 sides
92  Common::Rect _cardDisplayDest[2]; // data+0x633
93  Common::Array<Common::Rect> _columnButtons; // data+0x653, one per column
94  Common::Array<Common::Rect> _faceDownSrc; // data+0x723, 3 rows
95  Common::Rect _exitHotspot; // data+0x1336
96 
97  // Animation timing (data+0x62b)
98  uint16 _moveAnimSteps = 0;
99  uint16 _moveAnimDelta = 0;
100  uint32 _moveAnimDelay = 0;
101 
102  // Outcome scenes (data+0x1304 / 0x1320). The win block has two scene ids that share one set of
103  // transition params (frame/scroll/sound), held in _winScene; the id is chosen by the result.
104  uint16 _winSceneStartPlayer = 0; // data+0x1304
105  uint16 _winSceneStartEnemy = 0; // data+0x1306
106  SceneChangeDescription _winScene;
107  int16 _winFlagPlayer = -1; // data+0x131c
108  int16 _winFlagEnemy = -1; // data+0x131e
109  uint16 _exitScene = 0; // data+0x1320
110  SceneChangeDescription _exitSceneChange;
111  bool _gaveUp = false; // left via the exit hotspot rather than playing out
112 
113  // Voiced lines / SFX (all on the card-game channel). Read selectively from the 0xba3..0x1304 block.
114  Common::String _moveVoiceName; // data+0xbc4 (card-move SFX)
115  Common::String _dealVoiceName; // data+0xbe5 (card-deal SFX)
116  Common::String _matchVoice[2][kMaxCols]; // data+0xc2b (AI) / 0xf68 (player), keyed by column
117  Common::String _enemyScoredVoiceName; // data+0xee0 (a column completed for the AI)
118  Common::String _playerScoredVoiceName; // data+0x121d (a column completed for the player)
119  Common::String _endVoiceName[2]; // data+0xf22 (AI wins) / 0x125f (player wins)
120  SoundDescription _voiceSound;
121 
122  // At game over, the winner's line plays before the result scene transition.
123  bool _awaitingEnd = false;
124  uint32 _endWaitUntil = 0;
125 
126  // Runtime board state
128  PlayerBoard _board[2];
129  byte _availMap[kMaxRows][kMaxCols]; // shared deck: 1 = card still on the table
130  int _deckRemaining = 0;
131  int _currentTurn = 0; // which side is to play (the player's side draws the grid)
132  int _lastAiColumn = -1; // the AI avoids immediately repeating its previous column
133  bool _gameOver = false;
134 
135  // Slide animation for cards that changed hands on the last move (visual only; the board state
136  // is already up to date). Appeared cards slide into place, departed cards slide away.
137  static const int kSlidePerStep = 12;
138  bool _appearing[kMaxRows][kMaxCols] = {};
139  bool _leaving[kMaxRows][kMaxCols] = {};
140  int _animStep = 0;
141  uint32 _animNextStep = 0;
142  bool _animating = false;
143 };
144 
145 } // End of namespace Action
146 } // End of namespace Nancy
147 
148 #endif // NANCY_ACTION_CARDGAMEPUZZLE_H
Definition: managed_surface.h:51
Definition: str.h:59
Definition: cardgamepuzzle.h:34
Definition: commontypes.h:152
Definition: rect.h:524
Definition: path.h:52
Definition: stream.h:745
Definition: input.h:41
Definition: cardgamepuzzle.h:55
Definition: actionrecord.h:152
Definition: commontypes.h:255
Definition: actionmanager.h:32