mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
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:
+13
-3
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user