Here's how to get them working.
If you want the solution, skip down a ways. I'm going to describe the problem.
A ship is a multi. Multis in the decompiled demo can be found in the rundir/multi.txt.q file. This actually lists the components of the multi with the locations, and what scripts are attached to each component.
The idea is, when the multi (or boat) is loaded, the script for each appropriate piece is loaded. In the following image, it should be clear that 5 scripts should be loaded into the boat multi, but are not.
This is, in short, why boats don't work.
We need to modify two scripts to make boats work.
shipdeed.m.q
shipplank.m.q
In shipdeed.m.q, after the include, and before the first declared function (Q5SF), insert the following:
- Code: Select all
function void attachScriptToComponent(object user, object shipComponent)
{
if(getName(shipComponent) == "a tiller man")
{
attachScript(shipComponent, "shiptillerman");
}
if(getName(shipComponent) == "a hatch")
{
attachScript(shipComponent, "shiphold");
}
if(getName(shipComponent) == "a mast")
{
attachScript(shipComponent, "shipdecay");
}
if(getObjType(shipComponent) == 0x3EB1)
{
attachScript(shipComponent, "shipplank");
attachScript(shipComponent, "shipleftplank");
}
if(getObjType(shipComponent) == 0x3EB2)
{
attachScript(shipComponent, "shipplank");
attachScript(shipComponent, "shiprightplank");
}
return();
}
Now, further down in shipdeed.m.q, about halfway, in the function "targetloc":
After the line that reads "object Q5AO = Q5SD(Q5SR, place);"
And before the line that reads "if(Q5AO == NULL())"
Add the following snippet:
- Code: Select all
list objectsNearShip;
getObjectsInRange(objectsNearShip, place, 0x0A);
integer numObjects;
numObjects = numInList(objectsNearShip);
integer objectCounter;
for(objectCounter = 0x00; objectCounter < numObjects; objectCounter ++)
{
if(getMultiSlaveId(objectsNearShip[objectCounter]) == Q5AO)
{
attachScriptToComponent(user, objectsNearShip[objectCounter]);
}
}
One more change. Open up shipplank.m.q. In the function Q5SA:
Find the line that reads "setZ(Q5CP, getZ(Q5CP) + getSurfaceHeight(Q5IB));"
And change that line so it reads "setZ(Q5CP, getZ(Q5CP) + getSurfaceHeight(Q5IB) + 0x04);"
That is, you are adding 4 to the Z height of your player when you teleport TO the gang plank on double-click.
There is one bug left to find and that is why you can't walk after moving the boat, although you are on the same Z height as before the boat moved..
Regardless, these changes allow you to board boats, lock them, unlock them, issue commands to the tillerman, dock the boats, undock the boats, use the keys, see the age of the ship, (probably) rename the ship... etc...