- added setup of followers position at start of scene
svn-id: r16423
This commit is contained in:
parent
6d966a6e17
commit
e733d05fef
5 changed files with 175 additions and 32 deletions
150
saga/actor.cpp
150
saga/actor.cpp
|
@ -106,6 +106,27 @@ int angleLUT[16][2] = {
|
||||||
{ -98, -237}
|
{ -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) {
|
Actor::Actor(SagaEngine *vm) : _vm(vm) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -272,7 +293,7 @@ void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFl
|
||||||
actor = getActor(objectId);
|
actor = getActor(objectId);
|
||||||
location = actor->location;
|
location = actor->location;
|
||||||
} else {
|
} else {
|
||||||
warning("ObjectId unsupported"); //TODO: do it
|
warning("ObjectId unsupported"); //todo: do it
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -299,24 +320,114 @@ ActorData *Actor::getActor(uint16 actorId) {
|
||||||
return actor;
|
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() {
|
void Actor::updateActorsScene() {
|
||||||
int i;
|
int i, j;
|
||||||
|
int followerDirection;
|
||||||
ActorData *actor;
|
ActorData *actor;
|
||||||
|
ActorLocation tempLocation;
|
||||||
|
ActorLocation possibleLocation;
|
||||||
|
Point delta;
|
||||||
|
|
||||||
_activeSpeech.stringsCount = 0;
|
_activeSpeech.stringsCount = 0;
|
||||||
|
_protagonist = NULL;
|
||||||
|
|
||||||
for (i = 0; i < ACTORCOUNT; i++) {
|
for (i = 0; i < ACTORCOUNT; i++) {
|
||||||
actor = &_actors[i];
|
actor = &_actors[i];
|
||||||
if (actor->flags & (kProtagonist | kFollower)) {
|
if (actor->flags & (kProtagonist | kFollower)) {
|
||||||
actor->sceneNumber = _vm->_scene->currentSceneNumber();
|
actor->sceneNumber = _vm->_scene->currentSceneNumber();
|
||||||
if (actor->flags & kProtagonist) {
|
if (actor->flags & kProtagonist) {
|
||||||
//todo: actor->finalTarget = a->obj.loc;
|
actor->finalTarget = actor->location;
|
||||||
_centerActor = _protagonist = actor;
|
_centerActor = _protagonist = actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (actor->sceneNumber == _vm->_scene->currentSceneNumber())
|
if (actor->sceneNumber == _vm->_scene->currentSceneNumber()) {
|
||||||
actor->actionCycle = (rand() & 7) * 4;
|
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);
|
handleActions(0, true);
|
||||||
|
@ -575,8 +686,18 @@ void Actor::handleActions(int msec, bool setup) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kActionWalkDir:
|
case kActionWalkDir:
|
||||||
debug(9,"kActionWalkDir not implemented");
|
// tiled stuff
|
||||||
//todo: do it
|
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;
|
break;
|
||||||
|
|
||||||
case kActionSpeak:
|
case kActionSpeak:
|
||||||
|
@ -819,11 +940,6 @@ int Actor::drawActors() {
|
||||||
return SUCCESS;
|
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) {
|
bool Actor::followProtagonist(ActorData *actor) {
|
||||||
ActorLocation protagonistLocation;
|
ActorLocation protagonistLocation;
|
||||||
ActorLocation newLocation;
|
ActorLocation newLocation;
|
||||||
|
@ -837,6 +953,7 @@ bool Actor::followProtagonist(ActorData *actor) {
|
||||||
|
|
||||||
actor->flags &= ~(kFaster | kFastest);
|
actor->flags &= ~(kFaster | kFastest);
|
||||||
protagonistLocation = _protagonist->location;
|
protagonistLocation = _protagonist->location;
|
||||||
|
calcActorScreenPosition(_protagonist);
|
||||||
|
|
||||||
if (_vm->_scene->getMode() == SCENE_MODE_ISO) {
|
if (_vm->_scene->getMode() == SCENE_MODE_ISO) {
|
||||||
//todo: it
|
//todo: it
|
||||||
|
@ -863,8 +980,13 @@ bool Actor::followProtagonist(ActorData *actor) {
|
||||||
|
|
||||||
actor->location.delta(protagonistLocation, delta);
|
actor->location.delta(protagonistLocation, delta);
|
||||||
|
|
||||||
calcActorScreenPosition(_protagonist);
|
protagonistBGMaskType = 0;
|
||||||
protagonistBGMaskType = _vm->_scene->getBGMaskType(_protagonist->screenPosition);
|
if (_vm->_scene->isBGMaskPresent()) {
|
||||||
|
if (_vm->_scene->validBGMaskPoint(_protagonist->screenPosition)) {
|
||||||
|
protagonistBGMaskType = _vm->_scene->getBGMaskType(_protagonist->screenPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ((rand() & 0x7) == 0)
|
if ((rand() & 0x7) == 0)
|
||||||
|
|
|
@ -165,6 +165,11 @@ struct ActorLocation {
|
||||||
y += location.y;
|
y += location.y;
|
||||||
z += location.z;
|
z += location.z;
|
||||||
}
|
}
|
||||||
|
void fromScreenPoint(const Point &screenPoint) {
|
||||||
|
x = (screenPoint.x * ACTOR_LMULT);
|
||||||
|
y = (screenPoint.y * ACTOR_LMULT);
|
||||||
|
z = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ActorData {
|
struct ActorData {
|
||||||
|
@ -264,9 +269,6 @@ public:
|
||||||
int drawActors();
|
int drawActors();
|
||||||
void updateActorsScene(); // calls from scene loading to update Actors info
|
void updateActorsScene(); // calls from scene loading to update Actors info
|
||||||
|
|
||||||
void StoA(Point &actorPoint, const Point &screenPoint);
|
|
||||||
|
|
||||||
|
|
||||||
bool actorEndWalk(uint16 actorId, bool recurse);
|
bool actorEndWalk(uint16 actorId, bool recurse);
|
||||||
bool actorWalkTo(uint16 actorId, const ActorLocation &toLocation);
|
bool actorWalkTo(uint16 actorId, const ActorLocation &toLocation);
|
||||||
ActorData *getActor(uint16 actorId);
|
ActorData *getActor(uint16 actorId);
|
||||||
|
@ -310,6 +312,7 @@ private:
|
||||||
void removeNodes();
|
void removeNodes();
|
||||||
void nodeToPath();
|
void nodeToPath();
|
||||||
void removePathPoints();
|
void removePathPoints();
|
||||||
|
bool validFollowerLocation(const ActorLocation &location);
|
||||||
|
|
||||||
int _lastTickMsec;
|
int _lastTickMsec;
|
||||||
SagaEngine *_vm;
|
SagaEngine *_vm;
|
||||||
|
|
|
@ -555,28 +555,27 @@ int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
|
int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
|
||||||
return SUCCESS;
|
// return SUCCESS;
|
||||||
/*
|
|
||||||
int objectNum;
|
int objectNum;
|
||||||
uint16 object_flags = 0;
|
uint16 object_flags = 0;
|
||||||
|
|
||||||
int script_num;
|
int script_num;
|
||||||
Point iactor_pt;
|
ActorLocation location;
|
||||||
|
|
||||||
objectNum = _vm->_scene->_objectMap->hitTest(imousePt);
|
objectNum = _vm->_scene->_objectMap->hitTest(imousePt);
|
||||||
|
|
||||||
if (objectNum == -1) {
|
if (objectNum == -1) {
|
||||||
// Player clicked on empty spot - walk here regardless of verb
|
// Player clicked on empty spot - walk here regardless of verb
|
||||||
_vm->_actor->StoA(iactor_pt, imousePt);
|
location.fromScreenPoint(imousePt);
|
||||||
error("!");
|
|
||||||
|
|
||||||
_vm->_actor->walkTo(1, &iactor_pt, 0, NULL);
|
_vm->_actor->actorWalkTo(ID_PROTAG, location);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
object_flags = _vm->_scene->_objectMap->getFlags(objectNum);
|
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) {
|
if ((script_num = _vm->_scene->_objectMap->getEPNum(objectNum)) != -1) {
|
||||||
// Set active verb in script module
|
// Set active verb in script module
|
||||||
_vm->_script->putWord(4, 4, I_VerbData[_activeVerb].s_verb);
|
_vm->_script->putWord(4, 4, I_VerbData[_activeVerb].s_verb);
|
||||||
|
@ -588,13 +587,12 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not a normal scene object - walk to it as if it weren't there
|
// Not a normal scene object - walk to it as if it weren't there
|
||||||
_vm->_actor->StoA(iactor_pt, imousePt);
|
location.fromScreenPoint(imousePt);
|
||||||
// _vm->_actor->walkTo(1, &iactor_pt, 0, NULL);
|
|
||||||
error("!");
|
|
||||||
|
|
||||||
|
_vm->_actor->actorWalkTo(ID_PROTAG, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;*/
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) {
|
int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) {
|
||||||
|
|
|
@ -46,6 +46,10 @@
|
||||||
|
|
||||||
namespace Saga {
|
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) {
|
Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
|
||||||
GAME_SCENEDESC gs_desc;
|
GAME_SCENEDESC gs_desc;
|
||||||
byte *scene_lut_p;
|
byte *scene_lut_p;
|
||||||
|
@ -372,15 +376,25 @@ int Scene::getBGMaskType(const Point &testPoint) {
|
||||||
return (_bgMask.buf[offset] >> 4) & 0x0f;
|
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) {
|
bool Scene::canWalk(const Point &testPoint) {
|
||||||
int maskType;
|
int maskType;
|
||||||
|
|
||||||
if (!_bgMask.loaded) {
|
if (!_bgMask.loaded) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((testPoint.x < 0) || (testPoint.x >= _bgMask.w) ||
|
if (!validBGMaskPoint(testPoint)) {
|
||||||
(testPoint.y < 0) || (testPoint.y >= _bgMask.h)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
maskType = getBGMaskType(testPoint);
|
maskType = getBGMaskType(testPoint);
|
||||||
return getDoorState(maskType) == 0;
|
return getDoorState(maskType) == 0;
|
||||||
}
|
}
|
||||||
|
@ -487,6 +501,10 @@ int Scene::getDoorState(int doorNumber) {
|
||||||
return _sceneDoors[doorNumber];
|
return _sceneDoors[doorNumber];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::initDoorsState() {
|
||||||
|
memcpy(_sceneDoors, initSceneDoors, SCENE_DOORS_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
int Scene::getInfo(SCENE_INFO *si) {
|
int Scene::getInfo(SCENE_INFO *si) {
|
||||||
assert(_initialized);
|
assert(_initialized);
|
||||||
assert(si != NULL);
|
assert(si != NULL);
|
||||||
|
|
|
@ -234,11 +234,13 @@ class Scene {
|
||||||
return _bgMask.loaded;
|
return _bgMask.loaded;
|
||||||
}
|
}
|
||||||
int getBGMaskType(const Point &testPoint);
|
int getBGMaskType(const Point &testPoint);
|
||||||
|
bool validBGMaskPoint(const Point &testPoint);
|
||||||
bool canWalk(const Point &testPoint);
|
bool canWalk(const Point &testPoint);
|
||||||
bool offscreenPath(Point &testPoint);
|
bool offscreenPath(Point &testPoint);
|
||||||
|
|
||||||
void setDoorState(int doorNumber, int doorState);
|
void setDoorState(int doorNumber, int doorState);
|
||||||
int getDoorState(int doorNumber);
|
int getDoorState(int doorNumber);
|
||||||
|
void initDoorsState();
|
||||||
|
|
||||||
int getBGInfo(SCENE_BGINFO *bginfo);
|
int getBGInfo(SCENE_BGINFO *bginfo);
|
||||||
int getBGPal(PALENTRY **pal);
|
int getBGPal(PALENTRY **pal);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue