aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin2005-01-04 16:10:43 +0000
committerAndrew Kurushin2005-01-04 16:10:43 +0000
commite733d05fefa929f131cd39aed4b1eb935dac40ef (patch)
tree36743fbcc72fa8625aa6ac271966a13471c4107b
parent6d966a6e17900a865b3617515638f55f67031c4f (diff)
downloadscummvm-rg350-e733d05fefa929f131cd39aed4b1eb935dac40ef.tar.gz
scummvm-rg350-e733d05fefa929f131cd39aed4b1eb935dac40ef.tar.bz2
scummvm-rg350-e733d05fefa929f131cd39aed4b1eb935dac40ef.zip
- added setup of followers position at start of scene
svn-id: r16423
-rw-r--r--saga/actor.cpp150
-rw-r--r--saga/actor.h11
-rw-r--r--saga/interface.cpp20
-rw-r--r--saga/scene.cpp24
-rw-r--r--saga/scene.h2
5 files changed, 175 insertions, 32 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 42eaf5ca2a..5f14b79a98 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -106,6 +106,27 @@ int angleLUT[16][2] = {
{ -98, -237}
};
+int directionLUT[8][2] = {
+ { 0*2, -2*2},
+ { 2*2, -1*2},
+ { 3*2, 0*2},
+ { 2*2, 1*2},
+ { 0*2, 2*2},
+ {-2*2, 1*2},
+ {-4*2, 0*2},
+ {-2*2, -1*2}
+};
+
+int tileDirectionLUT[8][2] = {
+ { 1, 1},
+ { 2, 0},
+ { 1, -1},
+ { 0, -2},
+ {-1, -1},
+ {-2, 0},
+ {-1, 1},
+ { 0, 2}
+};
Actor::Actor(SagaEngine *vm) : _vm(vm) {
int i;
@@ -272,7 +293,7 @@ void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFl
actor = getActor(objectId);
location = actor->location;
} else {
- warning("ObjectId unsupported"); //TODO: do it
+ warning("ObjectId unsupported"); //todo: do it
}
}
@@ -299,24 +320,114 @@ ActorData *Actor::getActor(uint16 actorId) {
return actor;
}
+bool Actor::validFollowerLocation(const ActorLocation &location) {
+ Point point;
+ point.x = location.x / ACTOR_LMULT;
+ point.y = location.y / ACTOR_LMULT;
+
+ if ((point.x < 5) || (point.x >= _vm->getDisplayWidth() - 5) ||
+ (point.y < 0) || (point.y >= _vm->getStatusYOffset())) {
+ return false;
+ }
+
+ return (_vm->_scene->canWalk(point));
+}
+
void Actor::updateActorsScene() {
- int i;
+ int i, j;
+ int followerDirection;
ActorData *actor;
+ ActorLocation tempLocation;
+ ActorLocation possibleLocation;
+ Point delta;
_activeSpeech.stringsCount = 0;
+ _protagonist = NULL;
for (i = 0; i < ACTORCOUNT; i++) {
actor = &_actors[i];
if (actor->flags & (kProtagonist | kFollower)) {
actor->sceneNumber = _vm->_scene->currentSceneNumber();
if (actor->flags & kProtagonist) {
-//todo: actor->finalTarget = a->obj.loc;
+ actor->finalTarget = actor->location;
_centerActor = _protagonist = actor;
}
-
}
- if (actor->sceneNumber == _vm->_scene->currentSceneNumber())
+ if (actor->sceneNumber == _vm->_scene->currentSceneNumber()) {
actor->actionCycle = (rand() & 7) * 4;
+ }
+ }
+
+ assert(_protagonist);
+
+/* setup protagonist entry
+ // tiled stuff
+ if (_vm->_scene->getMode() == SCENE_MODE_ISO) {
+ //todo: it
+ } else {
+ }
+*/
+ _protagonist->currentAction = kActionWait;
+
+ if (_vm->_scene->getMode() == SCENE_MODE_ISO) {
+ //todo: it
+ } else {
+ _vm->_scene->initDoorsState();
+ }
+
+ followerDirection = _protagonist->facingDirection + 3;
+ calcActorScreenPosition(_protagonist);
+
+ for (i = 0; i < ACTORCOUNT; i++) {
+ actor = &_actors[i];
+ if (actor->flags & (kFollower)) {
+ actor->facingDirection = actor->actionDirection = _protagonist->facingDirection;
+ actor->currentAction = kActionWait;
+ actor->walkStepsCount = actor->walkStepIndex = 0;
+ actor->location.z = _protagonist->location.z;
+
+
+ if (_vm->_scene->getMode() == SCENE_MODE_ISO) {
+ //todo: it
+ } else {
+ followerDirection &= 0x07;
+
+ possibleLocation = _protagonist->location;
+
+
+ delta.x = directionLUT[followerDirection][0];
+ delta.y = directionLUT[followerDirection][1];
+
+
+ for (j = 0; j < 30; j++) {
+ tempLocation = possibleLocation;
+ tempLocation.x += delta.x;
+ tempLocation.y += delta.y;
+
+ if (validFollowerLocation( tempLocation)) {
+ possibleLocation = tempLocation;
+ } else {
+ tempLocation = possibleLocation;
+ tempLocation.x += delta.x;
+ if (validFollowerLocation( tempLocation)) {
+ possibleLocation = tempLocation;
+ } else {
+ tempLocation = possibleLocation;
+ tempLocation.y += delta.y;
+ if (validFollowerLocation( tempLocation)) {
+ possibleLocation = tempLocation;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ actor->location = possibleLocation;
+ }
+ followerDirection += 2;
+ }
+
}
handleActions(0, true);
@@ -575,8 +686,18 @@ void Actor::handleActions(int msec, bool setup) {
break;
case kActionWalkDir:
- debug(9,"kActionWalkDir not implemented");
- //todo: do it
+ // tiled stuff
+ if (_vm->_scene->getMode() == SCENE_MODE_ISO) {
+ //todo: it
+ } else {
+ actor->location.x += directionLUT[actor->actionDirection][0] * 2;
+ actor->location.y += directionLUT[actor->actionDirection][1] * 2;
+
+ frameRange = getActorFrameRange(actor->actorId, actor->walkFrameSequence);
+ actor->actionCycle++;
+ actor->cycleWrap(frameRange->frameCount);
+ actor->frameNumber = frameRange->frameIndex + actor->actionCycle;
+ }
break;
case kActionSpeak:
@@ -819,11 +940,6 @@ int Actor::drawActors() {
return SUCCESS;
}
-void Actor::StoA(Point &actorPoint, const Point &screenPoint) {
- actorPoint.x = (screenPoint.x * ACTOR_LMULT);
- actorPoint.y = (screenPoint.y * ACTOR_LMULT);
-}
-
bool Actor::followProtagonist(ActorData *actor) {
ActorLocation protagonistLocation;
ActorLocation newLocation;
@@ -837,6 +953,7 @@ bool Actor::followProtagonist(ActorData *actor) {
actor->flags &= ~(kFaster | kFastest);
protagonistLocation = _protagonist->location;
+ calcActorScreenPosition(_protagonist);
if (_vm->_scene->getMode() == SCENE_MODE_ISO) {
//todo: it
@@ -863,9 +980,14 @@ bool Actor::followProtagonist(ActorData *actor) {
actor->location.delta(protagonistLocation, delta);
- calcActorScreenPosition(_protagonist);
- protagonistBGMaskType = _vm->_scene->getBGMaskType(_protagonist->screenPosition);
+ protagonistBGMaskType = 0;
+ if (_vm->_scene->isBGMaskPresent()) {
+ if (_vm->_scene->validBGMaskPoint(_protagonist->screenPosition)) {
+ protagonistBGMaskType = _vm->_scene->getBGMaskType(_protagonist->screenPosition);
+ }
+ }
+
if ((rand() & 0x7) == 0)
actor->actorFlags &= ~kActorNoFollow;
diff --git a/saga/actor.h b/saga/actor.h
index 34496de31a..0f8313018e 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -165,6 +165,11 @@ struct ActorLocation {
y += location.y;
z += location.z;
}
+ void fromScreenPoint(const Point &screenPoint) {
+ x = (screenPoint.x * ACTOR_LMULT);
+ y = (screenPoint.y * ACTOR_LMULT);
+ z = 0;
+ }
};
struct ActorData {
@@ -264,9 +269,6 @@ public:
int drawActors();
void updateActorsScene(); // calls from scene loading to update Actors info
- void StoA(Point &actorPoint, const Point &screenPoint);
-
-
bool actorEndWalk(uint16 actorId, bool recurse);
bool actorWalkTo(uint16 actorId, const ActorLocation &toLocation);
ActorData *getActor(uint16 actorId);
@@ -310,7 +312,8 @@ private:
void removeNodes();
void nodeToPath();
void removePathPoints();
-
+ bool validFollowerLocation(const ActorLocation &location);
+
int _lastTickMsec;
SagaEngine *_vm;
RSCFILE_CONTEXT *_actorContext;
diff --git a/saga/interface.cpp b/saga/interface.cpp
index 77fa34b6fe..ae4ba581da 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -555,28 +555,27 @@ int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) {
}
int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
- return SUCCESS;
-/*
+// return SUCCESS;
+
int objectNum;
uint16 object_flags = 0;
int script_num;
- Point iactor_pt;
+ ActorLocation location;
objectNum = _vm->_scene->_objectMap->hitTest(imousePt);
if (objectNum == -1) {
// Player clicked on empty spot - walk here regardless of verb
- _vm->_actor->StoA(iactor_pt, imousePt);
- error("!");
+ location.fromScreenPoint(imousePt);
- _vm->_actor->walkTo(1, &iactor_pt, 0, NULL);
+ _vm->_actor->actorWalkTo(ID_PROTAG, location);
return SUCCESS;
}
object_flags = _vm->_scene->_objectMap->getFlags(objectNum);
- if (object_flags & OBJECT_EXIT) { // FIXME. This is wrong
+ if (object_flags & kHitZoneExit) { // FIXME. This is wrong
if ((script_num = _vm->_scene->_objectMap->getEPNum(objectNum)) != -1) {
// Set active verb in script module
_vm->_script->putWord(4, 4, I_VerbData[_activeVerb].s_verb);
@@ -588,13 +587,12 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
}
} else {
// Not a normal scene object - walk to it as if it weren't there
- _vm->_actor->StoA(iactor_pt, imousePt);
-// _vm->_actor->walkTo(1, &iactor_pt, 0, NULL);
- error("!");
+ location.fromScreenPoint(imousePt);
+ _vm->_actor->actorWalkTo(ID_PROTAG, location);
}
- return SUCCESS;*/
+ return SUCCESS;
}
int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) {
diff --git a/saga/scene.cpp b/saga/scene.cpp
index 68cfb0c24e..18b3e42a4b 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -46,6 +46,10 @@
namespace Saga {
+static int initSceneDoors[SCENE_DOORS_MAX] = {
+0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
GAME_SCENEDESC gs_desc;
byte *scene_lut_p;
@@ -372,15 +376,25 @@ int Scene::getBGMaskType(const Point &testPoint) {
return (_bgMask.buf[offset] >> 4) & 0x0f;
}
+bool Scene::validBGMaskPoint(const Point &testPoint) {
+ if (!_bgMask.loaded) {
+ error("Scene::validBGMaskPoint _bgMask not loaded");
+ }
+
+ return !((testPoint.x < 0) || (testPoint.x >= _bgMask.w) ||
+ (testPoint.y < 0) || (testPoint.y >= _bgMask.h));
+}
+
bool Scene::canWalk(const Point &testPoint) {
int maskType;
+
if (!_bgMask.loaded) {
return true;
}
- if ((testPoint.x < 0) || (testPoint.x >= _bgMask.w) ||
- (testPoint.y < 0) || (testPoint.y >= _bgMask.h)) {
+ if (!validBGMaskPoint(testPoint)) {
return true;
- }
+ }
+
maskType = getBGMaskType(testPoint);
return getDoorState(maskType) == 0;
}
@@ -487,6 +501,10 @@ int Scene::getDoorState(int doorNumber) {
return _sceneDoors[doorNumber];
}
+void Scene::initDoorsState() {
+ memcpy(_sceneDoors, initSceneDoors, SCENE_DOORS_MAX);
+}
+
int Scene::getInfo(SCENE_INFO *si) {
assert(_initialized);
assert(si != NULL);
diff --git a/saga/scene.h b/saga/scene.h
index e66a4fdea8..a5679fb468 100644
--- a/saga/scene.h
+++ b/saga/scene.h
@@ -234,11 +234,13 @@ class Scene {
return _bgMask.loaded;
}
int getBGMaskType(const Point &testPoint);
+ bool validBGMaskPoint(const Point &testPoint);
bool canWalk(const Point &testPoint);
bool offscreenPath(Point &testPoint);
void setDoorState(int doorNumber, int doorState);
int getDoorState(int doorNumber);
+ void initDoorsState();
int getBGInfo(SCENE_BGINFO *bginfo);
int getBGPal(PALENTRY **pal);