aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorAndrew Kurushin2005-06-29 20:00:44 +0000
committerAndrew Kurushin2005-06-29 20:00:44 +0000
commit0a29c11bc9ba6c0ab84913f0a7b98297d69c10b2 (patch)
treec70541ba160cb1caada1ba6e1e42d44123c0ad8d /saga
parentac071d6470342c71840c8ed0aac661652e126e94 (diff)
downloadscummvm-rg350-0a29c11bc9ba6c0ab84913f0a7b98297d69c10b2.tar.gz
scummvm-rg350-0a29c11bc9ba6c0ab84913f0a7b98297d69c10b2.tar.bz2
scummvm-rg350-0a29c11bc9ba6c0ab84913f0a7b98297d69c10b2.zip
dragon wip1
svn-id: r18476
Diffstat (limited to 'saga')
-rw-r--r--saga/actor.cpp275
-rw-r--r--saga/actor.h37
-rw-r--r--saga/isomap.cpp203
-rw-r--r--saga/isomap.h27
-rw-r--r--saga/saveload.cpp2
5 files changed, 541 insertions, 3 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 12d657e2f2..05aa4a3dd6 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -151,6 +151,26 @@ static const int tileDirectionLUT[8][2] = {
{ 0, 2}
};
+struct DragonMove {
+ uint16 baseFrame;
+ int16 offset[4][2];
+};
+
+static const DragonMove dragonMoveTable[12] = {
+ {0, {{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }}},
+ {0, {{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }}},
+ {0, {{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }}},
+ {0, {{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }}},
+ {28, {{ -0, 0 },{ -1, 6 }, { -5, 11 }, {-10, 15 } }},
+ {56, {{ 0, 0 },{ 1, 6 }, { 5, 11 }, { 10, 15 } }},
+ {40, {{ 0, 0 },{ 6, 1 }, { 11, 5 }, { 15, 10 } }},
+ {44, {{ 0, 0 },{ 6, -1 }, { 11, -5 }, { 15,-10 } }},
+ {32, {{ -0, -0 },{ -6, -1 }, {-11, -5 }, {-15,-10 } }},
+ {52, {{ -0, 0 },{ -6, 1 }, {-11, 5 }, {-15, 10 } }},
+ {36, {{ 0, -0 },{ 1, -6 }, { 5,-11 }, { 10,-15 } }},
+ {48, {{ -0, -0 },{ -1, -6 }, { -5,-11 }, {-10,-15 } }},
+};
+
Actor::Actor(SagaEngine *vm) : _vm(vm) {
int i;
int result;
@@ -267,6 +287,8 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
_protagonist = &dummyActor;
}
+
+ _dragonHunt = true;
}
Actor::~Actor() {
@@ -1381,7 +1403,11 @@ void Actor::drawSpeech(void) {
if (_activeSpeech.actorIds[0] != 0) {
for (i = 0; i < _activeSpeech.actorsCount; i++){
- _vm->textDraw(MEDIUM_FONT_ID, back_buf, outputString, _activeSpeech.speechCoords[i].x, _activeSpeech.speechCoords[i].y, _activeSpeech.speechColor[i], _activeSpeech.outlineColor[i], textDrawFlags);
+ _vm->textDraw(MEDIUM_FONT_ID, back_buf, outputString,
+ _activeSpeech.speechCoords[i].x,
+ _activeSpeech.speechCoords[i].y,
+ _activeSpeech.speechColor[i],
+ _activeSpeech.outlineColor[i], textDrawFlags);
}
} else { // non actors speech
@@ -1850,6 +1876,253 @@ void Actor::abortSpeech() {
_activeSpeech.playingTime = 0;
}
+void Actor::moveDragon(ActorData *actor) {
+ int16 dir0, dir1, dir2, dir3;
+ int16 moveType;
+ EVENT event;
+ const DragonMove *dragonMove;
+
+ if ((actor->actionCycle < 0) ||
+ ((actor->actionCycle == 0) && (actor->dragonMoveType >= ACTOR_DRAGON_TURN_MOVES))) {
+
+ moveType = kDragonMoveInvalid;
+ if (actor->location.distance(_protagonist->location) < 24) {
+ if (_dragonHunt && (_protagonist->currentAction != kActionFall)) {
+ event.type = ONESHOT_EVENT;
+ event.code = SCRIPT_EVENT;
+ event.op = EVENT_EXEC_NONBLOCKING;
+ event.time = 0;
+ event.param = _vm->_scene->getScriptModuleNumber(); // module number
+ event.param2 = ACTOR_EXP_KNOCK_RIF; // script entry point number
+ event.param3 = -1; // Action
+ event.param4 = -1; // Object
+ event.param5 = -1; // With Object
+ event.param6 = -1; // Actor
+
+ _vm->_events->queue(&event);
+ _dragonHunt = FALSE;
+ }
+ } else {
+ _dragonHunt = true;
+ }
+
+ if (actor->walkStepIndex + 2 > actor->walkStepsCount) {
+
+ _vm->_isoMap->findDragonTilePath(actor, actor->location, _protagonist->location, actor->actionDirection);
+
+ if (actor->walkStepsCount == 0) {
+ _vm->_isoMap->findDragonTilePath(actor, actor->location, _protagonist->location, 0);
+ }
+
+ if (actor->walkStepsCount < 2) {
+ return;
+ }
+
+ actor->partialTarget = actor->location;
+ actor->finalTarget = _protagonist->location;
+ actor->walkStepIndex = 0;
+ }
+
+ dir0 = actor->actionDirection;
+ dir1 = actor->tileDirections[actor->walkStepIndex++];
+ dir2 = actor->tileDirections[actor->walkStepIndex];
+ dir3 = actor->tileDirections[actor->walkStepIndex + 1];
+
+ if (dir0 != dir1){
+ actor->actionDirection = dir0 = dir1;
+ }
+
+ actor->location = actor->partialTarget;
+
+ if ((dir1 != dir2) && (dir1 == dir3)) {
+ switch (dir1) {
+ case kDirUpLeft:
+ actor->partialTarget.v() += 16;
+ moveType = kDragonMoveUpLeft;
+ break;
+ case kDirDownLeft:
+ actor->partialTarget.u() -= 16;
+ moveType = kDragonMoveDownLeft;
+ break;
+ case kDirDownRight:
+ actor->partialTarget.v() -= 16;
+ moveType = kDragonMoveDownRight;
+ break;
+ case kDirUpRight:
+ actor->partialTarget.u() += 16;
+ moveType = kDragonMoveUpRight;
+ break;
+ }
+
+ switch (dir2) {
+ case kDirUpLeft:
+ actor->partialTarget.v() += 16;
+ break;
+ case kDirDownLeft:
+ actor->partialTarget.u() -= 16;
+ break;
+ case kDirDownRight:
+ actor->partialTarget.v() -= 16;
+ break;
+ case kDirUpRight:
+ actor->partialTarget.u() += 16;
+ break;
+ }
+
+ actor->walkStepIndex++;
+ } else {
+ switch (dir1) {
+ case kDirUpLeft:
+ actor->partialTarget.v() += 16;
+ switch (dir2) {
+ case kDirDownLeft:
+ moveType = kDragonMoveUpLeft_Left;
+ actor->partialTarget.u() -= 16;
+ break;
+ case kDirUpLeft:
+ moveType = kDragonMoveUpLeft;
+ break;
+ case kDirUpRight:
+ actor->partialTarget.u() += 16;
+ moveType = kDragonMoveUpLeft_Right;
+ break;
+ default:
+ actor->actionDirection = dir1;
+ actor->walkStepsCount = 0;
+ break;
+ }
+ break;
+ case kDirDownLeft:
+ actor->partialTarget.u() -= 16;
+ switch (dir2) {
+ case kDirDownRight:
+ moveType = kDragonMoveDownLeft_Left;
+ actor->partialTarget.v() -= 16;
+ break;
+ case kDirDownLeft:
+ moveType = kDragonMoveDownLeft;
+ break;
+ case kDirUpLeft:
+ moveType = kDragonMoveDownLeft_Right;
+ actor->partialTarget.v() += 16;
+ break;
+ default:
+ actor->actionDirection = dir1;
+ actor->walkStepsCount = 0;
+ break;
+ }
+ break;
+ case kDirDownRight:
+ actor->partialTarget.v() -= 16;
+ switch (dir2) {
+ case kDirUpRight:
+ moveType = kDragonMoveDownRight_Left;
+ actor->partialTarget.u() += 16;
+ break;
+ case kDirDownRight:
+ moveType = kDragonMoveDownRight;
+ break;
+ case kDirDownLeft:
+ moveType = kDragonMoveDownRight_Right;
+ actor->partialTarget.u() -= 16;
+ break;
+ default:
+ actor->actionDirection = dir1;
+ actor->walkStepsCount = 0;
+ break;
+ }
+ break;
+ case kDirUpRight:
+ actor->partialTarget.u() += 16;
+ switch (dir2) {
+ case kDirUpLeft:
+ moveType = kDragonMoveUpRight_Left;
+ actor->partialTarget.v() += 16;
+ break;
+ case kDirUpRight:
+ moveType = kDragonMoveUpRight;
+ break;
+ case kDirDownRight:
+ moveType = kDragonMoveUpRight_Right;
+ actor->partialTarget.v() -= 16;
+ break;
+ default:
+ actor->actionDirection = dir1;
+ actor->walkStepsCount = 0;
+ break;
+ }
+ break;
+
+ default:
+ actor->actionDirection = dir1;
+ actor->walkStepsCount = 0;
+ break;
+ }
+ }
+
+ actor->dragonMoveType = moveType;
+
+ if (moveType >= ACTOR_DRAGON_TURN_MOVES) {
+ actor->dragonStepCycle = 0;
+ actor->actionCycle = 4;
+ actor->walkStepIndex++;
+ } else {
+ actor->actionCycle = 4;
+ }
+ }
+
+ actor->actionCycle--;
+
+ if ((actor->walkStepsCount < 1) || (actor->actionCycle < 0)) {
+ return;
+ }
+
+ if (actor->dragonMoveType < ACTOR_DRAGON_TURN_MOVES) {
+
+ actor->dragonStepCycle++;
+ if (actor->dragonStepCycle >= 7) {
+ actor->dragonStepCycle = 0;
+ }
+
+ actor->dragonBaseFrame = actor->dragonMoveType * 7;
+
+ if (actor->location.u() > actor->partialTarget.u() + 3) {
+ actor->location.u() -= 4;
+ } else {
+ if (actor->location.u() < actor->partialTarget.u() - 3) {
+ actor->location.u() += 4;
+ } else {
+ actor->location.u() = actor->partialTarget.u();
+ }
+ }
+
+
+ if (actor->location.v() > actor->partialTarget.v() + 3) {
+ actor->location.v() -= 4;
+ } else {
+ if (actor->location.v() < actor->partialTarget.v() - 3) {
+ actor->location.v() += 4;
+ } else {
+ actor->location.v() = actor->partialTarget.v();
+ }
+ }
+ } else {
+ dragonMove = &dragonMoveTable[actor->dragonMoveType];
+ actor->dragonBaseFrame = dragonMove->baseFrame;
+
+
+ actor->location.u() = actor->partialTarget.u() - dragonMove->offset[actor->actionCycle][0];
+ actor->location.v() = actor->partialTarget.v() - dragonMove->offset[actor->actionCycle][1];
+
+ actor->dragonStepCycle++;
+ if (actor->dragonStepCycle >= 3) {
+ actor->dragonStepCycle = 3;
+ }
+ }
+
+ actor->frameNumber = actor->dragonBaseFrame + actor->dragonStepCycle;
+}
+
void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint) {
Point iteratorPoint;
Point bestPoint;
diff --git a/saga/actor.h b/saga/actor.h
index 2c5ac3cc5a..8a58431e33 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -63,8 +63,12 @@ class HitZone;
#define ACTOR_SPEECH_STRING_MAX 16 // speech const
#define ACTOR_SPEECH_ACTORS_MAX 8
+#define ACTOR_DRAGON_TURN_MOVES 4
+
#define ACTOR_NO_ENTRANCE -1
+#define ACTOR_EXP_KNOCK_RIF 24
+
#define PATH_NODE_EMPTY -1
enum ActorActions {
@@ -122,6 +126,22 @@ enum PathCellType {
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;
@@ -295,6 +315,10 @@ public:
int16 fallAcceleration;
int16 fallPosition;
+ uint8 dragonBaseFrame;
+ uint8 dragonStepCycle;
+ uint8 dragonMoveType;
+
int32 frameNumber; // current frame number
int32 tileDirectionsAlloced;
@@ -326,6 +350,9 @@ public:
out->writeSint16LE(fallVelocity);
out->writeSint16LE(fallAcceleration);
out->writeSint16LE(fallPosition);
+ out->writeByte(dragonBaseFrame);
+ out->writeByte(dragonStepCycle);
+ out->writeByte(dragonMoveType);
out->writeSint32LE(frameNumber);
out->writeSint32LE(tileDirectionsAlloced);
@@ -367,6 +394,14 @@ public:
} else {
fallVelocity = fallAcceleration = fallPosition = 0;
}
+ if (_vm->getCurrentLoadVersion() > 2) {
+ dragonBaseFrame = in->readByte();
+ dragonStepCycle = in->readByte();
+ dragonMoveType = in->readByte();
+ } else {
+ dragonBaseFrame = dragonStepCycle = dragonMoveType = 0;
+ }
+
frameNumber = in->readSint32LE();
@@ -562,6 +597,7 @@ private:
void nodeToPath();
void removePathPoints();
bool validFollowerLocation(const Location &location);
+ void moveDragon(ActorData *actor);
protected:
@@ -587,6 +623,7 @@ public:
protected:
SpeechData _activeSpeech;
int _protagState;
+ bool _dragonHunt;
private:
//path stuff
diff --git a/saga/isomap.cpp b/saga/isomap.cpp
index ad5cdf1934..dba57939b3 100644
--- a/saga/isomap.cpp
+++ b/saga/isomap.cpp
@@ -897,7 +897,51 @@ void IsoMap::drawTile(SURFACE *ds, uint16 tileIndex, const Point &point, const L
}
-//
+bool IsoMap::checkDragonPoint(int16 u, int16 v, uint16 direction) {
+ DragonPathCell *pathCell;
+
+ if ((u < 1) || (u >= SAGA_DRAGON_SEARCH_DIAMETER - 1) || (v < 1) || (v >= SAGA_DRAGON_SEARCH_DIAMETER - 1)) {
+ return false;
+ }
+
+ pathCell = _dragonSearchArray.getPathCell(u, v);
+
+ if (pathCell->visited) {
+ return false;
+ }
+
+ pathCell->visited = 1;
+ pathCell->direction = direction;
+ return true;
+}
+
+void IsoMap::pushDragonPoint(int16 u, int16 v, uint16 direction) {
+ DragonTilePoint *tilePoint;
+ DragonPathCell *pathCell;
+
+ if ((u < 1) || (u >= SAGA_DRAGON_SEARCH_DIAMETER - 1) || (v < 1) || (v >= SAGA_DRAGON_SEARCH_DIAMETER - 1)) {
+ return;
+ }
+
+ pathCell = _dragonSearchArray.getPathCell(u, v);
+
+ if (pathCell->visited) {
+ return;
+ }
+
+ tilePoint = _dragonSearchArray.getQueue(_queueCount);
+ _queueCount++;
+ if (_queueCount >= SAGA_SEARCH_QUEUE_SIZE) {
+ _queueCount = 0;
+ }
+
+ tilePoint->u = u;
+ tilePoint->v = v;
+ tilePoint->direction = direction;
+
+ pathCell->visited = 1;
+ pathCell->direction = direction;
+}
void IsoMap::pushPoint(int16 u, int16 v, uint16 cost, uint16 direction) {
int16 upper;
@@ -1211,6 +1255,163 @@ void IsoMap::placeOnTileMap(const Location &start, Location &result, int16 dista
result.v() = ((vBase + bestV) << 4) + 8;
}
+void IsoMap::findDragonTilePath(ActorData* actor,const Location &start, const Location &end, uint16 initialDirection) {
+ byte *res;
+ int i;
+ int16 u;
+ int16 v;
+ int16 u1;
+ int16 v1;
+ uint16 dir;
+
+ int16 bestDistance;
+ int16 bestU;
+ int16 bestV;
+
+ int16 uBase;
+ int16 vBase;
+ int16 uFinish;
+ int16 vFinish;
+ DragonPathCell *pcell;
+ IsoTileData *tile;
+ uint16 mask;
+ DragonTilePoint *tilePoint;
+
+ int16 dist;
+ bool first;
+
+ bestDistance = SAGA_DRAGON_SEARCH_DIAMETER;
+ bestU = SAGA_DRAGON_SEARCH_CENTER,
+ bestV = SAGA_DRAGON_SEARCH_CENTER;
+
+ uBase = (start.u() >> 4) - SAGA_DRAGON_SEARCH_CENTER;
+ vBase = (start.v() >> 4) - SAGA_DRAGON_SEARCH_CENTER;
+ uFinish = (end.u() >> 4) - uBase;
+ vFinish = (end.v() >> 4) - vBase;
+
+ _platformHeight = _vm->_actor->_protagonist->location.z / 8;
+
+ memset( &_dragonSearchArray, 0, sizeof(_dragonSearchArray));
+
+ for (u = 0; u < SAGA_DRAGON_SEARCH_CENTER; u++) {
+ for (v = 0; v < SAGA_DRAGON_SEARCH_CENTER; v++) {
+
+ pcell = _dragonSearchArray.getPathCell(u, v);
+
+ u1 = uBase + u;
+ v1 = vBase + v;
+
+ if ((u1 > 127) || (u1 < 48) || (v1 > 127) || (v1 < 0)) {
+ pcell->visited = 1;
+ continue;
+ }
+
+ tile = getTile(u1, v1, _platformHeight );
+ if (tile != NULL) {
+ mask = tile->terrainMask;
+ if ( ((tile->terrainMask != 0) && (tile->GetFGDAttr() >= kTerrBlock)) ||
+ ((tile->terrainMask != 0xFFFF) && (tile->GetBGDAttr() >= kTerrBlock)) ) {
+ pcell->visited = 1;
+ }
+ } else {
+ pcell->visited = 1;
+ }
+ }
+ }
+
+ first = true;
+ _queueCount = _readCount = 0;
+ pushDragonPoint( SAGA_DRAGON_SEARCH_CENTER, SAGA_DRAGON_SEARCH_CENTER, initialDirection);
+
+ while (_queueCount != _readCount) {
+
+ tilePoint = _dragonSearchArray.getQueue(_readCount++);
+ if (_readCount >= SAGA_SEARCH_QUEUE_SIZE) {
+ _readCount = 0;
+ }
+
+
+ dist = ABS(tilePoint->u - uFinish) + ABS(tilePoint->v - vFinish);
+
+ if (dist < bestDistance) {
+
+ bestU = tilePoint->u;
+ bestV = tilePoint->v;
+ bestDistance = dist;
+ if (dist == 0) {
+ break;
+ }
+ }
+
+ switch (tilePoint->direction) {
+ case kDirUpRight:
+ if (checkDragonPoint( tilePoint->u + 1, tilePoint->v + 0, 1)) {
+ pushDragonPoint( tilePoint->u + 2, tilePoint->v + 0, 1);
+ pushDragonPoint( tilePoint->u + 1, tilePoint->v + 1, 7);
+ pushDragonPoint( tilePoint->u + 1, tilePoint->v - 1, 3);
+ }
+ break;
+ case kDirDownRight:
+ if (checkDragonPoint( tilePoint->u + 0, tilePoint->v - 1, 3)) {
+ pushDragonPoint( tilePoint->u + 0, tilePoint->v - 2, 3);
+ pushDragonPoint( tilePoint->u + 1, tilePoint->v - 1, 1);
+ pushDragonPoint( tilePoint->u - 1, tilePoint->v - 1, 5);
+ }
+ break;
+ case kDirDownLeft:
+ if (checkDragonPoint( tilePoint->u - 1, tilePoint->v + 0, 5)) {
+ pushDragonPoint( tilePoint->u - 2, tilePoint->v + 0, 5);
+ pushDragonPoint( tilePoint->u - 1, tilePoint->v - 1, 3);
+ pushDragonPoint( tilePoint->u - 1, tilePoint->v + 1, 7);
+ }
+ break;
+ case kDirUpLeft:
+ if (checkDragonPoint( tilePoint->u + 0, tilePoint->v + 1, 7)) {
+ pushDragonPoint( tilePoint->u + 0, tilePoint->v + 2, 7);
+ pushDragonPoint( tilePoint->u - 1, tilePoint->v + 1, 5);
+ pushDragonPoint( tilePoint->u + 1, tilePoint->v + 1, 1);
+ }
+ break;
+ }
+
+ if (first && (_queueCount == _readCount)) {
+ pushDragonPoint( tilePoint->u + 1, tilePoint->v + 0, 1);
+ pushDragonPoint( tilePoint->u + 0, tilePoint->v - 1, 3);
+ pushDragonPoint( tilePoint->u - 1, tilePoint->v + 0, 5);
+ pushDragonPoint( tilePoint->u + 0, tilePoint->v + 1, 7);
+ }
+ first = false;
+ }
+
+ res = &_pathDirections[SAGA_MAX_PATH_DIRECTIONS];
+ i = 0;
+ while ((bestU != SAGA_DRAGON_SEARCH_CENTER) || (bestV != SAGA_DRAGON_SEARCH_CENTER)) {
+ pcell = _dragonSearchArray.getPathCell(bestU, bestV);
+
+ *--res = pcell->direction;
+ i++;
+ if (i >= SAGA_MAX_PATH_DIRECTIONS) {
+ break;
+ }
+
+ dir = (pcell->direction + 4) & 0x07;
+
+ bestU += normalDirTable[dir].u;
+ bestV += normalDirTable[dir].v;
+ }
+
+/* if (i > 64) {
+ i = 64;
+ }*/
+
+ actor->walkStepsCount = i;
+ if (i) {
+ actor->setTileDirectionsSize(i, false);
+ memcpy(actor->tileDirections, res, i );
+ }
+
+}
+
void IsoMap::findTilePath(ActorData* actor, const Location &start, const Location &end) {
ActorData *other;
int i;
diff --git a/saga/isomap.h b/saga/isomap.h
index 4a23b74f41..0fe11f7861 100644
--- a/saga/isomap.h
+++ b/saga/isomap.h
@@ -53,6 +53,9 @@ namespace Saga {
#define SAGA_SCROLL_LIMIT_Y1 8
#define SAGA_SCROLL_LIMIT_Y2 32
+#define SAGA_DRAGON_SEARCH_CENTER 24
+#define SAGA_DRAGON_SEARCH_DIAMETER (SAGA_DRAGON_SEARCH_CENTER * 2)
+
#define SAGA_SEARCH_CENTER 15
#define SAGA_SEARCH_DIAMETER (SAGA_SEARCH_CENTER * 2)
#define SAGA_SEARCH_QUEUE_SIZE 128
@@ -164,6 +167,7 @@ public:
}
void screenPointToTileCoords(const Point &position, Location &location);
void placeOnTileMap(const Location &start, Location &result, int16 distance, uint16 direction);
+ void findDragonTilePath(ActorData* actor, const Location &start, const Location &end, uint16 initialDirection);
void findTilePath(ActorData* actor, const Location &start, const Location &end);
bool nextTileTarget(ActorData* actor);
void setTileDoorState(int doorNumber, int doorState);
@@ -197,6 +201,8 @@ private:
}
int16 findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH);
void pushPoint(int16 u, int16 v, uint16 cost, uint16 direction);
+ void pushDragonPoint(int16 u, int16 v, uint16 direction);
+ bool checkDragonPoint(int16 u, int16 v, uint16 direction);
void testPossibleDirections(int16 u, int16 v, uint16 terraComp[8], int skipCenter);
IsoTileData *getTile(int16 u, int16 v, int16 z);
@@ -223,6 +229,13 @@ private:
// path finding stuff
uint16 _platformHeight;
+ struct DragonPathCell {
+ uint16 visited:1,direction:3;
+ };
+ struct DragonTilePoint {
+ int8 u, v;
+ uint16 direction:4;
+ };
struct PathCell {
uint16 visited:1,direction:3,cost:12;
};
@@ -234,6 +247,18 @@ public:
};
private:
+ struct DragonSearchArray {
+ DragonPathCell cell[SAGA_DRAGON_SEARCH_DIAMETER][SAGA_DRAGON_SEARCH_DIAMETER];
+ DragonTilePoint queue[SAGA_SEARCH_QUEUE_SIZE];
+ DragonTilePoint *getQueue(uint16 i) {
+ assert(i < SAGA_SEARCH_QUEUE_SIZE);
+ return &queue[i];
+ }
+ DragonPathCell *getPathCell(uint16 u, uint16 v) {
+ assert((u < SAGA_DRAGON_SEARCH_DIAMETER) && (v < SAGA_DRAGON_SEARCH_DIAMETER));
+ return &cell[u][v];
+ }
+ };
struct SearchArray {
PathCell cell[SAGA_SEARCH_DIAMETER][SAGA_SEARCH_DIAMETER];
TilePoint queue[SAGA_SEARCH_QUEUE_SIZE];
@@ -248,7 +273,9 @@ private:
};
int16 _queueCount;
+ int16 _readCount;
SearchArray _searchArray;
+ DragonSearchArray _dragonSearchArray;
byte _pathDirections[SAGA_MAX_PATH_DIRECTIONS];
diff --git a/saga/saveload.cpp b/saga/saveload.cpp
index e062bd0283..88227e43ff 100644
--- a/saga/saveload.cpp
+++ b/saga/saveload.cpp
@@ -38,7 +38,7 @@
#include "saga/render.h"
#include "saga/events.h"
-#define CURRENT_SAGA_VER 2
+#define CURRENT_SAGA_VER 3
namespace Saga {