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
30namespace Lure {
31
32#define MAX_NUM_IMPINGING 10
33
34class Hotspot;
35class HotspotTickHandlers;
36
37class Support {
38private:
39 static bool changeRoomCheckBumped(Hotspot &h);
40public:
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
50typedef void (HotspotTickHandlers::*HandlerMethodPtr)(Hotspot &h);
51
53private:
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);
101public:
103
104 HandlerMethodPtr getHandler(uint16 procIndex);
105};
106
108private:
109 Direction _direction;
110 int _numSteps;
111public:
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
118enum PathFinderResult {PF_UNFINISHED, PF_OK, PF_DEST_OCCUPIED, PF_PART_PATH, PF_NO_WALK};
119
121private:
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 }
152public:
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
168enum HotspotPrecheckResult {PC_EXECUTE, PC_NOT_IN_ROOM, PC_FAILED, PC_WAIT, PC_EXCESS};
169
170enum 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
180class Hotspot {
181private:
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);
273public:
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
486class HotspotList: public Common::List<Common::SharedPtr<Hotspot> > {
487public:
488 void saveToStream(Common::WriteStream *stream) const;
489 void loadFromStream(Common::ReadStream *stream);
490};
491
492} // End of namespace Lure
493
494#endif
Definition: list.h:44
iterator begin()
Definition: list.h:266
void push_front(const t_T &element)
Definition: list.h:158
iterator erase(iterator pos)
Definition: list.h:112
void push_back(const t_T &element)
Definition: list.h:174
bool empty() const
Definition: list.h:258
Definition: stream.h:385
Definition: ptr.h:159
Definition: str.h:59
Definition: stream.h:77
Definition: res_struct.h:459
Definition: res_struct.h:607
Definition: res_struct.h:513
Definition: hotspots.h:180
Definition: hotspots.h:486
Definition: res_struct.h:582
Definition: hotspots.h:52
Definition: hotspots.h:120
Definition: res_struct.h:293
Definition: hotspots.h:37
Definition: surface.h:35
Definition: res_struct.h:641
Definition: hotspots.h:107
Definition: animseq.h:27
Direction
Definition: res_struct.h:251
Definition: rect.h:144
Definition: hotspots.h:172