mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-27 04:07:05 +00:00
2a6a79b167
This was a hack that was implemented while IHNM was being developed. That code should no longer be needed. If this issue does occur again, the actual cause should be investigated, instead of hiding it with workarounds. The code was buggy anyway, as _currentProtag was not initialized properly
682 lines
17 KiB
C++
682 lines
17 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
// Actor management module header file
|
|
|
|
#ifndef SAGA_ACTOR_H
|
|
#define SAGA_ACTOR_H
|
|
|
|
#include "common/savefile.h"
|
|
|
|
#include "saga/sprite.h"
|
|
#include "saga/itedata.h"
|
|
#include "saga/saga.h"
|
|
#include "saga/font.h"
|
|
|
|
namespace Saga {
|
|
|
|
class HitZone;
|
|
|
|
|
|
//#define ACTOR_DEBUG 1 //only for actor pathfinding debug!
|
|
|
|
#define ACTOR_BARRIERS_MAX 16
|
|
|
|
#define ACTOR_MAX_STEPS_COUNT 32
|
|
|
|
#define ACTOR_DIALOGUE_HEIGHT 100
|
|
|
|
#define ACTOR_LMULT 4
|
|
|
|
#define ACTOR_SPEED 72
|
|
|
|
#define ACTOR_CLIMB_SPEED 8
|
|
|
|
#define ACTOR_COLLISION_WIDTH 32
|
|
#define ACTOR_COLLISION_HEIGHT 8
|
|
|
|
#define ACTOR_DIRECTIONS_COUNT 4 // for ActorFrameSequence
|
|
|
|
#define ACTOR_SPEECH_STRING_MAX 16 // speech const
|
|
#define ACTOR_SPEECH_ACTORS_MAX 8
|
|
|
|
#define ACTOR_DRAGON_TURN_MOVES 4
|
|
#define ACTOR_DRAGON_INDEX 133
|
|
|
|
#define ACTOR_NO_ENTRANCE -1
|
|
|
|
#define ACTOR_EXP_KNOCK_RIF 24
|
|
|
|
#define PATH_NODE_EMPTY -1
|
|
|
|
#define ACTOR_INHM_SIZE 228
|
|
|
|
enum ActorDirections {
|
|
kDirectionRight = 0,
|
|
kDirectionLeft = 1,
|
|
kDirectionUp = 2,
|
|
kDirectionDown = 3
|
|
};
|
|
|
|
enum ActorActions {
|
|
kActionWait = 0,
|
|
kActionWalkToPoint = 1,
|
|
kActionWalkToLink = 2,
|
|
kActionWalkDir = 3,
|
|
kActionSpeak = 4,
|
|
kActionAccept = 5,
|
|
kActionStoop = 6,
|
|
kActionLook = 7,
|
|
kActionCycleFrames = 8,
|
|
kActionPongFrames = 9,
|
|
kActionFreeze = 10,
|
|
kActionFall = 11,
|
|
kActionClimb = 12
|
|
};
|
|
|
|
enum ActorFrameIds {
|
|
//ITE
|
|
kFrameITEStand = 0,
|
|
kFrameITEWalk = 1,
|
|
kFrameITESpeak = 2,
|
|
kFrameITEGive = 3,
|
|
kFrameITEGesture = 4,
|
|
kFrameITEWait = 5,
|
|
kFrameITEPickUp = 6,
|
|
kFrameITELook = 7,
|
|
//IHNM
|
|
kFrameIHNMStand = 0,
|
|
kFrameIHNMSpeak = 1,
|
|
kFrameIHNMWait = 2,
|
|
kFrameIHNMGesture = 3,
|
|
kFrameIHNMWalk = 4
|
|
};
|
|
|
|
enum SpeechFlags {
|
|
kSpeakNoAnimate = 1,
|
|
kSpeakAsync = 2,
|
|
kSpeakSlow = 4,
|
|
kSpeakForceText = 8
|
|
};
|
|
|
|
enum ActorFrameTypes {
|
|
kFrameStand,
|
|
kFrameWalk,
|
|
kFrameSpeak,
|
|
kFrameGive,
|
|
kFrameGesture,
|
|
kFrameWait,
|
|
kFramePickUp,
|
|
kFrameLook
|
|
};
|
|
|
|
// Lookup table to convert 8 cardinal directions to 4
|
|
static const int actorDirectionsLUT[8] = {
|
|
kDirectionUp, // kDirUp
|
|
kDirectionRight, // kDirUpRight
|
|
kDirectionRight, // kDirRight
|
|
kDirectionRight, // kDirDownRight
|
|
kDirectionDown, // kDirDown
|
|
kDirectionLeft, // kDirDownLeft
|
|
kDirectionLeft, // kDirLeft
|
|
kDirectionLeft // kDirUpLeft
|
|
};
|
|
|
|
enum ActorFlagsEx {
|
|
kActorNoCollide = (1 << 0),
|
|
kActorNoFollow = (1 << 1),
|
|
kActorCollided = (1 << 2),
|
|
kActorBackwards = (1 << 3),
|
|
kActorContinuous = (1 << 4),
|
|
kActorFinalFace = (1 << 5),
|
|
kActorFinishLeft = ((1 << 5) | (kDirLeft << 6)),
|
|
kActorFinishRight = ((1 << 5) | (kDirRight << 6)),
|
|
kActorFinishUp = ((1 << 5) | (kDirUp << 6)),
|
|
kActorFinishDown = ((1 << 5) | (kDirDown << 6)),
|
|
kActorFacingMask = (0xf << 5),
|
|
kActorRandom = (1 << 10)
|
|
};
|
|
|
|
enum PathCellType {
|
|
kPathCellEmpty = -1,
|
|
//kDirUp = 0 .... kDirUpLeft = 7
|
|
kPathCellBarrier = 0x57
|
|
};
|
|
|
|
enum DragonMoveTypes {
|
|
kDragonMoveUpLeft = 0,
|
|
kDragonMoveUpRight = 1,
|
|
kDragonMoveDownLeft = 2,
|
|
kDragonMoveDownRight = 3,
|
|
kDragonMoveUpLeft_Left = 4,
|
|
kDragonMoveUpLeft_Right = 5,
|
|
kDragonMoveUpRight_Left = 6,
|
|
kDragonMoveUpRight_Right = 7,
|
|
kDragonMoveDownLeft_Left = 8,
|
|
kDragonMoveDownLeft_Right = 9,
|
|
kDragonMoveDownRight_Left = 10,
|
|
kDragonMoveDownRight_Right = 11,
|
|
kDragonMoveInvalid = 12
|
|
};
|
|
|
|
struct PathDirectionData {
|
|
int8 direction;
|
|
int16 x;
|
|
int16 y;
|
|
};
|
|
|
|
struct ActorFrameRange {
|
|
int frameIndex;
|
|
int frameCount;
|
|
};
|
|
|
|
struct ActorFrameSequence {
|
|
ActorFrameRange directions[ACTOR_DIRECTIONS_COUNT];
|
|
};
|
|
|
|
typedef Common::Array<ActorFrameSequence> ActorFrameSequences;
|
|
|
|
uint pathLine(PointList &pointList, uint idx, const Point &point1, const Point &point2);
|
|
|
|
struct Location {
|
|
int32 x; // logical coordinates
|
|
int32 y; //
|
|
int32 z; //
|
|
Location() {
|
|
x = y = z = 0;
|
|
}
|
|
void saveState(Common::OutSaveFile *out) {
|
|
out->writeSint32LE(x);
|
|
out->writeSint32LE(y);
|
|
out->writeSint32LE(z);
|
|
}
|
|
void loadState(Common::InSaveFile *in) {
|
|
x = in->readSint32LE();
|
|
y = in->readSint32LE();
|
|
z = in->readSint32LE();
|
|
}
|
|
|
|
int distance(const Location &location) const {
|
|
return MAX(ABS(x - location.x), ABS(y - location.y));
|
|
}
|
|
int32 &u() {
|
|
return x;
|
|
}
|
|
int32 &v() {
|
|
return y;
|
|
}
|
|
int32 u() const {
|
|
return x;
|
|
}
|
|
int32 v() const {
|
|
return y;
|
|
}
|
|
int32 uv() const {
|
|
return u() + v();
|
|
}
|
|
void delta(const Location &location, Location &result) const {
|
|
result.x = x - location.x;
|
|
result.y = y - location.y;
|
|
result.z = z - location.z;
|
|
}
|
|
void addXY(const Location &location) {
|
|
x += location.x;
|
|
y += location.y;
|
|
}
|
|
void add(const Location &location) {
|
|
x += location.x;
|
|
y += location.y;
|
|
z += location.z;
|
|
}
|
|
void fromScreenPoint(const Point &screenPoint) {
|
|
x = (screenPoint.x * ACTOR_LMULT);
|
|
y = (screenPoint.y * ACTOR_LMULT);
|
|
z = 0;
|
|
}
|
|
void toScreenPointXY(Point &screenPoint) const {
|
|
screenPoint.x = x / ACTOR_LMULT;
|
|
screenPoint.y = y / ACTOR_LMULT;
|
|
}
|
|
void toScreenPointUV(Point &screenPoint) const {
|
|
screenPoint.x = u();
|
|
screenPoint.y = v();
|
|
}
|
|
void toScreenPointXYZ(Point &screenPoint) const {
|
|
screenPoint.x = x / ACTOR_LMULT;
|
|
screenPoint.y = y / ACTOR_LMULT - z;
|
|
}
|
|
void fromStream(Common::ReadStream &stream) {
|
|
x = stream.readUint16LE();
|
|
y = stream.readUint16LE();
|
|
z = stream.readUint16LE();
|
|
}
|
|
|
|
#if 0
|
|
// Obsolete function, throws warnings in older versions of GCC
|
|
// (warning: int format, int32 arg)
|
|
// Keeping it around for debug purposes
|
|
void debugPrint(int debuglevel = 0, const char *loc = "Loc:") const {
|
|
debug(debuglevel, "%s %d, %d, %d", loc, x, y, z);
|
|
}
|
|
#endif
|
|
|
|
};
|
|
|
|
class CommonObjectData {
|
|
public:
|
|
//constant
|
|
int32 _index; // index in local array
|
|
uint16 _id; // object id
|
|
int32 _scriptEntrypointNumber; // script entrypoint number
|
|
|
|
//variables
|
|
uint16 _flags; // initial flags
|
|
int32 _nameIndex; // index in name string list
|
|
int32 _sceneNumber; // scene
|
|
int32 _spriteListResourceId; // sprite list resource id
|
|
|
|
Location _location; // logical coordinates
|
|
Point _screenPosition; // screen coordinates
|
|
int32 _screenDepth; //
|
|
int32 _screenScale; //
|
|
|
|
void saveState(Common::OutSaveFile *out) {
|
|
out->writeUint16LE(_flags);
|
|
out->writeSint32LE(_nameIndex);
|
|
out->writeSint32LE(_sceneNumber);
|
|
out->writeSint32LE(_spriteListResourceId);
|
|
_location.saveState(out);
|
|
out->writeSint16LE(_screenPosition.x);
|
|
out->writeSint16LE(_screenPosition.y);
|
|
out->writeSint32LE(_screenDepth);
|
|
out->writeSint32LE(_screenScale);
|
|
}
|
|
void loadState(Common::InSaveFile *in) {
|
|
_flags = in->readUint16LE();
|
|
_nameIndex = in->readSint32LE();
|
|
_sceneNumber = in->readSint32LE();
|
|
_spriteListResourceId = in->readSint32LE();
|
|
_location.loadState(in);
|
|
_screenPosition.x = in->readSint16LE();
|
|
_screenPosition.y = in->readSint16LE();
|
|
_screenDepth = in->readSint32LE();
|
|
_screenScale = in->readSint32LE();
|
|
}
|
|
|
|
CommonObjectData() {
|
|
_index = 0;
|
|
_id = 0;
|
|
_scriptEntrypointNumber = 0;
|
|
|
|
_flags = 0;
|
|
_nameIndex = 0;
|
|
_sceneNumber = 0;
|
|
_spriteListResourceId = 0;
|
|
|
|
_screenDepth = 0;
|
|
_screenScale = 0;
|
|
}
|
|
};
|
|
|
|
typedef CommonObjectData *CommonObjectDataPointer;
|
|
|
|
typedef Common::List<CommonObjectDataPointer> CommonObjectOrderList;
|
|
|
|
class ObjectData: public CommonObjectData {
|
|
public:
|
|
//constant
|
|
uint16 _interactBits;
|
|
|
|
ObjectData() {
|
|
_interactBits = 0;
|
|
}
|
|
};
|
|
|
|
typedef Common::Array<ObjectData> ObjectDataArray;
|
|
|
|
class ActorData: public CommonObjectData {
|
|
public:
|
|
//constant
|
|
SpriteList _spriteList; // sprite list data
|
|
|
|
ActorFrameSequences *_frames; // Actor's frames
|
|
ActorFrameSequences _framesContainer; // Actor's frames
|
|
int _frameListResourceId; // Actor's frame list resource id
|
|
|
|
byte _speechColor; // Actor dialogue color
|
|
//
|
|
bool _inScene;
|
|
|
|
//variables
|
|
uint16 _actorFlags; // dynamic flags
|
|
int32 _currentAction; // ActorActions type
|
|
int32 _facingDirection; // orientation
|
|
int32 _actionDirection;
|
|
int32 _actionCycle;
|
|
uint16 _targetObject;
|
|
const HitZone *_lastZone;
|
|
|
|
int32 _cycleFrameSequence;
|
|
uint8 _cycleDelay;
|
|
uint8 _cycleTimeCount;
|
|
uint8 _cycleFlags;
|
|
|
|
int16 _fallVelocity;
|
|
int16 _fallAcceleration;
|
|
int16 _fallPosition;
|
|
|
|
uint8 _dragonBaseFrame;
|
|
uint8 _dragonStepCycle;
|
|
uint8 _dragonMoveType;
|
|
|
|
int32 _frameNumber; // current frame number
|
|
|
|
ByteArray _tileDirections;
|
|
|
|
Common::Array<Point> _walkStepsPoints;
|
|
|
|
int32 _walkStepsCount;
|
|
int32 _walkStepIndex;
|
|
|
|
Location _finalTarget;
|
|
Location _partialTarget;
|
|
int32 _walkFrameSequence;
|
|
|
|
public:
|
|
ActorData();
|
|
|
|
void saveState(Common::OutSaveFile *out);
|
|
void loadState(uint32 version, Common::InSaveFile *in);
|
|
|
|
void cycleWrap(int cycleLimit);
|
|
void addWalkStepPoint(const Point &point);
|
|
bool shareFrames() {
|
|
return ((_frames != NULL) && (_frames != &_framesContainer));
|
|
}
|
|
};
|
|
|
|
typedef Common::Array<ActorData> ActorDataArray;
|
|
|
|
struct ProtagStateData {
|
|
ActorFrameSequences _frames; // Actor's frames
|
|
};
|
|
|
|
|
|
struct SpeechData {
|
|
int speechColor[ACTOR_SPEECH_ACTORS_MAX];
|
|
int outlineColor[ACTOR_SPEECH_ACTORS_MAX];
|
|
int speechFlags;
|
|
const char *strings[ACTOR_SPEECH_STRING_MAX];
|
|
Rect speechBox;
|
|
Rect drawRect;
|
|
int stringsCount;
|
|
int slowModeCharIndex;
|
|
uint16 actorIds[ACTOR_SPEECH_ACTORS_MAX];
|
|
int actorsCount;
|
|
int sampleResourceId;
|
|
bool playing;
|
|
int playingTime;
|
|
|
|
SpeechData() {
|
|
memset(this, 0, sizeof(*this));
|
|
}
|
|
|
|
FontEffectFlags getFontFlags(int i) {
|
|
if (outlineColor[i] != 0) {
|
|
return kFontOutline;
|
|
} else {
|
|
return kFontNormal;
|
|
}
|
|
}
|
|
};
|
|
|
|
typedef int (*CompareFunction) (const CommonObjectDataPointer& a, const CommonObjectDataPointer& b);
|
|
|
|
class Actor {
|
|
friend class IsoMap;
|
|
friend class SagaEngine;
|
|
friend class Puzzle;
|
|
public:
|
|
|
|
Actor(SagaEngine *vm);
|
|
~Actor();
|
|
|
|
void cmdActorWalkTo(int argc, const char **argv);
|
|
|
|
bool validActorId(uint16 id) {
|
|
return (id == ID_PROTAG) || ((id >= objectIndexToId(kGameObjectActor, 0)) && (id < objectIndexToId(kGameObjectActor, _actors.size())));
|
|
}
|
|
int actorIdToIndex(uint16 id) { return (id == ID_PROTAG) ? 0 : objectIdToIndex(id); }
|
|
uint16 actorIndexToId(int index) { return (index == 0) ? ID_PROTAG : objectIndexToId(kGameObjectActor, index); }
|
|
ActorData *getActor(uint16 actorId);
|
|
|
|
// clarification: Obj - means game object, such Hat, Spoon etc, Object - means Actor,Obj,HitZone,StepZone
|
|
|
|
bool validObjId(uint16 id) { return (id >= objectIndexToId(kGameObjectObject, 0)) && (id < objectIndexToId(kGameObjectObject, _objs.size())); }
|
|
int objIdToIndex(uint16 id) { return objectIdToIndex(id); }
|
|
uint16 objIndexToId(int index) { return objectIndexToId(kGameObjectObject, index); }
|
|
ObjectData *getObj(uint16 objId);
|
|
|
|
int getObjectScriptEntrypointNumber(uint16 id) {
|
|
int objectType;
|
|
objectType = objectTypeId(id);
|
|
if (!(objectType & (kGameObjectObject | kGameObjectActor))) {
|
|
error("Actor::getObjectScriptEntrypointNumber wrong id 0x%X", id);
|
|
}
|
|
return (objectType == kGameObjectObject) ? getObj(id)->_scriptEntrypointNumber : getActor(id)->_scriptEntrypointNumber;
|
|
}
|
|
int getObjectFlags(uint16 id) {
|
|
int objectType;
|
|
objectType = objectTypeId(id);
|
|
if (!(objectType & (kGameObjectObject | kGameObjectActor))) {
|
|
error("Actor::getObjectFlags wrong id 0x%X", id);
|
|
}
|
|
return (objectType == kGameObjectObject) ? getObj(id)->_flags : getActor(id)->_flags;
|
|
}
|
|
|
|
void direct(int msec);
|
|
void drawActors();
|
|
void updateActorsScene(int actorsEntrance); // calls from scene loading to update Actors info
|
|
|
|
void drawSpeech();
|
|
|
|
#ifdef ACTOR_DEBUG
|
|
void drawPathTest();
|
|
#endif
|
|
|
|
uint16 hitTest(const Point &testPoint, bool skipProtagonist);
|
|
void takeExit(uint16 actorId, const HitZone *hitZone);
|
|
bool actorEndWalk(uint16 actorId, bool recurse);
|
|
bool actorWalkTo(uint16 actorId, const Location &toLocation);
|
|
int getFrameType(ActorFrameTypes frameType);
|
|
ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType);
|
|
void actorFaceTowardsPoint(uint16 actorId, const Location &toLocation);
|
|
void actorFaceTowardsObject(uint16 actorId, uint16 objectId);
|
|
|
|
void realLocation(Location &location, uint16 objectId, uint16 walkFlags);
|
|
|
|
// speech
|
|
void actorSpeech(uint16 actorId, const char **strings, int stringsCount, int sampleResourceId, int speechFlags);
|
|
void nonActorSpeech(const Common::Rect &box, const char **strings, int stringsCount, int sampleResourceId, int speechFlags);
|
|
void simulSpeech(const char *string, uint16 *actorIds, int actorIdsCount, int speechFlags, int sampleResourceId);
|
|
void setSpeechColor(int speechColor, int outlineColor) {
|
|
_activeSpeech.speechColor[0] = speechColor;
|
|
_activeSpeech.outlineColor[0] = outlineColor;
|
|
}
|
|
void abortAllSpeeches();
|
|
void abortSpeech();
|
|
bool isSpeaking() {
|
|
return _activeSpeech.stringsCount > 0;
|
|
}
|
|
|
|
int isForcedTextShown() {
|
|
return _activeSpeech.speechFlags & kSpeakForceText;
|
|
}
|
|
|
|
void saveState(Common::OutSaveFile *out);
|
|
void loadState(Common::InSaveFile *in);
|
|
|
|
void setProtagState(int state);
|
|
int getProtagState() { return _protagState; }
|
|
|
|
void loadActorList(int protagonistIdx, int actorCount, int actorsResourceID,
|
|
int protagStatesCount, int protagStatesResourceID);
|
|
void loadObjList(int objectCount, int objectsResourceID);
|
|
|
|
protected:
|
|
friend class Script;
|
|
void loadActorResources(ActorData *actor);
|
|
void loadFrameList(int frameListResourceId, ActorFrameSequences &frames);
|
|
private:
|
|
void stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped);
|
|
void loadActorSpriteList(ActorData *actor);
|
|
|
|
void drawOrderListAdd(const CommonObjectDataPointer& element, CompareFunction compareFunction);
|
|
void createDrawOrderList();
|
|
bool calcScreenPosition(CommonObjectData *commonObjectData);
|
|
bool getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber, SpriteList *&spriteList);
|
|
|
|
bool followProtagonist(ActorData *actor);
|
|
void findActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint);
|
|
void handleSpeech(int msec);
|
|
void handleActions(int msec, bool setup);
|
|
bool validPathCellPoint(const Point &testPoint) {
|
|
return !((testPoint.x < 0) || (testPoint.x >= _xCellCount) ||
|
|
(testPoint.y < 0) || (testPoint.y >= _yCellCount));
|
|
}
|
|
void setPathCell(const Point &testPoint, int8 value) {
|
|
#ifdef ACTOR_DEBUG
|
|
if (!validPathCellPoint(testPoint)) {
|
|
error("Actor::setPathCell wrong point");
|
|
}
|
|
#endif
|
|
_pathCell[testPoint.x + testPoint.y * _xCellCount] = value;
|
|
}
|
|
int8 getPathCell(const Point &testPoint) {
|
|
#ifdef ACTOR_DEBUG
|
|
if (!validPathCellPoint(testPoint)) {
|
|
error("Actor::getPathCell wrong point");
|
|
}
|
|
#endif
|
|
return _pathCell[testPoint.x + testPoint.y * _xCellCount];
|
|
}
|
|
bool scanPathLine(const Point &point1, const Point &point2);
|
|
int fillPathArray(const Point &fromPoint, const Point &toPoint, Point &bestPoint);
|
|
void setActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint);
|
|
void pathToNode();
|
|
void condenseNodeList();
|
|
void removeNodes();
|
|
void nodeToPath();
|
|
void removePathPoints();
|
|
bool validFollowerLocation(const Location &location);
|
|
void moveDragon(ActorData *actor);
|
|
|
|
|
|
protected:
|
|
//constants
|
|
ActorDataArray _actors;
|
|
|
|
ObjectDataArray _objs;
|
|
|
|
SagaEngine *_vm;
|
|
ResourceContext *_actorContext;
|
|
|
|
int _lastTickMsec;
|
|
CommonObjectOrderList _drawOrderList;
|
|
|
|
//variables
|
|
public:
|
|
ActorData *_centerActor;
|
|
ActorData *_protagonist;
|
|
int _handleActionDiv;
|
|
|
|
Rect _speechBoxScript;
|
|
|
|
StringsTable _objectsStrings;
|
|
StringsTable _actorsStrings;
|
|
|
|
protected:
|
|
SpeechData _activeSpeech;
|
|
int _protagState;
|
|
bool _dragonHunt;
|
|
|
|
private:
|
|
Common::Array<ProtagStateData> _protagStates;
|
|
|
|
//path stuff
|
|
struct PathNode {
|
|
Point point;
|
|
int link;
|
|
|
|
PathNode() : link(0) {}
|
|
PathNode(const Point &p) : point(p), link(0) {}
|
|
PathNode(const Point &p, int l) : point(p), link(l) {}
|
|
};
|
|
typedef Common::Array<PathNode> PathNodeList;
|
|
|
|
Rect _barrierList[ACTOR_BARRIERS_MAX];
|
|
int _barrierCount;
|
|
Common::Array<int8> _pathCell;
|
|
|
|
int _xCellCount;
|
|
int _yCellCount;
|
|
Rect _pathRect;
|
|
|
|
PointList _pathList;
|
|
uint _pathListIndex;
|
|
|
|
PathNodeList _pathNodeList;
|
|
|
|
public:
|
|
#ifdef ACTOR_DEBUG
|
|
#ifndef SAGA_DEBUG
|
|
#error You must also define SAGA_DEBUG
|
|
#endif
|
|
//path debug - use with care
|
|
struct DebugPoint {
|
|
Point point;
|
|
byte color;
|
|
|
|
DebugPoint() : color(0) {}
|
|
|
|
DebugPoint(const Point &p, byte c): point(p), color(c) {}
|
|
};
|
|
|
|
Common::Array<DebugPoint> _debugPoints;
|
|
uint _debugPointsCount;
|
|
// we still need this trick to speedup debug points addition
|
|
void addDebugPoint(const Point &point, byte color) {
|
|
if (_debugPointsCount < _debugPoints.size()) {
|
|
_debugPoints[_debugPointsCount].point = point;
|
|
_debugPoints[_debugPointsCount].color = color;
|
|
} else {
|
|
_debugPoints.push_back(DebugPoint(point, color));
|
|
}
|
|
++_debugPointsCount;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
} // End of namespace Saga
|
|
|
|
#endif
|