ScummVM API documentation
stalkingzazu.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 MEDIASTATION_MINIGAMES_STALKINGZAZU_H
23 #define MEDIASTATION_MINIGAMES_STALKINGZAZU_H
24 
25 #include "mediastation/statemachine.h"
26 #include "mediastation/actors/stage.h"
27 
28 namespace MediaStation {
29 
30 class StalkingZazuActor;
31 namespace StalkingZazuMinigame {
32 
33 class Direction {
34 public:
35  static const uint TOTAL_DIRECTIONS = 8;
36  enum Value {
37  kNone = 0,
38  kEast = 1,
39  kNorthEast = 2,
40  kNorth = 3,
41  kNorthWest = 4,
42  kWest = 5,
43  kSouthWest = 6,
44  kSouth = 7,
45  kSouthEast = 8
46  };
47 
48  Direction() {}
49  Direction(Value value) : _value(value) {}
50  Direction(uint directionToken);
51 
52  // Conversion operator so a Direction stands in for its enum value directly.
53  operator Value() const { return _value; }
54 
55  Direction counterClockwise() const { return rotate(1); }
56  Direction opposite() const { return rotate(TOTAL_DIRECTIONS / 2); }
57 
58 private:
59  // Rotates counter-clockwise by the given number of eighth-turns,
60  Direction rotate(uint steps) const;
61  Value _value = kNone;
62 };
63 
64 class CellCoord : public Common::Point {
65 public:
66  CellCoord() : Common::Point() {}
67  CellCoord(int16 column, int16 row) : Common::Point(column, row) {}
68 
69  CellCoord getAdjacentCell(const Direction &direction) const;
70 };
71 
72 class StalkClips : public Common::Array<uint> {
73 public:
74  static const uint SIZE = 18;
75  uint indexOf(Direction direction, bool isCrouched);
76 };
77 
78 // This is basically a uint16 matrix with a lot of additional methods attached.
79 // The ScummVM Matrix class was not used because it is float-backed and so not really
80 // a great choice for an obstacle field. This is really a translation layer a logical
81 // "stalking field" space that defines whether a given region of graphical space contains
82 // an obstacle or not.
84 public:
85  StalkingField() = default;
86  StalkingField(int rowCount, int columnCount, const Common::Point &graphicalSize);
87 
88  uint16 &at(int row, int column);
89  const uint16 &at(int row, int column) const;
90  uint16 &at(const CellCoord &coord);
91  const uint16 &at(const CellCoord &coord) const;
92  bool isEmpty(const CellCoord &coord) { return at(coord) == 0; }
93 
94  bool isInBounds(int row, int column) const;
95  bool isInBounds(const CellCoord &coord) const;
96 
97  int rowCount() const { return _rows; }
98  int columnCount() const { return _columns; }
99 
100  void clear();
101  Common::Point bottomCenterPositionInFieldCoordinates();
102  CellCoord cellAtPoint(const Common::Point &point);
103  void placeObstacles(const Common::Array<uint> &obstacleActorIds);
104  Common::Point cellSize();
105  Common::Point centerOfCell(const CellCoord &coord);
106 
107 private:
108  bool addObstacleToRow(uint16 obstacleActorId, uint16 row);
109  Common::Array<CellCoord> calcAvailableCellsOnRow(uint row);
110  Common::Array<uint16> calcPartitionBoundaries(uint end, uint brk); // calcBreakPoints
111 
112  bool obstacleCanBePlaced(const CellCoord &coord); // cellIsValidObstacle
113  bool obstacleCanBePlaced(CellCoord cellCoord, Direction direction, Common::Array<CellCoord> &cellCoordVector);
114 
115  int _columns = 0;
116  int _rows = 0;
117  Common::Array<uint16> _values;
118  Common::Point _graphicalSize;
119 };
120 
121 enum GameState {
122  kStalkingZazuStateStart = 0,
123  kStalkingZazuStateReset = 1,
124  kStalkingZazuStateCrouched = 2,
125  kStalkingZazuStateCanMove = 3,
126  kStalkingZazuStateProcessMove = 4,
127  kStalkingZazuStateDefeat = 5,
128  kStalkingZazuStateSuccess = 6
129 };
130 
131 enum GameStateEvent {
132  kStalkingZazuResetStateEvent = 0,
133  kStalkingZazuCrouchStateEvent = 1,
134  kStalkingZazuUncrouchStateEvent = 2,
135  kStalkingZazuMoveStateEvent = 3,
136  kStalkingZazuLoseStateEvent = 4,
137  kStalkingZazuWinStateEvent = 5
138 };
139 
140 struct GameStateMachineEvent : public StateMachineEvent<GameState> {
141 public:
142  uint obstaclesToShow = 0;
143 };
144 
145 class GameStateMachine : public StateMachine<GameState, GameStateEvent> {
146 public:
147  GameStateMachine(StalkingZazuActor *actor) : _actor(actor) { _currentState = kStalkingZazuStateStart; }
148 
149 protected:
150  virtual void executeNextState(GameStateEvent eventType) override;
151  StalkingZazuActor *_actor = nullptr;
152 };
153 
154 enum TimerState {
155  kStalkingZazuExpiredTimerState = 0,
156  kStalkingZazuQueuedTimerState = 1,
157  kStalkingZazuExpiredInactiveTimerState = 2,
158  kStalkingZazuExpiredActiveTimerState = 3,
159  kStalkingZazuQueuedInactiveTimerState = 4
160 };
161 
162 enum TimerEvent {
163  kStalkingZazuActivateTimerEvent = 0,
164  kStalkingZazuInactivateTimerEvent = 1,
165  kStalkingZazuExpireTimerEvent = 2,
166  kStalkingZazuQueueTimerEvent = 3
167 };
168 
169 class TimerStateMachine : public StateMachine<TimerState, TimerEvent> {
170 public:
171  TimerStateMachine(StalkingZazuActor *actor) : _actor(actor) { _currentState = kStalkingZazuExpiredTimerState; }
172 
173 protected:
174  virtual void executeNextState(TimerEvent eventType) override;
175  StalkingZazuActor *_actor = nullptr;
176 };
177 
178 }; // End of namespace StalkingZazuMinigame
179 
183 
184 public:
185  StalkingZazuActor() : SpatialEntity(kActorTypeStalkingZazu), _gameMachine(this), _timerMachine(this) {};
186 
187  virtual Common::String debugString() const override;
188  virtual void readParameter(Chunk &chunk, ActorHeaderSectionType paramType) override;
189  virtual ScriptValue callMethod(BuiltInMethod methodId, Common::Array<ScriptValue> &args) override;
190  virtual bool isVisible() const override;
191  virtual void draw(DisplayContext &displayContext) override;
192  virtual void loadIsComplete() override;
193 
194  virtual void onEvent(const ActorEvent &event) override;
195  virtual void timerEvent(const MediaStation::TimerEvent &event) override;
196 
197 private:
199  void generateStalkingEvent(StalkingZazuMinigame::GameStateEvent event);
201  void generateTimerEvent(StalkingZazuMinigame::TimerEvent event);
202 
203  void calcWhichObstaclesToShow(uint16 obstaclesToShow);
204  void calcObstaclePlacements();
205  void placeObstaclesOnStage();
206  void positionSimbaStartOnStage();
207 
208  bool simbaIsInSuccessPosition();
209  void setSimbaCrouchClip(bool isSimbaCrouching);
210  void setSimbaClipFromDirection(StalkingZazuMinigame::Direction direction);
211  bool zazuSeesSimba();
212  bool simbaIsBehindRock();
213 
214  void placeAndShowActor(uint obstacleActorId, const Common::Point &pos);
215  void setClipOfMovie(uint spriteActorId, uint clipId);
216  int zCoordOfPoint(const Common::Point &point);
217 
218  void processMove(Common::Point dest);
219  bool getMoveInformation(const Common::Point &targetPos, Common::Point &nextPos, StalkingZazuMinigame::Direction &direction);
220  StalkingZazuMinigame::Direction directionOfVector(const Common::Point &dest);
221  Common::Point desiredPositionFromVectorInFieldCoordinates(const Common::Point &point);
222  bool isClearAtPoint(const Common::Point &point);
223 
224  StalkingZazuMinigame::Direction directionZazuWillLook();
225  void setZazuLook(bool isLooking);
226  void setActive(bool isActive);
227 
228  void stalkingState_1_reset();
229  void stalkingState_2_crouched();
230  void stalkingState_3_canMove();
231  void stalkingState_4_processMove();
232  void stalkingState_5_defeat();
233  void stalkingState_6_success();
234  void timerState_0_expired();
235  void timerState_1_queued();
236  // The original has a few other timer states that are no-ops,
237  // so they are excluded here.
238 
239  virtual bool interactsWithMouse() const override { return _isActive; }
240  virtual uint16 findActorToAcceptMouseEvents(
241  const Common::Point &point,
242  uint16 eventMask,
243  MouseActorState &state,
244  bool clipMouseEvents) override;
245  bool mousePositionIsInteresting(const Common::Point &pos);
246  void mouseDownEvent(const MouseEvent &event) override;
247  void mouseUpEvent(const MouseEvent &event) override;
248  void mouseEnteredEvent(const MouseEvent &event) override;
249  void mouseExitedEvent(const MouseEvent &event) override;
250  bool _mouseIsDown = false;
251  bool _mouseIsInside = false;
252 
255  Common::Point _targetPosInFieldCoordinates;
256  Common::Point _simbaPosInFieldCoordinates;
257  Common::Rect _simbaMovementBoundsInFieldCoordinates; // Offset 0x104 in original (FP68K calls obscure xrefs).
258  StalkingZazuMinigame::Direction _currentDirection;
259 
260  uint _cursorResourceId = 0;
261  uint _simbaActorId = 0;
262  int _obstaclesToShow = 0;
263  Common::Array<uint> _obstacleActorIds;
264 
265  bool _isActive = false;
266  bool _simbaIsCrouching = false;
267  bool _crouchClipIsSet = false;
268  bool _acceptingMouseEvents = true;
269  bool _zazuIsLooking = false;
270 
271  double _timerDurationInSeconds = 0.10;
272  uint _scalingFactor = 10; // Offset 0xD8 in original (FP68K calls obscure xrefs).
273  uint _successRadius = 20; // Offset 0xFE in original (FP68K calls obscure xrefs).
274 
275  // These are read in the original, but they don't seem to actually be populated
276  // and sound effects don't seem to be enabled. However, they are included in case
277  // they are used in some localization.
278  bool _soundEffectsEnabled = false;
279  uint _soundEffectId1 = 0;
280  uint _soundEffectId2 = 0;
281  void setAudio(bool isEnabled);
282  void startSound(uint soundActorId);
283  void stopSound(uint soundActorId);
284 };
285 
286 } // End namespace MediaStation
287 
288 #endif
Definition: str.h:59
Definition: actor.h:174
Definition: actor.h:278
Definition: actor.h:34
Definition: array.h:52
Definition: datafile.h:99
Definition: rect.h:536
Definition: graphics.h:122
Definition: events.h:103
Definition: events.h:94
Definition: lobject.h:59
Definition: stalkingzazu.h:180
Definition: rect.h:144
Definition: events.h:125
Definition: statemachine.h:31
Definition: scriptvalue.h:35
Definition: statemachine.h:39