SCUMM: Fix o5_faceActor() implementation for v4 and below

Fixes #5312.
Verified from the disasms of MANIAC v2, INDY3 v3 and LOOM v4.
This commit is contained in:
AndywinXp
2022-07-27 15:03:36 +02:00
parent a5c0b044c6
commit c108dc2646
3 changed files with 50 additions and 6 deletions
+13 -3
View File
@@ -1524,7 +1524,7 @@ void Actor::setDirection(int direction) {
// For versions 1 to 6 we need to store the direction info in the frame array (like
// the original interpreters do). I haven't found any signs that v7/8 require it, though.
// I haven't checked HE, but since it uses the same AKOS costumes as v7/8 I leave that
// as it is...
// as it is...
if ((vald & 3) == newDirToOldDir(_facing)) {
// v1/2 skip the frame only if everything is equal...
if (_vm->_game.version > 2 || (vald >> 2) == _frame)
@@ -1567,7 +1567,7 @@ void Actor_v0::setDirection(int direction) {
}
void Actor::faceToObject(int obj) {
int x2, y2, dir;
int x2, y2, dir, width;
if (!isInCurrentRoom())
return;
@@ -1575,7 +1575,17 @@ void Actor::faceToObject(int obj) {
if (_vm->getObjectOrActorXY(obj, x2, y2) == -1)
return;
dir = (x2 > _pos.x) ? 90 : 270;
if (_vm->_game.version > 4) {
dir = (x2 > _pos.x) ? 90 : 270;
} else {
_vm->getObjectOrActorWidth(obj, width);
dir = _pos.x < x2;
if (abs(_pos.x - x2) < width / 2)
dir = (_pos.y > y2) + 2;
dir = oldDirToNewDir(dir);
}
turnToDirection(dir);
}
+32 -1
View File
@@ -368,6 +368,37 @@ int ScummEngine::whereIsObject(int object) const {
return WIO_NOT_FOUND;
}
int ScummEngine::getObjectOrActorWidth(int object, int &width) {
Actor *act;
if (objIsActor(object)) {
act = derefActorSafe(objToActor(object), "getObjectOrActorWidth");
if (act && act->isInCurrentRoom()) {
width = act->_width;
return 0;
} else
return -1;
}
switch (whereIsObject(object)) {
case WIO_NOT_FOUND:
return -1;
case WIO_INVENTORY:
if (objIsActor(_objectOwnerTable[object])) {
act = derefActor(_objectOwnerTable[object], "getObjectOrActorWidth(2)");
if (act && act->isInCurrentRoom()) {
width = act->_width;
return 0;
}
}
return -1;
default:
break;
}
getObjectWidth(object, width);
return 0;
}
int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
Actor *act;
@@ -405,7 +436,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
* Return the position of an object.
* Returns X, Y and direction in angles
*/
void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir, int &width) {
int idx = getObjectIndex(object);
assert(idx >= 0);
ObjectData &od = _objs[idx];
+5 -2
View File
@@ -849,8 +849,10 @@ protected:
virtual int actorToObj(int actor);
int getObjX(int obj);
int getObjY(int obj);
void getObjectXYPos(int object, int &x, int &y) { int dir; getObjectXYPos(object, x, y, dir); }
void getObjectXYPos(int object, int &x, int &y, int &dir);
void getObjectWidth(int object, int &width) { int x, y, dir; getObjectXYPos(object, x, y, dir, width); }
void getObjectXYPos(int object, int &x, int &y) { int dir, width; getObjectXYPos(object, x, y, dir, width); }
void getObjectXYPos(int object, int &x, int &y, int &dir) { int width; getObjectXYPos(object, x, y, dir, width); }
void getObjectXYPos(int object, int &x, int &y, int &dir, int &width);
int getObjOldDir(int obj);
int getObjNewDir(int obj);
int getObjectIndex(int object) const;
@@ -859,6 +861,7 @@ protected:
int findObject(int x, int y);
void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
public:
int getObjectOrActorWidth(int object, int &width); // Used in v4 and below
int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public
int getDist(int x, int y, int x2, int y2); // Also used in actor.cpp
protected: