Tuesday, April 1, 2014

That Menacing Mechanical Manatee

Continued from the previous entry

After the initial excitement of fixing the bug, Inguin remembered that the Manatee was the reason why that code was written in the first place. We have to try it out, so let's get to the MicroGroggery and try it out:
  • dofile("_jumpscripts.lua")
  • jump_script("250")
  • switch_to_set("mig")
Great, we're there! After a brief conversation with the barkeep, we get to ride the Manatee. And then things go a little bit wrong:

Air Riding the Manatee!
It turns out that the Chandelier wasn't a great test of the position code. The base actor was at (0,0,0) and had no rotation. The Manatee (or more specifically: mig.manatee_rotator) has a rotation before we attach Guybrush's actor to it. So, there's a problem with attaching actors when there's rotation. Let's do some investigation and see what the behavior of the retail engine is, as compared to the current code in ResidualVM.

The configuration for all of the tests start with this setup:
  • Actor1 is located at [1,2,3]
  • Actor2 is located at [2,4,6]
  • Actor1 is rotated to (0, 90, 0) using setrot
  • We call Actor1:attach(Actor2, nil) to attach the two actors
Once these steps have been completed, I looked at the information we can get from the Actors:

Command ResidualVM Retail
Actor1:getpos() (1,2,3) (1,2,3)
Actor1:getworldpos() (1,2,3) (1,2,3)
Actor1:getrot() (0,90,0) (0,90,0)
Actor2:getpos() (1,2,3) (-3,2,1)
Actor2:getworldpos() (4,4,2) (2,4,6)
Actor2:getrot() (0,0,0) (0,-90,0)

So, what does this tell us? For Actor1, the attaching doesn't change his position or behavior and both engines do the same thing! Actor2, who was attached to Actor1 doesn't fare quite as well. Starting with getrot, we see that the retail engine shows the angle relative to the attached actor. The world position from getworldpos is the original position before we attached the actors, while the position reported by getpos is wrong.

Let's try another test with this setup:
  • Actor1 is located at [1,2,3]
  • Actor2 is located at [2,4,6]
  • Actor1 is rotated to (0, 90, 0) using setrot
  • Actor2 is rotated to (20, 0, 0) using setrot
  • We call Actor1:attach(Actor2, nil) to attach the two actors
What happens this time?

Command ResidualVM Retail
Actor1:getpos() (1,2,3) (1,2,3)
Actor1:getworldpos() (1,2,3) (1,2,3)
Actor1:getrot() (0,90,0) (0,90,0)
Actor2:getpos() (1,2,3) (-3,2,1)
Actor2:getworldpos() (4,4,2) (2,4,6)
Actor2:getrot() (20,0,0) (90,70,-90)

Finally, let's look at what happens when we detach Actor2 from Actor1 using the second example:
  • Use the setup from the previous example
  • Then a2:detach()
Here's what happened this time:

Command ResidualVM Retail
Actor1:getpos() (1,2,3) (1,2,3)
Actor1:getworldpos() (1,2,3) (1,2,3)
Actor1:getrot() (0,90,0) (0,90,0)
Actor2:getpos() (4,4,2) (2,4,6)
Actor2:getworldpos() (4,4,2) (2,4,6)
Actor2:getrot() (0,0,0) (0,0,-20)

We can now make a few guesses as to what's going wrong. In the next post, we'll figure out how to fix the problem!

No comments:

Post a Comment