mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
dragon wip1
svn-id: r18476
This commit is contained in:
parent
ac071d6470
commit
0a29c11bc9
275
saga/actor.cpp
275
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;
|
||||
|
37
saga/actor.h
37
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
|
||||
|
203
saga/isomap.cpp
203
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;
|
||||
|
@ -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];
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "saga/render.h"
|
||||
#include "saga/events.h"
|
||||
|
||||
#define CURRENT_SAGA_VER 2
|
||||
#define CURRENT_SAGA_VER 3
|
||||
|
||||
namespace Saga {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user