- 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}
|
||||
};
|
||||
|
||||
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,8 +980,13 @@ 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)
|
||||
|
|
|
@ -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,6 +312,7 @@ private:
|
|||
void removeNodes();
|
||||
void nodeToPath();
|
||||
void removePathPoints();
|
||||
bool validFollowerLocation(const ActorLocation &location);
|
||||
|
||||
int _lastTickMsec;
|
||||
SagaEngine *_vm;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue