diff options
author | Andrew Kurushin | 2005-06-29 20:00:44 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-06-29 20:00:44 +0000 |
commit | 0a29c11bc9ba6c0ab84913f0a7b98297d69c10b2 (patch) | |
tree | c70541ba160cb1caada1ba6e1e42d44123c0ad8d /saga | |
parent | ac071d6470342c71840c8ed0aac661652e126e94 (diff) | |
download | scummvm-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.cpp | 275 | ||||
-rw-r--r-- | saga/actor.h | 37 | ||||
-rw-r--r-- | saga/isomap.cpp | 203 | ||||
-rw-r--r-- | saga/isomap.h | 27 | ||||
-rw-r--r-- | saga/saveload.cpp | 2 |
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 { |