ScummVM API documentation
hotspots.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 LURE_HOTSPOTS_H
23 #define LURE_HOTSPOTS_H
24 
25 #include "lure/luredefs.h"
26 #include "lure/screen.h"
27 #include "lure/disk.h"
28 #include "lure/res_struct.h"
29 
30 namespace Lure {
31 
32 #define MAX_NUM_IMPINGING 10
33 
34 class Hotspot;
35 class HotspotTickHandlers;
36 
37 class Support {
38 private:
39  static bool changeRoomCheckBumped(Hotspot &h);
40 public:
41  static int findIntersectingCharacters(Hotspot &h, uint16 *charList, int16 xp = -1, int16 yp = -1, int roomNumber = -1);
42  static bool checkForIntersectingCharacter(Hotspot &h, int16 xp = -1, int16 yp = -1, int roomNumber = -1);
43  static bool checkRoomChange(Hotspot &h);
44  static void characterChangeRoom(Hotspot &h, uint16 roomNumber,
45  int16 newX, int16 newY, Direction dir);
46  static bool charactersIntersecting(HotspotData *hotspot1, HotspotData *hotspot2);
47  static bool isCharacterInList(uint16 *lst, int numEntries, uint16 charId);
48 };
49 
50 typedef void (HotspotTickHandlers::*HandlerMethodPtr)(Hotspot &h);
51 
53 private:
54  // Special variable used across multiple calls to followerAnimHandler
55  int countdownCtr;
56 
57  // Special variables used across multiple calls to talkAnimHandler
58  TalkEntryData *_talkResponse;
59  uint16 talkDestCharacter;
60 
61  // Special variable used across multiple calls to barmanAnimHandler
62  bool ewanXOffset;
63 
64  // Support methods
65  void npcRoomChange(Hotspot &h);
66  void talkEndConversation();
67 
68  // Handler methods
69  void defaultHandler(Hotspot &h);
70  void voiceBubbleAnimHandler(Hotspot &h);
71  void standardAnimHandler(Hotspot &h);
72  void standardAnimHandler2(Hotspot &h);
73  void standardCharacterAnimHandler(Hotspot &h);
74  void puzzledAnimHandler(Hotspot &h);
75  void roomExitAnimHandler(Hotspot &h);
76  void playerAnimHandler(Hotspot &h);
77  void followerAnimHandler(Hotspot &h);
78  void jailorAnimHandler(Hotspot &h);
79  void sonicRatAnimHandler(Hotspot &h);
80  void droppingTorchAnimHandler(Hotspot &h);
81  void playerSewerExitAnimHandler(Hotspot &h);
82  void fireAnimHandler(Hotspot &h);
83  void sparkleAnimHandler(Hotspot &h);
84  void teaAnimHandler(Hotspot &h);
85  void goewinCaptiveAnimHandler(Hotspot &h);
86  void prisonerAnimHandler(Hotspot &h);
87  void catrionaAnimHandler(Hotspot &h);
88  void morkusAnimHandler(Hotspot &h);
89  void talkAnimHandler(Hotspot &h);
90  void grubAnimHandler(Hotspot &h);
91  void barmanAnimHandler(Hotspot &h);
92  void skorlAnimHandler(Hotspot &h);
93  void gargoyleAnimHandler(Hotspot &h);
94  void goewinShopAnimHandler(Hotspot &h);
95  void skullAnimHandler(Hotspot &h);
96  void dragonFireAnimHandler(Hotspot &h);
97  void castleSkorlAnimHandler(Hotspot &h);
98  void rackSerfAnimHandler(Hotspot &h);
99  void fighterAnimHandler(Hotspot &h);
100  void playerFightAnimHandler(Hotspot &h);
101 public:
103 
104  HandlerMethodPtr getHandler(uint16 procIndex);
105 };
106 
108 private:
109  Direction _direction;
110  int _numSteps;
111 public:
112  WalkingActionEntry(Direction dir, int steps): _direction(dir), _numSteps(steps) {}
113  Direction direction() const { return _direction; }
114  int &rawSteps() { return _numSteps; }
115  int numSteps() const;
116 };
117 
118 enum PathFinderResult {PF_UNFINISHED, PF_OK, PF_DEST_OCCUPIED, PF_PART_PATH, PF_NO_WALK};
119 
120 class PathFinder {
121 private:
122  Hotspot *_hotspot;
123  bool _inUse;
125  WalkingActionList _list;
126  RoomPathsDecompressedData _layer;
127  int _stepCtr;
128  bool _inProgress;
129  int _countdownCtr;
130  int16 _destX, _destY;
131  int16 _xPos, _yPos;
132  int16 _xCurrent, _yCurrent;
133  int16 _xDestPos, _yDestPos;
134  int16 _xDestCurrent, _yDestCurrent;
135  bool _destOccupied;
136  bool _cellPopulated;
137  uint16 *_pSrc, *_pDest;
138  int _xChangeInc, _xChangeStart;
139  int _yChangeInc, _yChangeStart;
140  int _xCtr, _yCtr;
141 
142  void initVars();
143  void processCell(uint16 *p);
144  void scanLine(int numScans, int changeAmount, uint16 *&pEnd, int &v);
145 
146  void add(Direction dir, int steps) {
148  }
149  void addBack(Direction dir, int steps) {
151  }
152 public:
153  PathFinder(Hotspot *h);
154  void clear();
155  void reset(RoomPathsData &src);
156  PathFinderResult process();
157  Common::String getDebugInfo() const;
158 
159  void pop() { _list.erase(_list.begin()); }
160  WalkingActionEntry &top() const { return **_list.begin(); }
161  bool isEmpty() const { return _list.empty(); }
162  int &stepCtr() { return _stepCtr; }
163 
164  void saveToStream(Common::WriteStream *stream) const;
165  void loadFromStream(Common::ReadStream *stream);
166 };
167 
168 enum HotspotPrecheckResult {PC_EXECUTE, PC_NOT_IN_ROOM, PC_FAILED, PC_WAIT, PC_EXCESS};
169 
170 enum BarPlaceResult {BP_KEEP_TRYING, BP_GOT_THERE, BP_FAIL};
171 
173  uint8 counter;
174  Common::Point position;
175 };
176 
177 
178 #define MAX_NUM_FRAMES 16
179 
180 class Hotspot {
181 private:
182  HotspotTickHandlers _tickHandlers;
183  HotspotData *_data;
184  uint16 _animId;
185  HotspotAnimData *_anim;
186  HandlerMethodPtr _tickHandler;
187  Surface *_frames;
188  uint16 _hotspotId;
189  uint16 _originalId;
190  uint16 _roomNumber;
191  int16 _startX, _startY;
192  uint16 _height, _width;
193  uint16 _heightCopy, _widthCopy;
194  uint16 _yCorrection;
195  uint16 _charRectY;
196  int8 _talkX, _talkY;
197  uint16 _numFrames;
198  uint16 _frameNumber;
199  Direction _direction;
200  uint8 _layer;
201  uint16 _hotspotScriptOffset;
202  uint8 _colorOffset;
203  bool _persistent;
204  HotspotOverrideData *_override;
205  bool _skipFlag;
206  PathFinder _pathFinder;
207  uint16 _frameWidth;
208  bool _frameStartsUsed;
209  uint16 _frameStarts[MAX_NUM_FRAMES];
210  char _nameBuffer[MAX_HOTSPOT_NAME_SIZE];
211  DestStructure _tempDest;
212 
213  // Runtime fields
214  uint16 _frameCtr;
215  uint8 _voiceCtr;
216  int16 _destX, _destY;
217  uint16 _destHotspotId;
218  uint16 _blockedOffset;
219  uint8 _exitCtr;
220  bool _walkFlag;
221  uint16 _startRoomNumber;
222  uint16 _supportValue;
223 
224  // Support methods
225  uint16 getTalkId(HotspotData *charHotspot);
226  void startTalk(HotspotData *charHotspot, uint16 id);
227  void startTalkDialog();
228 
229  // Action support methods
230  HotspotPrecheckResult actionPrecheck(HotspotData *hotspot);
231  BarPlaceResult getBarPlace();
232  bool findClearBarPlace();
233  bool characterWalkingCheck(uint16 id);
234  void resetDirection();
235 
236  // Action set
237  void doGet(HotspotData *hotspot);
238  void doOperate(HotspotData *hotspot);
239  void doOpen(HotspotData *hotspot);
240  void doClose(HotspotData *hotspot);
241  void doLockUnlock(HotspotData *hotspot);
242  void doUse(HotspotData *hotspot);
243  void doGive(HotspotData *hotspot);
244  void doTalkTo(HotspotData *hotspot);
245  void doTell(HotspotData *hotspot);
246  void doLook(HotspotData *hotspot);
247  void doLookAt(HotspotData *hotspot);
248  void doLookThrough(HotspotData *hotspot);
249  void doAsk(HotspotData *hotspot);
250  void doDrink(HotspotData *hotspot);
251  void doStatus(HotspotData *hotspot);
252  void doGoto(HotspotData *hotspot);
253  void doReturn(HotspotData *hotspot);
254  void doBribe(HotspotData *hotspot);
255  void doExamine(HotspotData *hotspot);
256  void npcSetRoomAndBlockedOffset(HotspotData *hotspot);
257  void npcHeySir(HotspotData *hotspot);
258  void npcExecScript(HotspotData *hotspot);
259  void npcResetPausedList(HotspotData *hotspot);
260  void npcSetRandomDest(HotspotData *hotspot);
261  void npcWalkingCheck(HotspotData *hotspot);
262  void npcSetSupportOffset(HotspotData *hotspot);
263  void npcSupportOffsetConditional(HotspotData *hotspot);
264  void npcDispatchAction(HotspotData *hotspot);
265  void npcTalkNpcToNpc(HotspotData *hotspot);
266  void npcPause(HotspotData *hotspot);
267  void npcStartTalking(HotspotData *hotspot);
268  void npcJumpAddress(HotspotData *hotspot);
269 
270  // Auxillaries
271  void doLookAction(HotspotData *hotspot, Action action);
272 public:
273  Hotspot(HotspotData *res);
274  Hotspot(Hotspot *character, uint16 objType);
275  Hotspot();
276  ~Hotspot();
277 
278  void setAnimation(uint16 newAnimId);
279  void setAnimationIndex(int animIndex);
280  void setAnimation(HotspotAnimData *newRecord);
281  uint16 hotspotId() const { return _hotspotId; }
282  uint16 originalId() const { return _originalId; }
283  Surface &frames() const { return *_frames; }
284  HotspotAnimData &anim() const { return *_anim; }
285  HotspotData *resource() const { return _data; }
286  uint16 numFrames() const { return _numFrames; }
287  uint16 frameNumber() const { return _frameNumber; }
288  void setFrameNumber(uint16 frameNum) {
289  assert(frameNum < _numFrames);
290  _frameNumber = frameNum;
291  }
292  void incFrameNumber();
293  Direction direction() const { return _direction; }
294  uint16 frameWidth() const { return _width; }
295  int16 x() const { return _startX; }
296  int16 y() const { return _startY; }
297  int16 destX() const { return _destX; }
298  int16 destY() const { return _destY; }
299  int8 talkX() const { return _talkX; }
300  int8 talkY() const { return _talkY; }
301  uint16 destHotspotId() const { return _destHotspotId; }
302  uint16 blockedOffset() const { return _blockedOffset; }
303  uint8 exitCtr() const { return _exitCtr; }
304  bool walkFlag() const { return _walkFlag; }
305  uint16 startRoomNumber() const { return _startRoomNumber; }
306  uint16 width() const { return _width; }
307  uint16 height() const { return _height; }
308  uint16 widthCopy() const { return _widthCopy; }
309  uint16 heightCopy() const { return _heightCopy; }
310  uint16 yCorrection() const { return _yCorrection; }
311  uint16 charRectY() const { return _charRectY; }
312  uint16 roomNumber() const { return _roomNumber; }
313  uint16 talkScript() const {
314  assert(_data);
315  return _data->talkScriptOffset;
316  }
317  uint16 hotspotScript() const { return _hotspotScriptOffset; }
318  uint8 layer() const { return _layer; }
319  bool skipFlag() const { return _skipFlag; }
320  void setTickProc(uint16 newVal);
321  bool persistent() const { return _persistent; }
322  void setPersistent(bool value) { _persistent = value; }
323  uint8 colorOffset() const { return _colorOffset; }
324  void setColorOffset(uint8 value) { _colorOffset = value; }
325  void setRoomNumber(uint16 roomNum) {
326  _roomNumber = roomNum;
327  if (_data) _data->roomNumber = roomNum;
328  }
329  uint16 nameId() const;
330  const char *getName();
331  bool isActiveAnimation();
332  void setPosition(int16 newX, int16 newY);
333  void setDestPosition(int16 newX, int16 newY) { _destX = newX; _destY = newY; }
334  void setDestHotspot(uint16 id) { _destHotspotId = id; }
335  void setExitCtr(uint8 value) { _exitCtr = value; }
336  BlockedState blockedState() const {
337  assert(_data);
338  return _data->blockedState;
339  }
340  void setBlockedState(BlockedState newState) {
341  assert(_data);
342  _data->blockedState = newState;
343  }
344  bool blockedFlag() const {
345  assert(_data);
346  return _data->blockedFlag;
347  }
348  void setBlockedFlag(bool newValue) {
349  assert(_data);
350  _data->blockedFlag = newValue;
351  }
352  void setWalkFlag(bool value) { _walkFlag = value; }
353  void setStartRoomNumber(uint16 value) { _startRoomNumber = value; }
354  void setSize(uint16 newWidth, uint16 newHeight);
355  void setWidth(uint16 newWidth) {
356  _width = newWidth;
357  _frameWidth = newWidth;
358  }
359  void setHeight(uint16 newHeight) {
360  _height = newHeight;
361  }
362  void setHotspotScript(uint16 offset) {
363  assert(_data != NULL);
364  _hotspotScriptOffset = offset;
365  _data->hotspotScriptOffset = offset;
366  }
367  void setLayer(uint8 newLayer) {
368  assert(_data != NULL);
369  _layer = newLayer;
370  _data->layer = newLayer;
371  }
372  void setActions(uint32 newActions) {
373  assert(_data);
374  _data->actions = newActions;
375  }
376  void setCharRectY(uint16 value) { _charRectY = value; }
377  void setSkipFlag(bool value) { _skipFlag = value; }
378  CharacterMode characterMode() const {
379  assert(_data != NULL);
380  return _data->characterMode;
381  }
382  void setCharacterMode(CharacterMode value) {
383  assert(_data != NULL);
384  _data->characterMode = value;
385  }
386  uint16 delayCtr() const {
387  assert(_data);
388  return _data->delayCtr;
389  }
390  void setDelayCtr(uint16 value) {
391  assert(_data);
392  _data->delayCtr = value;
393  }
394  uint16 pauseCtr() const {
395  assert(_data);
396  return _data->pauseCtr;
397  }
398  void setPauseCtr(uint16 value) {
399  assert(_data);
400  _data->pauseCtr = value;
401  }
402  VariantBool coveredFlag() const {
403  assert(_data);
404  return _data->coveredFlag;
405  }
406  void setCoveredFlag(VariantBool value) {
407  assert(_data);
408  _data->coveredFlag = value;
409  }
410  uint16 useHotspotId() const {
411  assert(_data);
412  return _data->useHotspotId;
413  }
414  void setUseHotspotId(uint16 value) {
415  assert(_data);
416  _data->useHotspotId = value;
417  }
418  uint16 talkGate() const {
419  assert(_data);
420  return _data->talkGate;
421  }
422  void setTalkGate(uint16 value) {
423  assert(_data);
424  _data->talkGate = value;
425  }
426  uint16 supportValue() const { return _supportValue; }
427  void setSupportValue(uint16 value) { _supportValue = value; }
428 
429  void copyTo(Surface *dest);
430  bool executeScript();
431  void tick();
432  bool isRoomExit(uint16 id);
433 
434  // Walking
435  void walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot = 0);
436  void stopWalking();
437  void endAction();
438  void setDirection(Direction dir);
439  void faceHotspot(HotspotData *hotspot);
440  void faceHotspot(uint16 hotspotId);
441  void setRandomDest();
442  void setOccupied(bool occupiedFlag);
443  bool walkingStep();
444  void updateMovement();
445  void updateMovement2(CharacterMode value);
446  void resetPosition();
447  bool doorCloseCheck(uint16 doorId);
448 
449  void doAction();
450  void doAction(Action action, HotspotData *hotspot);
451  CurrentActionStack &currentActions() const {
452  assert(_data);
453  return _data->npcSchedule;
454  }
455  PathFinder &pathFinder() { return _pathFinder; }
456  DestStructure &tempDest() { return _tempDest; }
457  uint16 frameCtr() const { return _frameCtr; }
458  void setFrameCtr(uint16 value) { _frameCtr = value; }
459  void decrFrameCtr() { if (_frameCtr > 0) --_frameCtr; }
460  uint8 actionCtr() const {
461  assert(_data);
462  return _data->actionCtr;
463  }
464  void setActionCtr(uint8 v) {
465  assert(_data);
466  _data->actionCtr = v;
467  }
468  uint8 voiceCtr() const { return _voiceCtr; }
469  void setVoiceCtr(uint8 v) { _voiceCtr = v; }
470 
471  // Miscellaneous
472  void doNothing(HotspotData *hotspot);
473  void converse(uint16 destCharacterId, uint16 messageId, bool srcStandStill = false,
474  bool destStandStill = false);
475  void showMessage(uint16 messageId, uint16 destCharacterId = NOONE_ID);
476  void scheduleConverse(uint16 destHotspot, uint16 messageId);
477  void handleTalkDialog();
478 
479  void saveToStream(Common::WriteStream *stream) const;
480  void loadFromStream(Common::ReadStream *stream);
481 };
482 
483 class HotspotList: public Common::List<Common::SharedPtr<Hotspot> > {
484 public:
485  void saveToStream(Common::WriteStream *stream) const;
486  void loadFromStream(Common::ReadStream *stream);
487 };
488 
489 } // End of namespace Lure
490 
491 #endif
Definition: hotspots.h:483
Definition: str.h:59
Definition: stream.h:77
Definition: hotspots.h:172
Definition: res_struct.h:607
Direction
Definition: res_struct.h:251
Definition: list.h:44
Definition: res_struct.h:513
Definition: hotspots.h:37
Definition: hotspots.h:180
void push_front(const t_T &element)
Definition: list.h:135
Definition: res_struct.h:293
Definition: res_struct.h:459
Definition: hotspots.h:120
iterator begin()
Definition: list.h:227
Definition: rect.h:45
Definition: res_struct.h:582
Definition: res_struct.h:641
Definition: stream.h:385
iterator erase(iterator pos)
Definition: list.h:95
Definition: animseq.h:27
Definition: ptr.h:159
void push_back(const t_T &element)
Definition: list.h:140
Definition: surface.h:35
bool empty() const
Definition: list.h:219
Definition: hotspots.h:52
Definition: hotspots.h:107