mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
partly implemented game objects
svn-id: r16595
This commit is contained in:
parent
b4b2e52df7
commit
0ccf59faee
154
saga/actor.cpp
154
saga/actor.cpp
@ -36,6 +36,7 @@
|
||||
|
||||
#include "saga/actor.h"
|
||||
#include "saga/actordata.h"
|
||||
#include "saga/objectdata.h"
|
||||
#include "saga/stream.h"
|
||||
#include "saga/interface.h"
|
||||
#include "saga/events.h"
|
||||
@ -44,13 +45,15 @@
|
||||
|
||||
namespace Saga {
|
||||
|
||||
static int actorCompare(const ActorDataPointer& actor1, const ActorDataPointer& actor2) {
|
||||
if (actor1->location.y == actor2->location.y) {
|
||||
static int commonObjectCompare(const CommonObjectDataPointer& obj1, const CommonObjectDataPointer& obj2) {
|
||||
if (obj1->location.y == obj2->location.y) {
|
||||
return 0;
|
||||
} else if (actor1->location.y < actor2->location.y) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
if (obj1->location.y < obj2->location.y) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,9 +138,14 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
|
||||
byte *stringsPointer;
|
||||
size_t stringsLength;
|
||||
ActorData *actor;
|
||||
ObjectData *obj;
|
||||
debug(9, "Actor::Actor()");
|
||||
|
||||
_actors = NULL;
|
||||
_actorsCount = 0;
|
||||
|
||||
_objs = NULL;
|
||||
_objsCount = 0;
|
||||
|
||||
#ifdef ACTOR_DEBUG
|
||||
_debugPoints = NULL;
|
||||
@ -185,12 +193,12 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
|
||||
|
||||
if (_vm->getGameType() == GType_ITE) {
|
||||
_actorsCount = ITE_ACTORCOUNT;
|
||||
_actors = (ActorData **)malloc(_actorsCount * sizeof(ActorData *));
|
||||
_actors = (ActorData **)malloc(_actorsCount * sizeof(*_actors));
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i] = new ActorData();
|
||||
actor->actorId = actorIndexToId(i);
|
||||
actor->id = actorIndexToId(i);
|
||||
actor->index = i;
|
||||
debug(9, "init actorId=%d index=%d", actor->actorId, actor->index);
|
||||
debug(9, "init actor id=%d index=%d", actor->id, actor->index);
|
||||
actor->nameIndex = ITE_ActorTable[i].nameIndex;
|
||||
actor->scriptEntrypointNumber = ITE_ActorTable[i].scriptEntrypointNumber;
|
||||
actor->spriteListResourceId = ITE_ActorTable[i].spriteListResourceId;
|
||||
@ -212,9 +220,29 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
|
||||
|
||||
actor->disabled = !loadActorResources(actor);
|
||||
if (actor->disabled) {
|
||||
warning("Disabling actorId=%d index=%d", actor->actorId, actor->index);
|
||||
warning("Disabling actor Id=%d index=%d", actor->id, actor->index);
|
||||
}
|
||||
}
|
||||
_objsCount = ITE_OBJECTCOUNT;
|
||||
_objs = (ObjectData **)malloc(_objsCount * sizeof(*_objs));
|
||||
for (i = 0; i < _objsCount; i++) {
|
||||
obj = _objs[i] = new ObjectData();
|
||||
obj->id = objIndexToId(i);
|
||||
obj->index = i;
|
||||
debug(9, "init obj id=%d index=%d", obj->id, obj->index);
|
||||
obj->nameIndex = ITE_ObjectTable[i].nameIndex;
|
||||
obj->scriptEntrypointNumber = ITE_ObjectTable[i].scriptEntrypointNumber;
|
||||
obj->spriteListResourceId = ITE_ObjectTable[i].spriteListResourceId;
|
||||
obj->sceneNumber = ITE_ObjectTable[i].sceneIndex;
|
||||
obj->interactBits = ITE_ObjectTable[i].interactBits;
|
||||
obj->flags = 0;
|
||||
obj->frameNumber = 0;
|
||||
|
||||
obj->location.x = ITE_ObjectTable[i].x;
|
||||
obj->location.y = ITE_ObjectTable[i].y;
|
||||
obj->location.z = ITE_ObjectTable[i].z;
|
||||
}
|
||||
|
||||
} else {
|
||||
// TODO.
|
||||
static ActorData dummyActor;
|
||||
@ -223,13 +251,13 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
|
||||
dummyActor.walkStepsPoints = NULL;
|
||||
|
||||
_protagonist = &dummyActor;
|
||||
_actorsCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Actor::~Actor() {
|
||||
int i;
|
||||
ActorData *actor;
|
||||
ObjectData *obj;
|
||||
|
||||
debug(9, "Actor::~Actor()");
|
||||
|
||||
@ -248,6 +276,11 @@ Actor::~Actor() {
|
||||
delete actor;
|
||||
}
|
||||
free(_actors);
|
||||
for (i = 0; i < _objsCount; i++) {
|
||||
obj = _objs[i];
|
||||
delete obj;
|
||||
}
|
||||
free(_objs);
|
||||
}
|
||||
|
||||
bool Actor::loadActorResources(ActorData *actor) {
|
||||
@ -354,7 +387,7 @@ void Actor::stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit,
|
||||
}
|
||||
}
|
||||
if (hitZone->getFlags() & kHitZoneExit) {
|
||||
takeExit(actor->actorId, hitZone);
|
||||
takeExit(actor->id, hitZone);
|
||||
} else {
|
||||
if (hitZone->getScriptNumber() > 0) {
|
||||
event.type = ONESHOT_EVENT;
|
||||
@ -432,15 +465,21 @@ void Actor::actorFaceTowardsObject(uint16 actorId, uint16 objectId) {
|
||||
}
|
||||
}
|
||||
|
||||
const char * Actor::getActorName(uint16 actorId) {
|
||||
ActorData *actor;
|
||||
actor = getActor(actorId);
|
||||
return _actorsStrings.getString(actor->nameIndex);
|
||||
|
||||
ObjectData *Actor::getObj(uint16 objId) {
|
||||
ObjectData *obj;
|
||||
|
||||
if (!validObjId(objId))
|
||||
error("Actor::getObj Wrong objId 0x%X", objId);
|
||||
|
||||
obj = _objs[objIdToIndex(objId)];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
ActorData *Actor::getActor(uint16 actorId) {
|
||||
ActorData *actor;
|
||||
|
||||
|
||||
if (!validActorId(actorId))
|
||||
error("Actor::getActor Wrong actorId 0x%X", actorId);
|
||||
|
||||
@ -526,7 +565,7 @@ void Actor::updateActorsScene(int actorsEntrance) {
|
||||
}
|
||||
|
||||
followerDirection = _protagonist->facingDirection + 3;
|
||||
calcActorScreenPosition(_protagonist);
|
||||
calcScreenPosition(_protagonist);
|
||||
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i];
|
||||
@ -731,11 +770,11 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
}
|
||||
|
||||
if (actor->targetObject != ID_NOTHING) {
|
||||
actorFaceTowardsObject(actor->actorId, actor->targetObject);
|
||||
actorFaceTowardsObject(actor->id, actor->targetObject);
|
||||
}
|
||||
|
||||
if (actor->flags & kCycle) {
|
||||
frameRange = getActorFrameRange(actor->actorId, kFrameStand);
|
||||
frameRange = getActorFrameRange(actor->id, kFrameStand);
|
||||
if (frameRange->frameCount > 0) {
|
||||
actor->actionCycle++;
|
||||
actor->actionCycle = (actor->actionCycle) % frameRange->frameCount;
|
||||
@ -749,9 +788,9 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
if ((actor->actionCycle & 3) == 0) {
|
||||
actor->cycleWrap(100);
|
||||
|
||||
frameRange = getActorFrameRange(actor->actorId, kFrameWait);
|
||||
frameRange = getActorFrameRange(actor->id, kFrameWait);
|
||||
if ((frameRange->frameCount < 1 || actor->actionCycle > 33))
|
||||
frameRange = getActorFrameRange(actor->actorId, kFrameStand);
|
||||
frameRange = getActorFrameRange(actor->id, kFrameStand);
|
||||
|
||||
if (frameRange->frameCount) {
|
||||
actor->frameNumber = frameRange->frameIndex + (uint16)rand() % frameRange->frameCount;
|
||||
@ -773,7 +812,7 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
while ((delta.x == 0) && (delta.y == 0)) {
|
||||
|
||||
if (actor->walkStepIndex >= actor->walkStepsCount) {
|
||||
actorEndWalk(actor->actorId, true);
|
||||
actorEndWalk(actor->id, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -829,7 +868,7 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
actor->actionCycle++;
|
||||
}
|
||||
|
||||
frameRange = getActorFrameRange(actor->actorId, actor->walkFrameSequence);
|
||||
frameRange = getActorFrameRange(actor->id, actor->walkFrameSequence);
|
||||
|
||||
if (actor->actionCycle < 0) {
|
||||
actor->actionCycle = frameRange->frameCount - 1;
|
||||
@ -850,7 +889,7 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
actor->location.x += directionLUT[actor->actionDirection][0] * 2;
|
||||
actor->location.y += directionLUT[actor->actionDirection][1] * 2;
|
||||
|
||||
frameRange = getActorFrameRange(actor->actorId, actor->walkFrameSequence);
|
||||
frameRange = getActorFrameRange(actor->id, actor->walkFrameSequence);
|
||||
actor->actionCycle++;
|
||||
actor->cycleWrap(frameRange->frameCount);
|
||||
actor->frameNumber = frameRange->frameIndex + actor->actionCycle;
|
||||
@ -861,16 +900,16 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
actor->actionCycle++;
|
||||
actor->cycleWrap(64);
|
||||
|
||||
frameRange = getActorFrameRange(actor->actorId, kFrameGesture);
|
||||
frameRange = getActorFrameRange(actor->id, kFrameGesture);
|
||||
if (actor->actionCycle >= frameRange->frameCount) {
|
||||
if (actor->actionCycle & 1)
|
||||
break;
|
||||
frameRange = getActorFrameRange(actor->actorId, kFrameSpeak);
|
||||
frameRange = getActorFrameRange(actor->id, kFrameSpeak);
|
||||
|
||||
state = (uint16)rand() % (frameRange->frameCount + 1);
|
||||
|
||||
if (state == 0) {
|
||||
frameRange = getActorFrameRange(actor->actorId, kFrameStand);
|
||||
frameRange = getActorFrameRange(actor->id, kFrameStand);
|
||||
} else {
|
||||
state--;
|
||||
}
|
||||
@ -895,7 +934,7 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
actor->cycleTimeCount = actor->cycleDelay;
|
||||
actor->actionCycle++;
|
||||
|
||||
frameRange = getActorFrameRange(actor->actorId, actor->cycleFrameSequence);
|
||||
frameRange = getActorFrameRange(actor->id, actor->cycleFrameSequence);
|
||||
|
||||
if (actor->currentAction == kActionPongFrames) {
|
||||
if (actor->actionCycle >= frameRange->frameCount * 2 - 2) {
|
||||
@ -988,39 +1027,39 @@ int Actor::direct(int msec) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void Actor::calcActorScreenPosition(ActorData *actor) {
|
||||
void Actor::calcScreenPosition(CommonObjectData *commonObjectData) {
|
||||
int beginSlope, endSlope, middle;
|
||||
if (_vm->_scene->getFlags() & kSceneFlagISO) {
|
||||
//todo: it
|
||||
} else {
|
||||
middle = _vm->getSceneHeight() - actor->location.y / ACTOR_LMULT;
|
||||
middle = _vm->getSceneHeight() - commonObjectData->location.y / ACTOR_LMULT;
|
||||
|
||||
_vm->_scene->getSlopes(beginSlope, endSlope);
|
||||
|
||||
actor->screenDepth = (14 * middle) / endSlope + 1;
|
||||
commonObjectData->screenDepth = (14 * middle) / endSlope + 1;
|
||||
|
||||
if (middle <= beginSlope) {
|
||||
actor->screenScale = 256;
|
||||
commonObjectData->screenScale = 256;
|
||||
} else {
|
||||
if (middle >= endSlope) {
|
||||
actor->screenScale = 1;
|
||||
commonObjectData->screenScale = 1;
|
||||
} else {
|
||||
middle -= beginSlope;
|
||||
endSlope -= beginSlope;
|
||||
actor->screenScale = 256 - (middle * 256) / endSlope;
|
||||
commonObjectData->screenScale = 256 - (middle * 256) / endSlope;
|
||||
}
|
||||
}
|
||||
|
||||
actor->location.toScreenPointXYZ(actor->screenPosition);
|
||||
commonObjectData->location.toScreenPointXYZ(commonObjectData->screenPosition);
|
||||
}
|
||||
|
||||
/*if (actor->index == 2)
|
||||
debug(9, "act: %d. x: %d y: %d", actor->index, actor->screenPosition.x, actor->screenPosition.y);*/
|
||||
}
|
||||
|
||||
|
||||
void Actor::createDrawOrderList() {
|
||||
int i;
|
||||
ActorData *actor;
|
||||
ObjectData *obj;
|
||||
|
||||
_drawOrderList.clear();
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
@ -1028,15 +1067,24 @@ void Actor::createDrawOrderList() {
|
||||
if (actor->disabled) continue;
|
||||
if (actor->sceneNumber != _vm->_scene->currentSceneNumber()) continue;
|
||||
|
||||
_drawOrderList.pushBack(actor, actorCompare);
|
||||
_drawOrderList.pushBack(actor, commonObjectCompare);
|
||||
|
||||
calcActorScreenPosition(actor);
|
||||
calcScreenPosition(actor);
|
||||
}
|
||||
|
||||
for (i = 0; i < _objsCount; i++) {
|
||||
obj = _objs[i];
|
||||
if (obj->sceneNumber != _vm->_scene->currentSceneNumber()) continue;
|
||||
|
||||
_drawOrderList.pushBack(obj, commonObjectCompare);
|
||||
|
||||
calcScreenPosition(obj);
|
||||
}
|
||||
}
|
||||
|
||||
int Actor::drawActors() {
|
||||
ActorOrderList::iterator actorDrawOrderIterator;
|
||||
ActorData *actor;
|
||||
CommonObjectOrderList::iterator drawOrderIterator;
|
||||
CommonObjectDataPointer drawObject;
|
||||
int frameNumber;
|
||||
SpriteList *spriteList;
|
||||
|
||||
@ -1046,30 +1094,30 @@ int Actor::drawActors() {
|
||||
|
||||
createDrawOrderList();
|
||||
|
||||
for (actorDrawOrderIterator = _drawOrderList.begin(); actorDrawOrderIterator != _drawOrderList.end(); ++actorDrawOrderIterator) {
|
||||
actor = actorDrawOrderIterator.operator*();
|
||||
for (drawOrderIterator = _drawOrderList.begin(); drawOrderIterator != _drawOrderList.end(); ++drawOrderIterator) {
|
||||
drawObject = drawOrderIterator.operator*();
|
||||
|
||||
if (_vm->_scene->currentSceneNumber() == RID_ITE_OVERMAP_SCENE) {
|
||||
if (!(actor->flags & kProtagonist)){
|
||||
if (!(drawObject->flags & kProtagonist)){
|
||||
warning("not protagonist");
|
||||
continue;
|
||||
}
|
||||
frameNumber = 8;
|
||||
spriteList = &_vm->_sprite->_mainSprites;
|
||||
} else {
|
||||
frameNumber = actor->frameNumber;
|
||||
spriteList = &actor->spriteList;
|
||||
frameNumber = drawObject->frameNumber;
|
||||
spriteList = &drawObject->spriteList;
|
||||
}
|
||||
|
||||
if ((frameNumber < 0) || (spriteList->spriteCount <= frameNumber)) {
|
||||
warning("Actor::drawActors frameNumber invalid for actorId 0x%X", actor->actorId);
|
||||
warning("Actor::drawActors frameNumber invalid for object id 0x%X", drawObject->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_vm->_scene->getFlags() & kSceneFlagISO) {
|
||||
//todo: it
|
||||
} else {
|
||||
_vm->_sprite->drawOccluded(back_buf, *spriteList, frameNumber, actor->screenPosition, actor->screenScale, actor->screenDepth);
|
||||
_vm->_sprite->drawOccluded(back_buf, *spriteList, frameNumber, drawObject->screenPosition, drawObject->screenScale, drawObject->screenDepth);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1122,7 +1170,7 @@ bool Actor::followProtagonist(ActorData *actor) {
|
||||
|
||||
actor->flags &= ~(kFaster | kFastest);
|
||||
protagonistLocation = _protagonist->location;
|
||||
calcActorScreenPosition(_protagonist);
|
||||
calcScreenPosition(_protagonist);
|
||||
|
||||
if (_vm->_scene->getFlags() & kSceneFlagISO) {
|
||||
//todo: it
|
||||
@ -1192,7 +1240,7 @@ bool Actor::followProtagonist(ActorData *actor) {
|
||||
|
||||
newLocation.x = clamp(-31*4, newLocation.x, (_vm->getDisplayWidth() + 31) * 4); //fixme
|
||||
|
||||
return actorWalkTo(actor->actorId, newLocation);
|
||||
return actorWalkTo(actor->id, newLocation);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -1955,10 +2003,10 @@ void Actor::removePathPoints() {
|
||||
|
||||
|
||||
_newPathNodeListIndex = -1;
|
||||
addNewPathNodeListPoint(_pathNodeList[0].point, _pathNodeList[0].link);
|
||||
addNewPathNodeListPoint(_pathNodeList[0]);
|
||||
|
||||
for (i = 1, node = _pathNodeList + 1; i < _pathNodeListIndex; i++, node++) {
|
||||
addNewPathNodeListPoint(node->point, node->link);
|
||||
addNewPathNodeListPoint(*node);
|
||||
|
||||
for (j = 5; j > 0; j--) {
|
||||
start = node->link - j;
|
||||
@ -1996,7 +2044,7 @@ void Actor::removePathPoints() {
|
||||
}
|
||||
}
|
||||
|
||||
addNewPathNodeListPoint(_pathNodeList[_pathNodeListIndex].point, _pathNodeList[_pathNodeListIndex].link);
|
||||
addNewPathNodeListPoint(_pathNodeList[_pathNodeListIndex]);
|
||||
|
||||
for (i = 0, j = 0; i <= _newPathNodeListIndex; i++) {
|
||||
if (_newPathNodeListIndex == i || (_newPathNodeList[i].point != _newPathNodeList[i+1].point)) {
|
||||
|
117
saga/actor.h
117
saga/actor.h
@ -35,6 +35,7 @@ namespace Saga {
|
||||
|
||||
class HitZone;
|
||||
|
||||
|
||||
#define ACTOR_DEBUG
|
||||
|
||||
#define ACTOR_BARRIERS_MAX 16
|
||||
@ -120,11 +121,6 @@ struct PathDirectionData {
|
||||
int16 y;
|
||||
};
|
||||
|
||||
struct PathNode {
|
||||
Point point;
|
||||
int link;
|
||||
};
|
||||
|
||||
struct ActorFrameRange {
|
||||
int frameIndex;
|
||||
int frameCount;
|
||||
@ -169,28 +165,51 @@ struct Location {
|
||||
}
|
||||
};
|
||||
|
||||
struct ActorData {
|
||||
bool disabled; // Actor disabled in init section
|
||||
int index; // Actor index
|
||||
uint16 actorId; // Actor id
|
||||
int nameIndex; // Actor's index in actor name string list
|
||||
byte speechColor; // Actor dialogue color
|
||||
uint16 flags; // Actor initial flags
|
||||
int scriptEntrypointNumber; // Actor script entrypoint number
|
||||
class CommonObjectData {
|
||||
public:
|
||||
int index; // index in local array
|
||||
uint16 id; // object id
|
||||
uint16 flags; // initial flags
|
||||
int nameIndex; // index in name string list
|
||||
int sceneNumber; // scene
|
||||
int scriptEntrypointNumber; // script entrypoint number
|
||||
|
||||
int sceneNumber; // scene of actor
|
||||
Location location; // Actor's logical coordinates
|
||||
|
||||
Point screenPosition; // Actor's screen coordinates
|
||||
Location location; // logical coordinates
|
||||
Point screenPosition; // screen coordinates
|
||||
int screenDepth; //
|
||||
int screenScale; //
|
||||
|
||||
SpriteList spriteList; // sprite list data
|
||||
int spriteListResourceId; // sprite list resource id
|
||||
|
||||
int frameNumber; // current frame number
|
||||
|
||||
CommonObjectData() {
|
||||
screenDepth = screenScale = 0;
|
||||
flags = 0;
|
||||
frameNumber = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef CommonObjectData *CommonObjectDataPointer;
|
||||
|
||||
typedef SortedList<CommonObjectDataPointer> CommonObjectOrderList;
|
||||
|
||||
class ObjectData: public CommonObjectData {
|
||||
public:
|
||||
uint16 interactBits;
|
||||
};
|
||||
|
||||
class ActorData: public CommonObjectData {
|
||||
public:
|
||||
bool disabled; // Actor disabled in init section
|
||||
byte speechColor; // Actor dialogue color
|
||||
|
||||
uint16 actorFlags; // dynamic flags
|
||||
int currentAction; // ActorActions type
|
||||
int facingDirection; // orientation
|
||||
int actionDirection;
|
||||
int actionCycle;
|
||||
int frameNumber; // current actor frame number
|
||||
uint16 targetObject;
|
||||
const HitZone *lastZone;
|
||||
|
||||
@ -199,9 +218,6 @@ struct ActorData {
|
||||
uint8 cycleTimeCount;
|
||||
uint8 cycleFlags;
|
||||
|
||||
SpriteList spriteList; // Actor's sprite list data
|
||||
int spriteListResourceId; // Actor's sprite list resource id
|
||||
|
||||
ActorFrameSequence *frames; // Actor's frames
|
||||
int framesCount; // Actor's frames count
|
||||
int frameListResourceId; // Actor's frame list resource id
|
||||
@ -242,8 +258,7 @@ struct ActorData {
|
||||
}
|
||||
};
|
||||
|
||||
typedef ActorData *ActorDataPointer;
|
||||
typedef SortedList<ActorDataPointer> ActorOrderList;
|
||||
|
||||
|
||||
struct SpeechData {
|
||||
int speechColor[ACTOR_SPEECH_ACTORS_MAX];
|
||||
@ -270,15 +285,41 @@ class Actor {
|
||||
public:
|
||||
ActorData *_centerActor;
|
||||
ActorData *_protagonist;
|
||||
StringsTable _actorsStrings;
|
||||
|
||||
Actor(SagaEngine *vm);
|
||||
~Actor();
|
||||
|
||||
void cmdActorWalkTo(int argc, const char **argv);
|
||||
|
||||
bool validActorId(uint16 id) { return (id == ID_PROTAG) || ((id > OBJECT_TYPE_MASK) && (id < objectIndexToId(kGameObjectActor, _actorsCount))); }
|
||||
bool validActorId(uint16 id) { return (id == ID_PROTAG) || ((id >= objectIndexToId(kGameObjectActor, 0)) && (id < objectIndexToId(kGameObjectActor, _actorsCount))); }
|
||||
int actorIdToIndex(uint16 id) { return (id == ID_PROTAG ) ? 0 : objectIdToIndex(id); }
|
||||
uint16 actorIndexToId(int index) { return (index == 0 ) ? ID_PROTAG : objectIndexToId(kGameObjectActor, index); }
|
||||
ActorData *getActor(uint16 actorId);
|
||||
|
||||
// clarification: Obj - means game object, such Hat, Spoon etc, Object - means Actor,Obj,HitZone,StepZone
|
||||
|
||||
bool validObjId(uint16 id) { return (id >= objectIndexToId(kGameObjectObject, 0)) && (id < objectIndexToId(kGameObjectObject, _objsCount)); }
|
||||
int objIdToIndex(uint16 id) { return objectIdToIndex(id); }
|
||||
uint16 objIndexToId(int index) { return objectIndexToId(kGameObjectObject, index); }
|
||||
ObjectData *getObj(uint16 objId);
|
||||
|
||||
int getObjectScriptEntrypointNumber(uint16 id) {
|
||||
int objectType;
|
||||
objectType = objectTypeId(id);
|
||||
if (!(objectType & (kGameObjectObject | kGameObjectActor))) {
|
||||
error("Actor::getObjectScriptEntrypointNumber wrong id 0x%X", id);
|
||||
}
|
||||
return (objectType == kGameObjectObject) ? getObj(id)->scriptEntrypointNumber : getActor(id)->scriptEntrypointNumber;
|
||||
}
|
||||
int getObjectFlags(uint16 id) {
|
||||
int objectType;
|
||||
objectType = objectTypeId(id);
|
||||
if (!(objectType & (kGameObjectObject | kGameObjectActor))) {
|
||||
error("Actor::getObjectFlags wrong id 0x%X", id);
|
||||
}
|
||||
return (objectType == kGameObjectObject) ? getObj(id)->flags : getActor(id)->flags;
|
||||
}
|
||||
|
||||
int direct(int msec);
|
||||
int drawActors();
|
||||
@ -288,15 +329,14 @@ public:
|
||||
|
||||
uint16 testHit(const Point& mousePointer){ return ID_NOTHING;}; //TODO: do it
|
||||
void takeExit(uint16 actorId, const HitZone *hitZone);
|
||||
const char * getActorName(uint16 actorId);
|
||||
bool actorEndWalk(uint16 actorId, bool recurse);
|
||||
bool actorWalkTo(uint16 actorId, const Location &toLocation);
|
||||
ActorData *getActor(uint16 actorId);
|
||||
bool actorWalkTo(uint16 actorId, const Location &toLocation);
|
||||
ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType);
|
||||
void realLocation(Location &location, uint16 objectId, uint16 walkFlags);
|
||||
void actorFaceTowardsPoint(uint16 actorId, const Location &toLocation);
|
||||
void actorFaceTowardsObject(uint16 actorId, uint16 objectId);
|
||||
|
||||
void realLocation(Location &location, uint16 objectId, uint16 walkFlags);
|
||||
|
||||
// speech
|
||||
void actorSpeech(uint16 actorId, const char **strings, int stringsCount, uint16 sampleResourceId, int speechFlags);
|
||||
void nonActorSpeech(const char **strings, int stringsCount, int speechFlags);
|
||||
@ -316,7 +356,8 @@ private:
|
||||
void stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped);
|
||||
|
||||
void createDrawOrderList();
|
||||
void calcActorScreenPosition(ActorData *actor);
|
||||
void calcScreenPosition(CommonObjectData *commonObjectData);
|
||||
|
||||
bool followProtagonist(ActorData *actor);
|
||||
void findActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint);
|
||||
void handleSpeech(int msec);
|
||||
@ -350,13 +391,22 @@ private:
|
||||
int _lastTickMsec;
|
||||
SagaEngine *_vm;
|
||||
RSCFILE_CONTEXT *_actorContext;
|
||||
ActorOrderList _drawOrderList;
|
||||
CommonObjectOrderList _drawOrderList;
|
||||
|
||||
int _actorsCount;
|
||||
ActorData **_actors;
|
||||
|
||||
int _objsCount;
|
||||
ObjectData **_objs;
|
||||
|
||||
SpeechData _activeSpeech;
|
||||
StringsTable _actorsStrings;
|
||||
|
||||
//path stuff
|
||||
struct PathNode {
|
||||
Point point;
|
||||
int link;
|
||||
};
|
||||
|
||||
Rect _barrierList[ACTOR_BARRIERS_MAX];
|
||||
int _barrierCount;
|
||||
int8 *_pathCell;
|
||||
@ -413,10 +463,9 @@ private:
|
||||
|
||||
}
|
||||
}
|
||||
void addNewPathNodeListPoint(const Point &point, int link) {
|
||||
void addNewPathNodeListPoint(const PathNode &pathNode) {
|
||||
incrementNewPathNodeListIndex();
|
||||
_newPathNodeList[_newPathNodeListIndex].point = point;
|
||||
_newPathNodeList[_newPathNodeListIndex].link = link;
|
||||
_newPathNodeList[_newPathNodeListIndex] = pathNode;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -529,7 +529,7 @@ void Interface::removeFromInventory(int sprite) {
|
||||
void Interface::drawInventory() {
|
||||
if (_panelMode != kPanelMain)
|
||||
return;
|
||||
|
||||
/*
|
||||
SURFACE *back_buf = _vm->_gfx->getBackBuffer();
|
||||
|
||||
// TODO: Inventory scrolling
|
||||
@ -560,7 +560,7 @@ void Interface::drawInventory() {
|
||||
}
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
int Interface::inventoryTest(const Point& imousePt, int *ibutton) {
|
||||
|
@ -28,7 +28,7 @@
|
||||
namespace Saga {
|
||||
|
||||
|
||||
OBJECTTABLE ObjectTable[OBJECTCOUNT] = {
|
||||
ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT] = {
|
||||
{ 8, 49, 1256, 760, 0, 9, 5, kObjNotFlat }, // Magic Hat
|
||||
{ 9, 52, 1080, 1864, 0, 10, 4, kObjUseWith }, // Berries
|
||||
{ 10, 259, 744, 524, 0, 11, 42, kObjUseWith }, // Card Key
|
||||
|
@ -33,18 +33,20 @@ enum {
|
||||
kObjNotFlat = 0x02
|
||||
};
|
||||
|
||||
struct OBJECTTABLE {
|
||||
struct ObjectTableData {
|
||||
byte nameIndex;
|
||||
int32 sceneIndex;
|
||||
int16 x, y, z;
|
||||
int32 spritelistRn;
|
||||
int16 x;
|
||||
int16 y;
|
||||
int16 z;
|
||||
int32 spriteListResourceId;
|
||||
byte scriptEntrypointNumber;
|
||||
uint16 interactBits;
|
||||
};
|
||||
|
||||
#define OBJECTCOUNT 39
|
||||
#define ITE_OBJECTCOUNT 39
|
||||
|
||||
extern OBJECTTABLE ObjectTable[OBJECTCOUNT];
|
||||
extern ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT];
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -349,40 +349,26 @@ void SagaEngine::loadStrings(StringsTable &stringsTable, const byte *stringsPoin
|
||||
}
|
||||
|
||||
const char *SagaEngine::getObjectName(uint16 objectId) {
|
||||
ActorData *actor;
|
||||
ObjectData *obj;
|
||||
const HitZone *hitZone;
|
||||
switch (objectTypeId(objectId)) {
|
||||
case kGameObjectObject:
|
||||
obj = _actor->getObj(objectId);
|
||||
_script->_mainStrings.getString(obj->nameIndex);
|
||||
break;
|
||||
case kGameObjectActor:
|
||||
return _actor->getActorName(objectId);
|
||||
actor = _actor->getActor(objectId);
|
||||
return _actor->_actorsStrings.getString(actor->nameIndex);
|
||||
break;
|
||||
case kGameObjectHitZone:
|
||||
hitZone = _vm->_scene->_objectMap->getHitZone(objectIdToIndex(objectId));
|
||||
return _vm->_scene->_sceneStrings.getString(hitZone->getNameIndex());
|
||||
}
|
||||
//todo: object name & etc
|
||||
warning("SagaEngine::getObjectName name not found for 0x%X", objectId);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int SagaEngine::getObjectScriptEntrypointNumber(uint16 objectId) {
|
||||
ActorData *actor;
|
||||
switch (objectTypeId(objectId)) {
|
||||
case kGameObjectActor:
|
||||
actor = _vm->_actor->getActor(objectId);
|
||||
return actor->scriptEntrypointNumber;
|
||||
break;
|
||||
}
|
||||
//todo: object name & etc
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SagaEngine::getObjectFlags(uint16 objectId) {
|
||||
ActorData *actor;
|
||||
if (objectTypeId(objectId) == kGameObjectActor) {
|
||||
actor = _vm->_actor->getActor(objectId);
|
||||
return actor->flags;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *SagaEngine::getTextString(int textStringId) {
|
||||
const char *string;
|
||||
int lang = _vm->getFeatures() & GF_LANG_DE ? 1 : 0;
|
||||
|
@ -460,8 +460,6 @@ public:
|
||||
void loadStrings(StringsTable &stringsTable, const byte *stringsPointer, size_t stringsLength);
|
||||
|
||||
const char *getObjectName(uint16 objectId);
|
||||
int getObjectScriptEntrypointNumber(uint16 objectId);
|
||||
int getObjectFlags(uint16 objectId);
|
||||
public:
|
||||
TEXTLIST *textCreateList();
|
||||
void textDestroyList(TEXTLIST *textlist);
|
||||
|
@ -663,8 +663,8 @@ void Script::doVerb() {
|
||||
objectType = objectTypeId(_pendingObject[0]);
|
||||
|
||||
if (_pendingVerb == kVerbGive) {
|
||||
scriptEntrypointNumber = _vm->getObjectScriptEntrypointNumber(_pendingObject[1]);
|
||||
if (_vm->getObjectFlags(_pendingObject[1]) & (kFollower|kProtagonist|kExtended)) {
|
||||
scriptEntrypointNumber = _vm->_actor->getObjectScriptEntrypointNumber(_pendingObject[1]);
|
||||
if (_vm->_actor->getObjectFlags(_pendingObject[1]) & (kFollower|kProtagonist|kExtended)) {
|
||||
scriptModuleNumber = 0;
|
||||
} else {
|
||||
scriptModuleNumber = _vm->_scene->getScriptModuleNumber();
|
||||
@ -686,9 +686,9 @@ void Script::doVerb() {
|
||||
|
||||
} else {
|
||||
if (objectType & (kGameObjectActor | kGameObjectObject)) {
|
||||
scriptEntrypointNumber = _vm->getObjectScriptEntrypointNumber(_pendingObject[0]);
|
||||
scriptEntrypointNumber = _vm->_actor->getObjectScriptEntrypointNumber(_pendingObject[0]);
|
||||
|
||||
if ((objectType == kGameObjectActor) && !(_vm->getObjectFlags(_pendingObject[0]) & (kFollower|kProtagonist|kExtended))) {
|
||||
if ((objectType == kGameObjectActor) && !(_vm->_actor->getObjectFlags(_pendingObject[0]) & (kFollower|kProtagonist|kExtended))) {
|
||||
scriptModuleNumber = _vm->_scene->getScriptModuleNumber();
|
||||
} else {
|
||||
scriptModuleNumber = 0;
|
||||
|
@ -239,6 +239,8 @@ struct ScriptDataBuf {
|
||||
|
||||
class Script {
|
||||
public:
|
||||
StringsTable _mainStrings;
|
||||
|
||||
Script();
|
||||
~Script();
|
||||
|
||||
@ -296,7 +298,7 @@ protected:
|
||||
ScriptData *_currentScript;
|
||||
ScriptDataBuf _dataBuf[SCRIPT_DATABUF_NUM];
|
||||
ScriptThreadList _threadList;
|
||||
StringsTable _mainStrings;
|
||||
|
||||
|
||||
//verb
|
||||
bool _firstObjectSet;
|
||||
|
@ -153,9 +153,12 @@ int Script::sfWait(SCRIPTFUNC_PARAMS) {
|
||||
|
||||
// Script function #2 (0x02)
|
||||
int Script::SF_takeObject(SCRIPTFUNC_PARAMS) {
|
||||
ScriptDataWord param = thread->pop();
|
||||
thread->pop();
|
||||
warning("Not implemented");
|
||||
/* ScriptDataWord param = thread->pop();
|
||||
int index = param & 0x1FFF;
|
||||
|
||||
|
||||
|
||||
if (index >= ARRAYSIZE(ObjectTable)) {
|
||||
return FAILURE;
|
||||
}
|
||||
@ -163,7 +166,7 @@ int Script::SF_takeObject(SCRIPTFUNC_PARAMS) {
|
||||
if (ObjectTable[index].sceneIndex != -1) {
|
||||
ObjectTable[index].sceneIndex = -1;
|
||||
_vm->_interface->addToInventory(index);
|
||||
}
|
||||
}*/
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -171,7 +174,11 @@ int Script::SF_takeObject(SCRIPTFUNC_PARAMS) {
|
||||
// Script function #3 (0x03)
|
||||
// Check if an object is carried.
|
||||
int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) {
|
||||
ScriptDataWord param = thread->pop();
|
||||
/*ScriptDataWord param =*/ thread->pop();
|
||||
warning("Not implemented");
|
||||
thread->retVal = 0;
|
||||
/*
|
||||
|
||||
int index = param & 0x1FFF;
|
||||
|
||||
if (index >= ARRAYSIZE(ObjectTable)) {
|
||||
@ -179,7 +186,7 @@ int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
thread->retVal = (ObjectTable[index].sceneIndex == -1) ? 1 : 0;
|
||||
thread->retVal = (ObjectTable[index].sceneIndex == -1) ? 1 : 0;*/
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -435,9 +442,11 @@ int Script::SF_gotoScene(SCRIPTFUNC_PARAMS) {
|
||||
|
||||
// Script function #17 (0x11)
|
||||
int Script::SF_setObjImage(SCRIPTFUNC_PARAMS) {
|
||||
int16 obj_param = getSWord(thread->pop());
|
||||
error("Not implemented");
|
||||
/* int16 obj_param = getSWord(thread->pop());
|
||||
int16 sprite_param = getSWord(thread->pop());
|
||||
|
||||
|
||||
int index = obj_param & 0x1FFF;
|
||||
|
||||
if (index >= ARRAYSIZE(ObjectTable)) {
|
||||
@ -446,13 +455,15 @@ int Script::SF_setObjImage(SCRIPTFUNC_PARAMS) {
|
||||
|
||||
ObjectTable[index].spritelistRn = sprite_param + 9;
|
||||
_vm->_interface->draw();
|
||||
|
||||
*/
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Script function #18 (0x12)
|
||||
int Script::SF_setObjName(SCRIPTFUNC_PARAMS) {
|
||||
int obj_param = getSWord(thread->pop());
|
||||
error("Not implemented");
|
||||
|
||||
/* int obj_param = getSWord(thread->pop());
|
||||
int name_param = getSWord(thread->pop());
|
||||
|
||||
int index = obj_param & 0x1FFF;
|
||||
@ -461,13 +472,15 @@ int Script::SF_setObjName(SCRIPTFUNC_PARAMS) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
ObjectTable[index].nameIndex = name_param;
|
||||
ObjectTable[index].nameIndex = name_param;*/
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Script function #19 (0x13)
|
||||
int Script::SF_getObjImage(SCRIPTFUNC_PARAMS) {
|
||||
int param = getSWord(thread->pop());
|
||||
error("Not implemented");
|
||||
|
||||
/* int param = getSWord(thread->pop());
|
||||
int index = param & 0x1FFF;
|
||||
|
||||
if (index >= ARRAYSIZE(ObjectTable)) {
|
||||
@ -475,7 +488,7 @@ int Script::SF_getObjImage(SCRIPTFUNC_PARAMS) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
thread->retVal = ObjectTable[index].spritelistRn;
|
||||
thread->retVal = ObjectTable[index].spritelistRn;*/
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -647,7 +660,9 @@ int Script::SF_sceneEq(SCRIPTFUNC_PARAMS) {
|
||||
|
||||
// Script function #32 (0x20)
|
||||
int Script::SF_dropObject(SCRIPTFUNC_PARAMS) {
|
||||
ScriptDataWord obj_param = thread->pop();
|
||||
error("Not implemented");
|
||||
|
||||
/* ScriptDataWord obj_param = thread->pop();
|
||||
ScriptDataWord sprite_param = thread->pop();
|
||||
ScriptDataWord x_param = thread->pop();
|
||||
ScriptDataWord y_param = thread->pop();
|
||||
@ -666,7 +681,7 @@ int Script::SF_dropObject(SCRIPTFUNC_PARAMS) {
|
||||
ObjectTable[index].spritelistRn = 9 + sprite_param;
|
||||
ObjectTable[index].x = x_param;
|
||||
ObjectTable[index].y = y_param;
|
||||
|
||||
*/
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user