aboutsummaryrefslogtreecommitdiff
path: root/engines/saga/actor.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/saga/actor.h')
-rw-r--r--engines/saga/actor.h778
1 files changed, 778 insertions, 0 deletions
diff --git a/engines/saga/actor.h b/engines/saga/actor.h
new file mode 100644
index 0000000000..74f1abd689
--- /dev/null
+++ b/engines/saga/actor.h
@@ -0,0 +1,778 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
+ *
+ * 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$
+ *
+ */
+
+// 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/list.h"
+#include "saga/saga.h"
+#include "saga/font.h"
+
+namespace Saga {
+
+class HitZone;
+
+
+//#define ACTOR_DEBUG //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_CLIMB_SPEED 8
+
+#define ACTOR_COLLISION_WIDTH 32
+#define ACTOR_COLLISION_HEIGHT 8
+
+#define ACTOR_DIRECTIONS_COUNT 4 // for ActorFrameSequence
+#define ACTOR_DIRECTION_RIGHT 0
+#define ACTOR_DIRECTION_LEFT 1
+#define ACTOR_DIRECTION_BACK 2
+#define ACTOR_DIRECTION_FORWARD 3
+
+#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 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 SpeechFlags {
+ kSpeakNoAnimate = 1,
+ kSpeakAsync = 2,
+ kSpeakSlow = 4
+};
+
+enum ActorFrameTypes {
+ kFrameStand,
+ kFrameWalk,
+ kFrameSpeak,
+ kFrameGive,
+ kFrameGesture,
+ kFrameWait,
+ kFramePickUp,
+ kFrameLook
+};
+
+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];
+};
+
+int pathLine(Point *pointList, 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::MemoryReadStream &stream) {
+ x = stream.readUint16LE();
+ y = stream.readUint16LE();
+ z = stream.readUint16LE();
+ }
+
+ void debugPrint(int debuglevel = 0, const char *loc = "Loc:") const {
+ debug(debuglevel, "%s %d, %d, %d", loc, x, y, z);
+ }
+};
+
+class CommonObjectData {
+public:
+//constant
+ bool _disabled; // disabled in init section
+ 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();
+ }
+};
+
+typedef CommonObjectData *CommonObjectDataPointer;
+
+typedef SortedList<CommonObjectDataPointer> CommonObjectOrderList;
+
+class ObjectData: public CommonObjectData {
+public:
+ //constant
+ uint16 _interactBits;
+ ObjectData() {
+ memset(this, 0, sizeof(*this));
+ }
+};
+
+class ActorData: public CommonObjectData {
+public:
+ //constant
+ SpriteList _spriteList; // sprite list data
+
+ ActorFrameSequence *_frames; // Actor's frames
+ int _framesCount; // Actor's frames count
+ 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
+
+ int32 _tileDirectionsAlloced;
+ byte *_tileDirections;
+
+ int32 _walkStepsAlloced;
+ Point *_walkStepsPoints;
+
+ int32 _walkStepsCount;
+ int32 _walkStepIndex;
+
+ Location _finalTarget;
+ Location _partialTarget;
+ int32 _walkFrameSequence;
+
+public:
+ void saveState(Common::OutSaveFile *out) {
+ int i = 0;
+ CommonObjectData::saveState(out);
+ out->writeUint16LE(_actorFlags);
+ out->writeSint32LE(_currentAction);
+ out->writeSint32LE(_facingDirection);
+ out->writeSint32LE(_actionDirection);
+ out->writeSint32LE(_actionCycle);
+ out->writeUint16LE(_targetObject);
+
+ out->writeSint32LE(_cycleFrameSequence);
+ out->writeByte(_cycleDelay);
+ out->writeByte(_cycleTimeCount);
+ out->writeByte(_cycleFlags);
+ out->writeSint16LE(_fallVelocity);
+ out->writeSint16LE(_fallAcceleration);
+ out->writeSint16LE(_fallPosition);
+ out->writeByte(_dragonBaseFrame);
+ out->writeByte(_dragonStepCycle);
+ out->writeByte(_dragonMoveType);
+ out->writeSint32LE(_frameNumber);
+
+ out->writeSint32LE(_tileDirectionsAlloced);
+ for (i = 0; i < _tileDirectionsAlloced; i++) {
+ out->writeByte(_tileDirections[i]);
+ }
+
+ out->writeSint32LE(_walkStepsAlloced);
+ for (i = 0; i < _walkStepsAlloced; i++) {
+ out->writeSint16LE(_walkStepsPoints[i].x);
+ out->writeSint16LE(_walkStepsPoints[i].y);
+ }
+
+ out->writeSint32LE(_walkStepsCount);
+ out->writeSint32LE(_walkStepIndex);
+ _finalTarget.saveState(out);
+ _partialTarget.saveState(out);
+ out->writeSint32LE(_walkFrameSequence);
+ }
+
+ void loadState(uint32 version, Common::InSaveFile *in) {
+ int i = 0;
+ CommonObjectData::loadState(in);
+ _actorFlags = in->readUint16LE();
+ _currentAction = in->readSint32LE();
+ _facingDirection = in->readSint32LE();
+ _actionDirection = in->readSint32LE();
+ _actionCycle = in->readSint32LE();
+ _targetObject = in->readUint16LE();
+
+ _lastZone = NULL;
+ _cycleFrameSequence = in->readSint32LE();
+ _cycleDelay = in->readByte();
+ _cycleTimeCount = in->readByte();
+ _cycleFlags = in->readByte();
+ if (version > 1) {
+ _fallVelocity = in->readSint16LE();
+ _fallAcceleration = in->readSint16LE();
+ _fallPosition = in->readSint16LE();
+ } else {
+ _fallVelocity = _fallAcceleration = _fallPosition = 0;
+ }
+ if (version > 2) {
+ _dragonBaseFrame = in->readByte();
+ _dragonStepCycle = in->readByte();
+ _dragonMoveType = in->readByte();
+ } else {
+ _dragonBaseFrame = _dragonStepCycle = _dragonMoveType = 0;
+ }
+
+ _frameNumber = in->readSint32LE();
+
+
+ setTileDirectionsSize(in->readSint32LE(), true);
+ for (i = 0; i < _tileDirectionsAlloced; i++) {
+ _tileDirections[i] = in->readByte();
+ }
+
+ setWalkStepsPointsSize(in->readSint32LE(), true);
+ for (i = 0; i < _walkStepsAlloced; i++) {
+ _walkStepsPoints[i].x = in->readSint16LE();
+ _walkStepsPoints[i].y = in->readSint16LE();
+ }
+
+ _walkStepsCount = in->readSint32LE();
+ _walkStepIndex = in->readSint32LE();
+ _finalTarget.loadState(in);
+ _partialTarget.loadState(in);
+ _walkFrameSequence = in->readSint32LE();
+ }
+
+ void setTileDirectionsSize(int size, bool forceRealloc) {
+ if ((size <= _tileDirectionsAlloced) && !forceRealloc) {
+ return;
+ }
+ _tileDirectionsAlloced = size;
+ _tileDirections = (byte*)realloc(_tileDirections, _tileDirectionsAlloced * sizeof(*_tileDirections));
+ }
+
+ void cycleWrap(int cycleLimit) {
+ if (_actionCycle >= cycleLimit)
+ _actionCycle = 0;
+ }
+
+ void setWalkStepsPointsSize(int size, bool forceRealloc) {
+ if ((size <= _walkStepsAlloced) && !forceRealloc) {
+ return;
+ }
+ _walkStepsAlloced = size;
+ _walkStepsPoints = (Point*)realloc(_walkStepsPoints, _walkStepsAlloced * sizeof(*_walkStepsPoints));
+ }
+
+ void addWalkStepPoint(const Point &point) {
+ setWalkStepsPointsSize(_walkStepsCount + 1, false);
+ _walkStepsPoints[_walkStepsCount++] = point;
+ }
+
+ void freeSpriteList() {
+ _spriteList.freeMem();
+ }
+
+ ActorData() {
+ memset(this, 0, sizeof(*this));
+ }
+ ~ActorData() {
+ free(_frames);
+ free(_tileDirections);
+ free(_walkStepsPoints);
+ freeSpriteList();
+ }
+};
+
+
+
+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;
+ }
+ }
+};
+
+
+
+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, _actorsCount))); }
+ 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, _objsCount)); }
+ 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();
+
+ void drawPathTest();
+
+ 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;
+ }
+
+ void saveState(Common::OutSaveFile *out);
+ void loadState(Common::InSaveFile *in);
+
+ void setProtagState(int state);
+ int getProtagState() { return _protagState; }
+
+ void freeActorList();
+ void loadActorList(int protagonistIdx, int actorCount, int actorsResourceID,
+ int protagStatesCount, int protagStatesResourceID);
+ void freeObjList();
+ void loadObjList(int objectCount, int objectsResourceID);
+
+ /*
+ uint16 _currentFrameIndex;
+ void frameTest() {
+ _currentFrameIndex++;
+ }*/
+protected:
+ friend class Script;
+ bool loadActorResources(ActorData *actor);
+
+private:
+ void stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped);
+ void loadActorSpriteList(ActorData *actor);
+
+ 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) {
+ if (!validPathCellPoint(testPoint)) {
+ error("Actor::setPathCell wrong point");
+ }
+ _pathCell[testPoint.x + testPoint.y * _xCellCount] = value;
+ }
+ int8 getPathCell(const Point &testPoint) {
+ if (!validPathCellPoint(testPoint)) {
+ error("Actor::getPathCell wrong point");
+ }
+ 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
+ int _actorsCount;
+ ActorData **_actors;
+
+ int _objsCount;
+ ObjectData **_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:
+ ActorFrameSequence *_protagStates;
+ int _protagStatesCount;
+
+//path stuff
+ struct PathNode {
+ Point point;
+ int link;
+ };
+
+ Rect _barrierList[ACTOR_BARRIERS_MAX];
+ int _barrierCount;
+ int8 *_pathCell;
+
+ int _xCellCount;
+ int _yCellCount;
+ Rect _pathRect;
+
+ PathDirectionData *_pathDirectionList;
+ int _pathDirectionListCount;
+ int _pathDirectionListAlloced;
+ PathDirectionData * addPathDirectionListData() {
+ if (_pathDirectionListCount + 1 >= _pathDirectionListAlloced) {
+ _pathDirectionListAlloced += 100;
+ _pathDirectionList = (PathDirectionData*) realloc(_pathDirectionList, _pathDirectionListAlloced * sizeof(*_pathDirectionList));
+ }
+ return &_pathDirectionList[_pathDirectionListCount++];
+ }
+
+ Point *_pathList;
+ int _pathListIndex;
+ int _pathListAlloced;
+ void addPathListPoint(const Point &point) {
+ ++_pathListIndex;
+ if (_pathListIndex >= _pathListAlloced) {
+ _pathListAlloced += 100;
+ _pathList = (Point*) realloc(_pathList, _pathListAlloced * sizeof(*_pathList));
+
+ }
+ _pathList[_pathListIndex] = point;
+ }
+
+ int _pathNodeListIndex;
+ int _pathNodeListAlloced;
+ PathNode *_pathNodeList;
+ void addPathNodeListPoint(const Point &point) {
+ ++_pathNodeListIndex;
+ if (_pathNodeListIndex >= _pathNodeListAlloced) {
+ _pathNodeListAlloced += 100;
+ _pathNodeList = (PathNode*) realloc(_pathNodeList, _pathNodeListAlloced * sizeof(*_pathNodeList));
+
+ }
+ _pathNodeList[_pathNodeListIndex].point = point;
+ }
+
+ int _newPathNodeListIndex;
+ int _newPathNodeListAlloced;
+ PathNode *_newPathNodeList;
+ void incrementNewPathNodeListIndex() {
+ ++_newPathNodeListIndex;
+ if (_newPathNodeListIndex >= _newPathNodeListAlloced) {
+ _newPathNodeListAlloced += 100;
+ _newPathNodeList = (PathNode*) realloc(_newPathNodeList, _newPathNodeListAlloced * sizeof(*_newPathNodeList));
+
+ }
+ }
+ void addNewPathNodeListPoint(const PathNode &pathNode) {
+ incrementNewPathNodeListIndex();
+ _newPathNodeList[_newPathNodeListIndex] = pathNode;
+ }
+
+public:
+#ifdef ACTOR_DEBUG
+//path debug - use with care
+ struct DebugPoint {
+ Point point;
+ byte color;
+ };
+ DebugPoint *_debugPoints;
+ int _debugPointsCount;
+ int _debugPointsAlloced;
+ void addDebugPoint(const Point &point, byte color) {
+ if (_debugPointsCount + 1 > _debugPointsAlloced) {
+ _debugPointsAlloced += 1000;
+ _debugPoints = (DebugPoint*) realloc(_debugPoints, _debugPointsAlloced * sizeof(*_debugPoints));
+ }
+ _debugPoints[_debugPointsCount].color = color;
+ _debugPoints[_debugPointsCount++].point = point;
+ }
+#endif
+};
+
+inline int16 quickDistance(const Point &point1, const Point &point2) {
+ Point delta;
+ delta.x = ABS(point1.x - point2.x) / 2;
+ delta.y = ABS(point1.y - point2.y);
+ return ((delta.x < delta.y) ? (delta.y + delta.x / 2) : (delta.x + delta.y / 2));
+}
+} // End of namespace Saga
+
+#endif