- added setup of followers position at start of scene

svn-id: r16423
This commit is contained in:
Andrew Kurushin 2005-01-04 16:10:43 +00:00
parent 6d966a6e17
commit e733d05fef
5 changed files with 175 additions and 32 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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) {

View file

@ -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);

View file

@ -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);