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; // 0: walking to a coordinate, 0xffff: invalid sentinel, else: room-exit hotspot
218  uint16 _walkToHotspotId; // hotspot being approached for interaction; exempt from block-avoidance
219  uint16 _blockedOffset;
220  uint8 _exitCtr;
221  bool _walkFlag;
222  uint16 _startRoomNumber;
223  uint16 _supportValue;
224 
225  // Support methods
226  uint16 getTalkId(HotspotData *charHotspot);
227  void startTalk(HotspotData *charHotspot, uint16 id);
228  void startTalkDialog();
229 
230  // Action support methods
231  HotspotPrecheckResult actionPrecheck(HotspotData *hotspot);
232  BarPlaceResult getBarPlace();
233  bool findClearBarPlace();
234  bool characterWalkingCheck(uint16 id);
235  void resetDirection();
236 
237  // Action set
238  void doGet(HotspotData *hotspot);
239  void doOperate(HotspotData *hotspot);
240  void doOpen(HotspotData *hotspot);
241  void doClose(HotspotData *hotspot);
242  void doLockUnlock(HotspotData *hotspot);
243  void doUse(HotspotData *hotspot);
244  void doGive(HotspotData *hotspot);
245  void doTalkTo(HotspotData *hotspot);
246  void doTell(HotspotData *hotspot);
247  void doLook(HotspotData *hotspot);
248  void doLookAt(HotspotData *hotspot);
249  void doLookThrough(HotspotData *hotspot);
250  void doAsk(HotspotData *hotspot);
251  void doDrink(HotspotData *hotspot);
252  void doStatus(HotspotData *hotspot);
253  void doGoto(HotspotData *hotspot);
254  void doReturn(HotspotData *hotspot);
255  void doBribe(HotspotData *hotspot);
256  void doExamine(HotspotData *hotspot);
257  void npcSetRoomAndBlockedOffset(HotspotData *hotspot);
258  void npcHeySir(HotspotData *hotspot);
259  void npcExecScript(HotspotData *hotspot);
260  void npcResetPausedList(HotspotData *hotspot);
261  void npcSetRandomDest(HotspotData *hotspot);
262  void npcWalkingCheck(HotspotData *hotspot);
263  void npcSetSupportOffset(HotspotData *hotspot);
264  void npcSupportOffsetConditional(HotspotData *hotspot);
265  void npcDispatchAction(HotspotData *hotspot);
266  void npcTalkNpcToNpc(HotspotData *hotspot);
267  void npcPause(HotspotData *hotspot);
268  void npcStartTalking(HotspotData *hotspot);
269  void npcJumpAddress(HotspotData *hotspot);
270 
271  // Auxiliaries
272  void doLookAction(HotspotData *hotspot, Action action);
273 public:
274  Hotspot(HotspotData *res);
275  Hotspot(Hotspot *character, uint16 objType);
276  Hotspot();
277  ~Hotspot();
278 
279  void setAnimation(uint16 newAnimId);
280  void setAnimationIndex(int animIndex);
281  void setAnimation(HotspotAnimData *newRecord);
282  uint16 hotspotId() const { return _hotspotId; }
283  uint16 originalId() const { return _originalId; }
284  Surface &frames() const { return *_frames; }
285  HotspotAnimData &anim() const { return *_anim; }
286  HotspotData *resource() const { return _data; }
287  uint16 numFrames() const { return _numFrames; }
288  uint16 frameNumber() const { return _frameNumber; }
289  void setFrameNumber(uint16 frameNum) {
290  assert(frameNum < _numFrames);
291  _frameNumber = frameNum;
292  }
293  void incFrameNumber();
294  Direction direction() const { return _direction; }
295  uint16 frameWidth() const { return _width; }
296  int16 x() const { return _startX; }
297  int16 y() const { return _startY; }
298  int16 destX() const { return _destX; }
299  int16 destY() const { return _destY; }
300  int8 talkX() const { return _talkX; }
301  int8 talkY() const { return _talkY; }
302  uint16 destHotspotId() const { return _destHotspotId; }
303  uint16 walkToHotspot() const { return _walkToHotspotId; }
304  uint16 blockedOffset() const { return _blockedOffset; }
305  uint8 exitCtr() const { return _exitCtr; }
306  bool walkFlag() const { return _walkFlag; }
307  uint16 startRoomNumber() const { return _startRoomNumber; }
308  uint16 width() const { return _width; }
309  uint16 height() const { return _height; }
310  uint16 widthCopy() const { return _widthCopy; }
311  uint16 heightCopy() const { return _heightCopy; }
312  uint16 yCorrection() const { return _yCorrection; }
313  uint16 charRectY() const { return _charRectY; }
314  uint16 roomNumber() const { return _roomNumber; }
315  uint16 talkScript() const {
316  assert(_data);
317  return _data->talkScriptOffset;
318  }
319  uint16 hotspotScript() const { return _hotspotScriptOffset; }
320  uint8 layer() const { return _layer; }
321  bool skipFlag() const { return _skipFlag; }
322  void setTickProc(uint16 newVal);
323  bool persistent() const { return _persistent; }
324  void setPersistent(bool value) { _persistent = value; }
325  uint8 colorOffset() const { return _colorOffset; }
326  void setColorOffset(uint8 value) { _colorOffset = value; }
327  void setRoomNumber(uint16 roomNum) {
328  _roomNumber = roomNum;
329  if (_data) _data->roomNumber = roomNum;
330  }
331  uint16 nameId() const;
332  const char *getName();
333  bool isActiveAnimation();
334  void setPosition(int16 newX, int16 newY);
335  void setDestPosition(int16 newX, int16 newY) { _destX = newX; _destY = newY; }
336  void setDestHotspot(uint16 id) { _destHotspotId = id; }
337  void setWalkToHotspot(uint16 id) { _walkToHotspotId = id; }
338  void setExitCtr(uint8 value) { _exitCtr = value; }
339  BlockedState blockedState() const {
340  assert(_data);
341  return _data->blockedState;
342  }
343  void setBlockedState(BlockedState newState) {
344  assert(_data);
345  _data->blockedState = newState;
346  }
347  bool blockedFlag() const {
348  assert(_data);
349  return _data->blockedFlag;
350  }
351  void setBlockedFlag(bool newValue) {
352  assert(_data);
353  _data->blockedFlag = newValue;
354  }
355  void setWalkFlag(bool value) { _walkFlag = value; }
356  void setStartRoomNumber(uint16 value) { _startRoomNumber = value; }
357  void setSize(uint16 newWidth, uint16 newHeight);
358  void setWidth(uint16 newWidth) {
359  _width = newWidth;
360  _frameWidth = newWidth;
361  }
362  void setHeight(uint16 newHeight) {
363  _height = newHeight;
364  }
365  void setHotspotScript(uint16 offset) {
366  assert(_data != NULL);
367  _hotspotScriptOffset = offset;
368  _data->hotspotScriptOffset = offset;
369  }
370  void setLayer(uint8 newLayer) {
371  assert(_data != NULL);
372  _layer = newLayer;
373  _data->layer = newLayer;
374  }
375  void setActions(uint32 newActions) {
376  assert(_data);
377  _data->actions = newActions;
378  }
379  void setCharRectY(uint16 value) { _charRectY = value; }
380  void setSkipFlag(bool value) { _skipFlag = value; }
381  CharacterMode characterMode() const {
382  assert(_data != NULL);
383  return _data->characterMode;
384  }
385  void setCharacterMode(CharacterMode value) {
386  assert(_data != NULL);
387  _data->characterMode = value;
388  }
389  uint16 delayCtr() const {
390  assert(_data);
391  return _data->delayCtr;
392  }
393  void setDelayCtr(uint16 value) {
394  assert(_data);
395  _data->delayCtr = value;
396  }
397  uint16 pauseCtr() const {
398  assert(_data);
399  return _data->pauseCtr;
400  }
401  void setPauseCtr(uint16 value) {
402  assert(_data);
403  _data->pauseCtr = value;
404  }
405  VariantBool coveredFlag() const {
406  assert(_data);
407  return _data->coveredFlag;
408  }
409  void setCoveredFlag(VariantBool value) {
410  assert(_data);
411  _data->coveredFlag = value;
412  }
413  uint16 useHotspotId() const {
414  assert(_data);
415  return _data->useHotspotId;
416  }
417  void setUseHotspotId(uint16 value) {
418  assert(_data);
419  _data->useHotspotId = value;
420  }
421  uint16 talkGate() const {
422  assert(_data);
423  return _data->talkGate;
424  }
425  void setTalkGate(uint16 value) {
426  assert(_data);
427  _data->talkGate = value;
428  }
429  uint16 supportValue() const { return _supportValue; }
430  void setSupportValue(uint16 value) { _supportValue = value; }
431 
432  void copyTo(Surface *dest);
433  bool executeScript();
434  void tick();
435  bool isRoomExit(uint16 id);
436 
437  // Walking
438  void walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot = 0);
439  void stopWalking();
440  void endAction();
441  void setDirection(Direction dir);
442  void faceHotspot(HotspotData *hotspot);
443  void faceHotspot(uint16 hotspotId);
444  void setRandomDest();
445  void setOccupied(bool occupiedFlag);
446  bool walkingStep();
447  void updateMovement();
448  void updateMovement2(CharacterMode value);
449  void resetPosition();
450  bool doorCloseCheck(uint16 doorId);
451 
452  void doAction();
453  void doAction(Action action, HotspotData *hotspot);
454  CurrentActionStack &currentActions() const {
455  assert(_data);
456  return _data->npcSchedule;
457  }
458  PathFinder &pathFinder() { return _pathFinder; }
459  DestStructure &tempDest() { return _tempDest; }
460  uint16 frameCtr() const { return _frameCtr; }
461  void setFrameCtr(uint16 value) { _frameCtr = value; }
462  void decrFrameCtr() { if (_frameCtr > 0) --_frameCtr; }
463  uint8 actionCtr() const {
464  assert(_data);
465  return _data->actionCtr;
466  }
467  void setActionCtr(uint8 v) {
468  assert(_data);
469  _data->actionCtr = v;
470  }
471  uint8 voiceCtr() const { return _voiceCtr; }
472  void setVoiceCtr(uint8 v) { _voiceCtr = v; }
473 
474  // Miscellaneous
475  void doNothing(HotspotData *hotspot);
476  void converse(uint16 destCharacterId, uint16 messageId, bool srcStandStill = false,
477  bool destStandStill = false);
478  void showMessage(uint16 messageId, uint16 destCharacterId = NOONE_ID);
479  void scheduleConverse(uint16 destHotspot, uint16 messageId);
480  void handleTalkDialog();
481 
482  void saveToStream(Common::WriteStream *stream) const;
483  void loadFromStream(Common::ReadStream *stream);
484 };
485 
486 class HotspotList: public Common::List<Common::SharedPtr<Hotspot> > {
487 public:
488  void saveToStream(Common::WriteStream *stream) const;
489  void loadFromStream(Common::ReadStream *stream);
490 };
491 
492 } // End of namespace Lure
493 
494 #endif
Definition: hotspots.h:486
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:158
Definition: res_struct.h:293
Definition: res_struct.h:459
Definition: hotspots.h:120
iterator begin()
Definition: list.h:266
Definition: rect.h:144
Definition: res_struct.h:582
Definition: res_struct.h:641
Definition: stream.h:385
iterator erase(iterator pos)
Definition: list.h:112
Definition: animseq.h:27
Definition: ptr.h:159
void push_back(const t_T &element)
Definition: list.h:174
Definition: surface.h:35
bool empty() const
Definition: list.h:258
Definition: hotspots.h:52
Definition: hotspots.h:107