From e733d05fefa929f131cd39aed4b1eb935dac40ef Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Tue, 4 Jan 2005 16:10:43 +0000 Subject: - added setup of followers position at start of scene svn-id: r16423 --- saga/actor.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++++++++----- saga/actor.h | 11 ++-- saga/interface.cpp | 20 ++++--- saga/scene.cpp | 24 +++++++-- saga/scene.h | 2 + 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); -- cgit v1.2.3