Opened 17 years ago

Closed 17 years ago

Last modified 17 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, 17 months ago

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