Opened 17 years ago

Closed 17 years ago

Last modified 13 months ago

#8179 closed patch (outdated)

CMI: The actor placement bug (don't apply)

Reported by: eriktorbjorn Owned by: fingolfin
Priority: normal Component: Engine: SCUMM
Keywords: Cc:
Game: Monkey Island 3

Description

I'm told my patch doesn't match the original
interpreter at all, so this should not be applied. Not
without a discussion, at least. Still, I thought it'd
be a good idea to write down what's currently known
about the actor placement bug in CMI.

In some rooms Guybrush is positioned incorrectly the
first time he enters, but not on subsequent visits.
This happens in at least two places, but I'll be using
the cannibal village as an example.

The reason it behaves differently the first time is
that the game plays a "mini-cutscene". Guybrush walks
to the center of the village and makes a remark about
it being deserted. The decision is made in
roomobj-53-873.dmp. I haven't verified this, but my
guess is that this is the object representing the
village on the overhead map:

[001A] (65) if (ifClassOfIs(873,[22])) {
[002F] (89) setClassOf?(873,[150])
[003F] (79) startScriptEx(0,329,[])
[0053] (66) } else {
[004F] (9E) loadRoomWithEgo(896,280,455)
[0064] (**) }

The loadRoomWithEgo() opcode provides startScene() with
both an actor and an object number, ensuring that
Guybrush is placed near some object - the entrance
gate, I guess - when the room is loaded. Obviously
script 329 will have to do the same, but it does so in
a different fashion:

[011B] (AC) initActor(1)
[0122] (AC) setActorDirection(135)
[0129] (A2) putActorAtObject(1,896)
[0134] (8D) actorFollowCamera(1)

It's not immediately obvious, but it's actually
actorFollowCamera() that causes startScene() to be
called. Since it provides neither actor nor object
number, it's reasonable to assume that
iputActorAtObject() that's responsible for placing
Guybrush at the right position. Indeed, this function
has access to all the information needed to do so:
actor, room and object number.

However, it will only be able to place Guybrush
correctly if whereIsObject(obj) != WIO_NOT_FOUND. If
not, it will fall back on a default position.

I don't know enough to change the behaviour of
whereIsObject(), but it will work if I ensure that the
room is loaded before the function is called. That's
what this patch does but, as I already said, I'm told
this is not the original behaviour.

Also, I have no idea how this affects V6/V7 games. Even
if we do use this solution, it may be that we need a
new function, o8_putActorAtObject().

Ticket imported from: #692781. Ticket imported from: patches/284.

Attachments (2)

cmi-actor-placement.diff (697 bytes ) - added by eriktorbjorn 17 years ago.
Patch against a February 24 CVS snapshot
cmi-actor-placement2.diff (1.0 KB ) - added by eriktorbjorn 17 years ago.
Patch against an April 2 CVS snapshot

Download all attachments as: .zip

Change History (12)

by eriktorbjorn, 17 years ago

Attachment: cmi-actor-placement.diff added

Patch against a February 24 CVS snapshot

comment:1 by fingolfin, 17 years ago

This does seem kind of hackish, and definitly should be made V8 specific, should we choose to go with this workaround.

More research using disassmbly would be nice. Endy seems to be not availble currently, but maybe aquadran can help?

comment:2 by fingolfin, 17 years ago

Owner: set to aquadran

comment:3 by aquadran, 17 years ago

it's from comi idb:
second stack argument is actor

commands_O_PUT_ACTOR_AT_OBJECT() {
object = pop();
actor = pop();
if (objects_FindObjectType(object) != 0) {
x = objects_GetObjectUsePos(object);
y = dx; from objects_GetObjectUsePos()
} else {
x = 160;
y = 120;
}
actors_PutActorAt(actor, x, y, objects_GetObjectRoom
(object));
}

comment:4 by eriktorbjorn, 17 years ago

Well, that change does put Guybrush in a much more
reasonable spot when the room is loaded. I'll have to
compare it with the original and to my patch to see where
they put him. It *could* be a scripting bug in the original...

(Another place where this happens is the first time you find
Elaine after arriving on Blood Island, but that too looks
much more reasonable now.)

by eriktorbjorn, 17 years ago

Attachment: cmi-actor-placement2.diff added

Patch against an April 2 CVS snapshot

comment:5 by eriktorbjorn, 17 years ago

I've compared ScummVM's behaviour to the original, and with
Aquadran's recent change the actor placement is close enough
that I can't tell the difference between them.

I still think it's odd that this opcode is called before the
room is loaded, but I guess that's a scripting bug. Question
is, should we attempt to "fix" it, or should we keep it the
way it is? I've attached a third, somewhat hacky, patch that
uses the "right" coordinates without loading the room, but
that's just to cover all options. I could argue both for and
against all three possibilities.

Just remember to update the CMI issues page when this patch
is finally closed.

comment:6 by fingolfin, 17 years ago

Owner: changed from aquadran to SF/ender

comment:7 by fingolfin, 17 years ago

It might indeed just be a script bug. I have no way to "compare with the original", thus, I have to trust you guys :-)

I guess this can be closed. assigning to Endy, in case he has another opinion on this...

comment:8 by eriktorbjorn, 17 years ago

I guess Ender doesn't have another opion. Can we close this
now, then?

comment:9 by fingolfin, 17 years ago

Owner: changed from SF/ender to fingolfin
Resolution: outdated
Status: newclosed

comment:10 by digitall, 13 months ago

Component: Engine: SCUMM
Game: Monkey Island 3
Note: See TracTickets for help on using tickets.