2006-02-11 12:54:56 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2005-2006 The ScummVM project
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __lure_hotspots_h__
|
|
|
|
#define __lure_hotspots_h__
|
|
|
|
|
|
|
|
#include "lure/luredefs.h"
|
|
|
|
#include "lure/screen.h"
|
|
|
|
#include "lure/disk.h"
|
|
|
|
#include "lure/res_struct.h"
|
|
|
|
|
|
|
|
namespace Lure {
|
|
|
|
|
2006-04-11 10:52:11 +00:00
|
|
|
#define MAX_NUM_IMPINGING 10
|
|
|
|
|
2006-02-11 12:54:56 +00:00
|
|
|
class Hotspot;
|
|
|
|
|
2006-04-11 10:52:11 +00:00
|
|
|
class Support {
|
|
|
|
public:
|
|
|
|
static int findIntersectingCharacters(Hotspot &h, uint16 *charList);
|
|
|
|
static bool checkForIntersectingCharacter(Hotspot &h);
|
|
|
|
static void checkRoomChange(Hotspot &h);
|
|
|
|
static void characterChangeRoom(Hotspot &h, uint16 roomNumber,
|
|
|
|
int16 newX, int16 newY, Direction dir);
|
|
|
|
static bool charactersIntersecting(HotspotData *hotspot1, HotspotData *hotspot2);
|
|
|
|
};
|
|
|
|
|
2006-02-11 12:54:56 +00:00
|
|
|
typedef void(*HandlerMethodPtr)(Hotspot &h);
|
|
|
|
|
|
|
|
class HotspotTickHandlers {
|
|
|
|
private:
|
2006-02-19 04:25:28 +00:00
|
|
|
// Handler methods
|
2006-02-11 12:54:56 +00:00
|
|
|
static void defaultHandler(Hotspot &h);
|
|
|
|
static void standardAnimHandler(Hotspot &h);
|
2006-04-11 10:52:11 +00:00
|
|
|
static void standardCharacterAnimHandler(Hotspot &h);
|
2006-02-11 12:54:56 +00:00
|
|
|
static void roomExitAnimHandler(Hotspot &h);
|
|
|
|
static void playerAnimHandler(Hotspot &h);
|
|
|
|
static void droppingTorchAnimHandler(Hotspot &h);
|
|
|
|
static void fireAnimHandler(Hotspot &h);
|
2006-02-19 04:25:28 +00:00
|
|
|
static void talkAnimHandler(Hotspot &h);
|
2006-02-11 12:54:56 +00:00
|
|
|
static void headAnimationHandler(Hotspot &h);
|
|
|
|
|
|
|
|
public:
|
|
|
|
static HandlerMethodPtr getHandler(uint16 procOffset);
|
|
|
|
};
|
|
|
|
|
2006-04-11 10:52:11 +00:00
|
|
|
enum CurrentAction {NO_ACTION, START_WALKING, DISPATCH_ACTION, EXEC_HOTSPOT_SCRIPT,
|
|
|
|
PROCESSING_PATH, WALKING};
|
|
|
|
|
|
|
|
class CurrentActionEntry {
|
|
|
|
private:
|
|
|
|
CurrentAction _action;
|
|
|
|
Action _hotspotAction;
|
|
|
|
uint16 _hotspotId;
|
|
|
|
public:
|
|
|
|
CurrentActionEntry(CurrentAction newAction) { _action = newAction; }
|
|
|
|
CurrentActionEntry(CurrentAction newAction, Action hsAction, uint16 id) {
|
|
|
|
_action = newAction;
|
|
|
|
_hotspotAction = hsAction;
|
|
|
|
_hotspotId = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
CurrentAction action() { return _action; }
|
|
|
|
Action hotspotAction() { return _hotspotAction; }
|
|
|
|
uint16 hotspotId() { return _hotspotId; }
|
|
|
|
};
|
|
|
|
|
|
|
|
class CurrentActionStack {
|
|
|
|
private:
|
|
|
|
ManagedList<CurrentActionEntry *> _actions;
|
|
|
|
public:
|
|
|
|
CurrentActionStack() { _actions.clear(); }
|
|
|
|
|
|
|
|
bool isEmpty() { return _actions.begin() == _actions.end(); }
|
|
|
|
void clear() { _actions.clear(); }
|
|
|
|
CurrentActionEntry &top() { return **_actions.begin(); }
|
|
|
|
CurrentAction action() { return isEmpty() ? NO_ACTION : top().action(); }
|
|
|
|
void pop() { _actions.erase(_actions.begin()); }
|
|
|
|
void add(CurrentAction newAction) {
|
|
|
|
_actions.push_back(new CurrentActionEntry(newAction));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class WalkingActionEntry {
|
|
|
|
private:
|
|
|
|
Direction _direction;
|
|
|
|
int _numSteps;
|
|
|
|
public:
|
|
|
|
WalkingActionEntry(Direction dir, int steps): _direction(dir), _numSteps(steps) {};
|
|
|
|
Direction direction() { return _direction; }
|
|
|
|
int &rawSteps() { return _numSteps; }
|
|
|
|
int numSteps();
|
|
|
|
};
|
|
|
|
|
|
|
|
enum PathFinderResult {PF_OK, PF_DEST_OCCUPIED, PF_NO_PATH, PF_NO_WALK};
|
|
|
|
|
|
|
|
class PathFinder {
|
|
|
|
private:
|
|
|
|
Hotspot *_hotspot;
|
|
|
|
ManagedList<WalkingActionEntry *> _list;
|
|
|
|
RoomPathsDecompressedData _layer;
|
|
|
|
int _stepCtr;
|
|
|
|
bool _inProgress;
|
|
|
|
int _countdownCtr;
|
|
|
|
int16 _destX, _destY;
|
|
|
|
int16 _xPos, _yPos;
|
|
|
|
int16 _xCurrent, _yCurrent;
|
|
|
|
int16 _xDestPos, _yDestPos;
|
|
|
|
int16 _xDestCurrent, _yDestCurrent;
|
|
|
|
bool _destOccupied;
|
|
|
|
bool _cellPopulated;
|
|
|
|
PathFinderResult _result;
|
|
|
|
uint16 *_pSrc, *_pDest;
|
|
|
|
int _xChangeInc, _xChangeStart;
|
|
|
|
int _yChangeInc, _yChangeStart;
|
|
|
|
int _xCtr, _yCtr;
|
|
|
|
|
|
|
|
void initVars();
|
|
|
|
void processCell(uint16 *p);
|
|
|
|
void scanLine(int numScans, int changeAmount, uint16 *&pEnd, int &v);
|
|
|
|
|
|
|
|
void add(Direction dir, int steps) {
|
|
|
|
_list.push_front(new WalkingActionEntry(dir, steps));
|
|
|
|
}
|
|
|
|
void addBack(Direction dir, int steps) {
|
|
|
|
_list.push_back(new WalkingActionEntry(dir, steps));
|
|
|
|
}
|
|
|
|
void clear() { _list.clear(); }
|
|
|
|
public:
|
|
|
|
PathFinder(Hotspot *h);
|
|
|
|
void reset(RoomPathsData &src);
|
|
|
|
bool process();
|
|
|
|
|
|
|
|
void pop() { _list.erase(_list.begin()); }
|
|
|
|
WalkingActionEntry &top() { return **_list.begin(); }
|
|
|
|
bool isEmpty() { return _list.empty(); }
|
|
|
|
int &stepCtr() { return _stepCtr; }
|
|
|
|
};
|
|
|
|
|
|
|
|
enum HotspotPrecheckResult {PC_0, PC_1, PC_2, PC_INITIAL, PC_4};
|
2006-02-11 12:54:56 +00:00
|
|
|
|
|
|
|
class Hotspot {
|
|
|
|
private:
|
|
|
|
HotspotData *_data;
|
|
|
|
HotspotAnimData *_anim;
|
|
|
|
HandlerMethodPtr _tickHandler;
|
|
|
|
Surface *_frames;
|
2006-02-19 04:25:28 +00:00
|
|
|
uint16 _hotspotId;
|
|
|
|
uint16 _roomNumber;
|
2006-02-11 12:54:56 +00:00
|
|
|
int16 _startX, _startY;
|
|
|
|
uint16 _height, _width;
|
2006-02-19 04:25:28 +00:00
|
|
|
uint16 _heightCopy, _widthCopy;
|
2006-04-11 10:52:11 +00:00
|
|
|
uint16 _yCorrection;
|
|
|
|
uint16 _charRectY;
|
2006-02-19 04:25:28 +00:00
|
|
|
int8 _talkX, _talkY;
|
2006-02-11 12:54:56 +00:00
|
|
|
uint16 _numFrames;
|
|
|
|
uint16 _frameNumber;
|
2006-04-11 10:52:11 +00:00
|
|
|
Direction _direction;
|
2006-02-19 04:25:28 +00:00
|
|
|
uint8 _layer;
|
|
|
|
uint16 _sequenceOffset;
|
2006-02-11 12:54:56 +00:00
|
|
|
uint16 _tickCtr;
|
2006-02-19 04:25:28 +00:00
|
|
|
uint32 _actions;
|
|
|
|
uint8 _colourOffset;
|
2006-02-11 12:54:56 +00:00
|
|
|
bool _persistant;
|
2006-02-19 04:25:28 +00:00
|
|
|
HotspotOverrideData *_override;
|
2006-04-11 10:52:11 +00:00
|
|
|
bool _skipFlag;
|
|
|
|
bool _pathfindCovered;
|
2006-02-11 12:54:56 +00:00
|
|
|
|
2006-04-11 10:52:11 +00:00
|
|
|
CurrentActionStack _currentActions;
|
|
|
|
PathFinder _pathFinder;
|
|
|
|
|
|
|
|
uint16 _frameCtr;
|
2006-02-11 12:54:56 +00:00
|
|
|
int16 _destX, _destY;
|
|
|
|
uint16 _destHotspotId;
|
2006-02-19 04:25:28 +00:00
|
|
|
|
|
|
|
// Support methods
|
|
|
|
void startTalk(HotspotData *charHotspot);
|
|
|
|
|
2006-04-11 10:52:11 +00:00
|
|
|
// Action support methods
|
|
|
|
HotspotPrecheckResult actionPrecheck(HotspotData *hotspot);
|
|
|
|
HotspotPrecheckResult actionPrecheck2(HotspotData *hotspot);
|
|
|
|
void actionPrecheck3(HotspotData *hotspot);
|
|
|
|
bool characterWalkingCheck(HotspotData *hotspot);
|
|
|
|
|
2006-02-19 04:25:28 +00:00
|
|
|
// Action set
|
|
|
|
void doGet(HotspotData *hotspot);
|
|
|
|
void doOperate(HotspotData *hotspot, Action action);
|
|
|
|
void doOpen(HotspotData *hotspot);
|
|
|
|
void doClose(HotspotData *hotspot);
|
|
|
|
void doLockUnlock(HotspotData *hotspot);
|
|
|
|
void doUse(HotspotData *hotspot);
|
|
|
|
void doGive(HotspotData *hotspot);
|
|
|
|
void doTalkTo(HotspotData *hotspot);
|
|
|
|
void doTell(HotspotData *hotspot);
|
|
|
|
void doLook();
|
|
|
|
void doLookAt(HotspotData *hotspot);
|
|
|
|
void doAsk(HotspotData *hotspot);
|
|
|
|
void doDrink();
|
|
|
|
void doStatus();
|
|
|
|
void doBribe(HotspotData *hotspot);
|
|
|
|
void doExamine();
|
|
|
|
void doSimple(HotspotData *hotspot, Action action);
|
2006-02-11 12:54:56 +00:00
|
|
|
public:
|
|
|
|
Hotspot(HotspotData *res);
|
2006-02-19 04:25:28 +00:00
|
|
|
Hotspot(Hotspot *character, uint16 objType);
|
2006-02-11 12:54:56 +00:00
|
|
|
~Hotspot();
|
|
|
|
|
|
|
|
void setAnimation(uint16 newAnimId);
|
|
|
|
void setAnimation(HotspotAnimData *newRecord);
|
2006-02-19 04:25:28 +00:00
|
|
|
uint16 hotspotId() { return _hotspotId; }
|
2006-02-11 12:54:56 +00:00
|
|
|
Surface &frames() { return *_frames; }
|
|
|
|
HotspotAnimData &anim() { return *_anim; }
|
2006-02-19 04:25:28 +00:00
|
|
|
HotspotData *resource() { return _data; }
|
2006-02-11 12:54:56 +00:00
|
|
|
uint16 numFrames() { return _numFrames; }
|
|
|
|
uint16 frameNumber() { return _frameNumber; }
|
|
|
|
void setFrameNumber(uint16 v) { _frameNumber = v; }
|
|
|
|
void incFrameNumber();
|
2006-04-11 10:52:11 +00:00
|
|
|
Direction direction() { return _direction; }
|
2006-02-11 12:54:56 +00:00
|
|
|
uint16 frameWidth() { return _width; }
|
|
|
|
int16 x() { return _startX; }
|
|
|
|
int16 y() { return _startY; }
|
|
|
|
int16 destX() { return _destX; }
|
|
|
|
int16 destY() { return _destY; }
|
2006-02-19 04:25:28 +00:00
|
|
|
int8 talkX() { return _talkX; }
|
|
|
|
int8 talkY() { return _talkY; }
|
2006-02-11 12:54:56 +00:00
|
|
|
uint16 destHotspotId() { return _destHotspotId; }
|
|
|
|
uint16 width() { return _width; }
|
|
|
|
uint16 height() { return _height; }
|
2006-02-19 04:25:28 +00:00
|
|
|
uint16 widthCopy() { return _widthCopy; }
|
|
|
|
uint16 heightCopy() { return _heightCopy; }
|
2006-04-11 10:52:11 +00:00
|
|
|
uint16 yCorrection() { return _yCorrection; }
|
|
|
|
uint16 charRectY() { return _charRectY; }
|
2006-02-19 04:25:28 +00:00
|
|
|
uint16 roomNumber() { return _roomNumber; }
|
|
|
|
uint16 script() { return _sequenceOffset; }
|
|
|
|
uint8 layer() { return _layer; }
|
2006-02-11 12:54:56 +00:00
|
|
|
uint16 tickCtr() { return _tickCtr; }
|
2006-04-11 10:52:11 +00:00
|
|
|
bool skipFlag() { return _skipFlag; }
|
2006-02-11 12:54:56 +00:00
|
|
|
void setTickCtr(uint16 newVal) { _tickCtr = newVal; }
|
|
|
|
void setTickProc(uint16 newVal);
|
|
|
|
bool persistant() { return _persistant; }
|
|
|
|
void setPersistant(bool value) { _persistant = value; }
|
2006-02-19 04:25:28 +00:00
|
|
|
void setRoomNumber(uint16 roomNum) {
|
|
|
|
_roomNumber = roomNum;
|
|
|
|
if (_data) _data->roomNumber = roomNum;
|
|
|
|
}
|
|
|
|
uint16 nameId();
|
2006-02-11 12:54:56 +00:00
|
|
|
bool isActiveAnimation();
|
|
|
|
void setPosition(int16 newX, int16 newY);
|
|
|
|
void setDestPosition(int16 newX, int16 newY) { _destX = newX; _destY = newY; }
|
2006-04-11 10:52:11 +00:00
|
|
|
void setDestHotspot(uint16 id) { _destHotspotId = id; }
|
2006-02-11 12:54:56 +00:00
|
|
|
void setSize(uint16 newWidth, uint16 newHeight);
|
2006-02-19 04:25:28 +00:00
|
|
|
void setScript(uint16 offset) {
|
|
|
|
_sequenceOffset = offset;
|
|
|
|
_data->sequenceOffset = offset;
|
|
|
|
}
|
|
|
|
void setActions(uint32 newActions) { _actions = newActions; }
|
2006-04-11 10:52:11 +00:00
|
|
|
void setCharRectY(uint16 value) { _charRectY = value; }
|
|
|
|
void setSkipFlag(bool value) { _skipFlag = value; }
|
2006-02-11 12:54:56 +00:00
|
|
|
|
|
|
|
void copyTo(Surface *dest);
|
|
|
|
bool executeScript();
|
|
|
|
void tick();
|
2006-02-19 04:25:28 +00:00
|
|
|
bool isRoomExit(uint16 id);
|
2006-02-11 12:54:56 +00:00
|
|
|
|
2006-04-11 10:52:11 +00:00
|
|
|
// Walking
|
|
|
|
void walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot = 0);
|
|
|
|
void stopWalking() { _currentActions.clear(); }
|
|
|
|
void setDirection(Direction dir);
|
|
|
|
void faceHotspot(HotspotData *hotspot);
|
|
|
|
void setOccupied(bool occupiedFlag);
|
|
|
|
bool walkingStep();
|
|
|
|
|
|
|
|
// Actions
|
2006-02-11 12:54:56 +00:00
|
|
|
void doAction(Action action, HotspotData *hotspot);
|
2006-04-11 10:52:11 +00:00
|
|
|
void setCurrentAction(CurrentAction currAction) { _currentActions.add(currAction); }
|
|
|
|
CurrentActionStack ¤tActions() { return _currentActions; }
|
|
|
|
PathFinder &pathFinder() { return _pathFinder; }
|
|
|
|
uint16 frameCtr() { return _frameCtr; }
|
|
|
|
void setFrameCtr(uint16 value) { _frameCtr = value; }
|
|
|
|
void decrFrameCtr() { if (_frameCtr > 0) --_frameCtr; }
|
2006-02-11 12:54:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef ManagedList<Hotspot *> HotspotList;
|
|
|
|
|
|
|
|
} // End of namespace Lure
|
|
|
|
|
|
|
|
#endif
|