Passenger Vehicle Mount Problems
by Ronald J Nelson · in Torque Game Engine · 07/30/2007 (9:28 am) · 16 replies
I have a problem where I can get a driver to mount a vehicle all of the time, but not a passenger. The wierd thing is that if both players exit their vehicles, and a player mounts the other player's vehicle as the driver, then the remaining player can mount as a passenger. Here is my script:
**Edited to provide the script that is the problem. All other script is working perfectly.**
**Edited to provide the script that is the problem. All other script is working perfectly.**
function GameConnection::createVehicle(%this, %spawnPoint)
{
if (%this.mVehicle > 0)
{
// The client should not have a player currently
// assigned. Assigning a new one could result in
// a player ghost.
error( "Attempting to create an angus ghost!" );
}
%player = new Player()
{
dataBlock = %this.playerDB;
client = %this;
noSwitch = "yes";
ammoCache1 = 0;
ammoSubCache1 = 0;
ammoCache2 = 0;
ammoSubCache2 = 0;
};
error("created player");
MissionCleanup.add(%player);
error("added driver to missionCleanup");
// player setup
%player.setTransform(%spawnPoint);
%player.setShapeName(%this.name);
%this.camera.setTransform(%player.getEyeTransform());
%this.player = %player;
// Starting equipment
commandToClient(%this,'resetInventoryHUD');
%this.clrInventoryInfo(%player);
%this.getInventoryInfo(%player);
// Create the vehicle object
%vehicle = new WheeledVehicle()
{
dataBlock = %this.chassisDB;
mountable = true;
client = %this;
};
//Engine, transmission, springs and tires setup
%vehicle.autoTrans = %this.clientVTrans;
%vehicle.setEngine( %this.clientVEngine );
%vehicle.setSkinName(%this.clientVehicleSkin); // <-- add this to change the skin when the editor adds the item
if(%this.numPowered == 1)
{
// Setup the motorcycle with custom tires & springs
%vehicle.setWheelSpring(0,%this.clientVFSpring);
%vehicle.setWheelSpring(1,%this.clientVRSpring);
%vehicle.setWheelTire(0,%this.clientVFTire);
%vehicle.setWheelTire(1,%this.clientVFTire);
// Steer front tire
%vehicle.setWheelSteering(0,1);
// Only power the rear wheel...
%vehicle.setWheelPowered(0,false);
%vehicle.setWheelPowered(1,true);
}
if(%this.numPowered == 2)
{
// Setup the car with custom tires & springs
%vehicle.setWheelSpring(0,%this.clientVFSpring);
%vehicle.setWheelSpring(1,%this.clientVFSpring);
%vehicle.setWheelSpring(2,%this.clientVRSpring);
%vehicle.setWheelSpring(3,%this.clientVRSpring);
%vehicle.setWheelTire(0,%this.clientVFTire);
%vehicle.setWheelTire(1,%this.clientVFTire);
%vehicle.setWheelTire(2,%this.clientVRTire);
%vehicle.setWheelTire(3,%this.clientVRTire);
// Steer front tires
%vehicle.setWheelSteering(0,1);
%vehicle.setWheelSteering(1,1);
// Only power the two rear wheels...
%vehicle.setWheelPowered(0,false);
%vehicle.setWheelPowered(1,false);
%vehicle.setWheelPowered(2,true);
%vehicle.setWheelPowered(3,true);
}
if(%this.numPowered == 4)
{
// Setup the car with custom tires & springs
%vehicle.setWheelSpring(0,%this.clientVFSpring);
%vehicle.setWheelSpring(1,%this.clientVFSpring);
%vehicle.setWheelSpring(2,%this.clientVRSpring);
%vehicle.setWheelSpring(3,%this.clientVRSpring);
%vehicle.setWheelTire(0,%this.clientVFTire);
%vehicle.setWheelTire(1,%this.clientVFTire);
%vehicle.setWheelTire(2,%this.clientVRTire);
%vehicle.setWheelTire(3,%this.clientVRTire);
// Steer front tires
%vehicle.setWheelSteering(0,1);
%vehicle.setWheelSteering(1,1);
// Only power the two rear wheels...
%vehicle.setWheelPowered(0,true);
%vehicle.setWheelPowered(1,true);
%vehicle.setWheelPowered(2,true);
%vehicle.setWheelPowered(3,true);
}
%vehicle.setEnergyLevel(%vehicle.getDataBlock().maxEnergy);
%vehicle.setRechargeRate(%vehicle.getDataBlock().rechargeRate);
// Vehicle weapons setup
//if($Pref::Server::allowVehicleWeapons)
//setupWeapons(%this,%vehicle);
error("created vehicle");
MissionCleanup.add(%vehicle);
error("added vehicle to missionCleanup");
//attempt to mount player
error("Attempting to mount player to vehicle");
%node = "mount0";
//%this.player.onMount(%this,%player,%vehicle,%node);
%vehicle.mountObject(%player, 0);
//%player.Armor.onMount(%this,%player,%vehicle,%node);
// Player setup...
%vehicle.setTransform(%spawnPoint);
%player.setShapeName(%this.name);
// Update the camera to start with the player
%this.camera.setTransform(%vehicle.getEyeTransform());
// Give the client control of the player
%this.mVehicle = %vehicle;
%this.setControlObject(%vehicle);
//Enhanced Damage System
setInitialMeshState(%this.mVehicle);
}
};
#2
It makes perfect sence. What you need to do to verify what I am going to tell you is look at your function findEmptySeat. If it's like the one on TDN, then it will get all the mount nodes starting from the Drivers position. If the drivers position is empty, then it's returned first (always).
Now you could do something like this if you wanted only Passenger Seats.
Note that %i starts from one not zero here.
This way it will skip the first node (assuming the first one is the driver) and only look at the passenger nodes.
If you wanted a specific passenger seat and you know the node id, then all you could do something like this as a check
07/30/2007 (9:50 am)
@RonIt makes perfect sence. What you need to do to verify what I am going to tell you is look at your function findEmptySeat. If it's like the one on TDN, then it will get all the mount nodes starting from the Drivers position. If the drivers position is empty, then it's returned first (always).
Now you could do something like this if you wanted only Passenger Seats.
function findEmptyPassengerSeat(%vehicle, %vehicleblock)
{
for (%i = 1; %i < %vehicleblock.numMountPoints; %i++)
{
%node = %vehicle.getMountNodeObject(%i);
if (%node == 0)
{
return %i;
}
}
return -1;
}Note that %i starts from one not zero here.
This way it will skip the first node (assuming the first one is the driver) and only look at the passenger nodes.
If you wanted a specific passenger seat and you know the node id, then all you could do something like this as a check
function isEmptyPassengerSeat(%vehicle, %nodeID)
{
%node = %vehicle.getMountNodeObject(%nodeID);
if (%node == 0)
{
return 1;
}
return 0;
}
#3
07/30/2007 (2:19 pm)
Thanks Sam But I really want to be able to have an unrestricted number so that vehicles with different mount numbers still work.
#4
07/30/2007 (2:23 pm)
Dunno who Sam is, but you are restricted to the number of mountPoints that the DataBlock allows. If you change that, and change the model, then no problem. So I realy don't know what your disagreeing with here.
#5
I also see what you are trying to get at, but they only seem to be alterations of the same function I am using , which doesn't explain why it is having the issues it is.
07/30/2007 (3:05 pm)
Sorry Simon, answered that after I ran a few miles. Brain was definitely off.I also see what you are trying to get at, but they only seem to be alterations of the same function I am using , which doesn't explain why it is having the issues it is.
#6
When making a vehicle, most drivers are setup as mount0, and mount1 to mountX as passengers. By using the function I showed you, you would skip mount0 aka the driver and only use the passenger mounts. That way you can put him into a random passenger.
The other example was if you want to place him in a specific mount. EG: if you tried to mount from the back of the vehicle and you know this, you may have a back position mount you may want to only mount to.
07/30/2007 (3:29 pm)
They are alterations of the same function. But with one major difference. It does not start at 0 when interating though the mount points.When making a vehicle, most drivers are setup as mount0, and mount1 to mountX as passengers. By using the function I showed you, you would skip mount0 aka the driver and only use the passenger mounts. That way you can put him into a random passenger.
The other example was if you want to place him in a specific mount. EG: if you tried to mount from the back of the vehicle and you know this, you may have a back position mount you may want to only mount to.
#7
The guy looked as if he was in the drivers seat for first person view.
Third person view was disabled, and the driver's view was set back to where he spawned.
Now every once and a while before I did this if you kept trying to mount the car by rapidly hitting the key for it, it would occasionally mount correctly.
Please, I have no idea what I have done wrong. It is obvious to me now that the problem is not where Simon thought just because forcing the mount node to 1 should have worked if his proposed methods were the fix.
I am positive that there are nodes mount0 and mount1 on the vehicle as well.
07/31/2007 (12:47 am)
Well I did some more experimenting and totally bypassed the whole look for a mount node and just had it have the guy mount node 1 with some really odd results. The guy looked as if he was in the drivers seat for first person view.
Third person view was disabled, and the driver's view was set back to where he spawned.
Now every once and a while before I did this if you kept trying to mount the car by rapidly hitting the key for it, it would occasionally mount correctly.
Please, I have no idea what I have done wrong. It is obvious to me now that the problem is not where Simon thought just because forcing the mount node to 1 should have worked if his proposed methods were the fix.
I am positive that there are nodes mount0 and mount1 on the vehicle as well.
#8
07/31/2007 (12:49 am)
Also there is this info I have in my vehicle's datablock, if it helps.mountPose[0] = "Sitting"; mountPointTransform[0] = "0 0 0 0 0 1 0"; isProtectedMountPoint[0] = true; mountPose[1] = "Sitting"; mountPointTransform[1] = "0 0 0 0 0 1 0"; isProtectedMountPoint[1] = true;
#9
First we have Driver 1 looking out of his car at Driver 2 who has gotten out of his car:

Driver 2 is looking at Driver 1 in his car:

Driver 2 walks around to the passenger side of the car, hits the enter/exit button and this is what happens to Driver 1's view:

This is what Driver 2 sees:

Now Driver 1 gets out of the car, and is half sunk into the ground but walking forward immediately fixes this problem. He walks around to the front of his car to look and sees this:

OK NOW PAY CLOSE ATTENTION TO WHAT DRIVER 2 IS SEEING! He looks as if he is looking from the driver's seat. But externally he is sitting in the passenger seat.
This prompts 2 questions.
1. Why does he mount now rather than using the original script above?
2. What has happened to create the problem in the bottom 2 pictures?
HELP!!!!
07/31/2007 (12:16 pm)
I know pictures say a thousand words so let me show you what happens when I simply made the player only mount to mount node 1 when using this command.First we have Driver 1 looking out of his car at Driver 2 who has gotten out of his car:

Driver 2 is looking at Driver 1 in his car:

Driver 2 walks around to the passenger side of the car, hits the enter/exit button and this is what happens to Driver 1's view:

This is what Driver 2 sees:

Now Driver 1 gets out of the car, and is half sunk into the ground but walking forward immediately fixes this problem. He walks around to the front of his car to look and sees this:

OK NOW PAY CLOSE ATTENTION TO WHAT DRIVER 2 IS SEEING! He looks as if he is looking from the driver's seat. But externally he is sitting in the passenger seat.
This prompts 2 questions.
1. Why does he mount now rather than using the original script above?
2. What has happened to create the problem in the bottom 2 pictures?
HELP!!!!
#10
I had failed to comment out ths:
Which since we were not even looking through mount nodes, It always equaled 0. The problem is that now it doesn't mount again. The second driver does exactly as before when he tries to enter, passes through the car and ends up on the driver's side, out side of the car and not mounted.
07/31/2007 (12:31 pm)
OK I answered Number 2 on my own but the answer only makes me even more frustrated!I had failed to comment out ths:
if (%node == 0) { %client.mVehicle = %col; %obj.client.setControlObject(%col); }Which since we were not even looking through mount nodes, It always equaled 0. The problem is that now it doesn't mount again. The second driver does exactly as before when he tries to enter, passes through the car and ends up on the driver's side, out side of the car and not mounted.
#11
Basically I set up a switch in the script that once the server has been started you can make the new players spawn without their cars as they would in stock starter.fps. With this the script that is being taken out of the loop is the mounting script done in my function createVehicle.
Oddly enough, it doesnt work always either.
Well since I now know that it isn't my spawn script, I am really at a loss.
Guess I update the top portion a bit too soon. Here is what I have in the other functions again.
07/31/2007 (5:22 pm)
OK I managed to set up a different kind of test that has at least shown me where the problem must be.Basically I set up a switch in the script that once the server has been started you can make the new players spawn without their cars as they would in stock starter.fps. With this the script that is being taken out of the loop is the mounting script done in my function createVehicle.
Oddly enough, it doesnt work always either.
Well since I now know that it isn't my spawn script, I am really at a loss.
Guess I update the top portion a bit too soon. Here is what I have in the other functions again.
#12
07/31/2007 (11:55 pm)
function serverCmdMountVehicle(%client)
{
//Determine how far should the picking ray extend into the world?
%selectRange = 3;
// Only search for vehicles
%searchMasks = $TypeMasks::vehicleObjectType;
%pos = %client.player.getEyePoint();
// Start with the shape's eye vector...
%eye = %client.player.getEyeVector();
%eye = vectorNormalize(%eye);
%vec = vectorScale(%eye, %selectRange);
%end = vectorAdd(%vec, %pos);
%scanTarg = ContainerRayCast (%pos, %end, %searchMasks);
// a target in range was found so select it
if (%scanTarg && %client.getControlObject() == %client.player)
{
%targetObject = firstWord(%scanTarg);
%col = %targetObject;
%obj = %client.getControlObject();
echo("Found a vehicle: " @ %targetObject);
//Check to see if it is already being delete or is a static object
if(!%col.getDataBlock().mountable)
return;
//Check to see if it is going too fast too mount
if(isVehicleMoving2Fast(%col))
{
echo("Vehicle is going too fast");
return;
}
// Mount vehicles
%vehicleBlock = %col.getDataBlock();
// Only mount drivers for now.
%node = findEmptySeat(%col, %vehicleBlock);
%col.mountObject(%obj,%node);
if (%obj.isPilot())
{
%obj.client.mVehicle = %col;
%obj.client.setControlObject(%col);
}
%client.schedule(30, "mountVehicles", false);
}
else
{
%vehicle = %client.getControlObject();
if( %vehicle.getDataBlock().category != "Vehicles")
{
echo("Not in a vehicle");
return;
}
if(isVehicleMoving2Fast(%vehicle))
{
echo("Vehicle is going too fast");
return;
}
echo("No object found/Try dismount");
commandToClient(%client,'getOut',%client);
%client.setControlObject(%client.player);
%client.schedule(30, "mountVehicles", true);
%client.mVehicle = "";
schedule(($Pref::Server::vehicleFadeTime * 1000), 0, "startVehicleDeath", %vehicle);
}
}
function findEmptySeat(%vehicle, %vehicleblock)
{
echo("This vehicle has " @ %vehicleblock.numMountPoints @ " mount points.");
for (%i = 0; %i < %vehicleblock.numMountPoints; %i++)
{
%node = %vehicle.getMountNodeObject(%i);
echo("This is what is at mount node " @ %i @ " : " @ %node);
if (%node == 0)
{
echo("Node number: " @ %i @ " was returned");
return %i;
}
}
return -1;
}
function Armor::onMount(%this,%obj,%vehicle,%node)
{
%obj.setTransform(%vehicle.getDatablock().mountPointTransform[%node]);
%obj.setActionThread(%vehicle.getDatablock().mountPose[%node],true,true);
%obj.lastWeapon = %obj.getMountedImage($WeaponSlot);
%obj.unmountImage($WeaponSlot);
commandToClient(%obj.client, 'PopAmmoAmountHud');
}
function Armor::onUnmount( %this, %obj, %vehicle, %node )
{
}
function Armor::doDismount(%this, %obj, %forced)
{
// This function is called by player.cc when the jump trigger
// is true while mounted
if (!%obj.isMounted())
return;
// Position above dismount point
%pos = getWords(%obj.getTransform(), 0, 2);
%oldPos = %pos;
%vec[0] = " -1 0 0";
%vec[1] = " 0 0 1";
%vec[2] = " 0 0 -1";
%vec[3] = " 1 0 0";
%vec[4] = "-1 0 0";
%impulseVec = "0 0 0";
%vec[0] = MatrixMulVector( %obj.getTransform(), %vec[0]);
// Make sure the point is valid
%pos = "0 0 0";
%numAttempts = 5;
%success = -1;
for (%i = 0; %i < %numAttempts; %i++) {
%pos = VectorAdd(%oldPos, VectorScale(%vec[%i], 3));
if (%obj.checkDismountPoint(%oldPos, %pos)) {
%success = %i;
%impulseVec = %vec[%i];
break;
}
}
if (%forced && %success == -1)
%pos = %oldPos;
%obj.unmount();
%obj.setControlObject(%obj);
if(%obj.mVehicle)
%obj.mountVehicle = false;
%obj.schedule(30, "mountVehicles", true);
// <- RFB
// Position above dismount point
%obj.setTransform(%pos);
%obj.applyImpulse(%pos, VectorScale(%impulseVec, %obj.getDataBlock().mass));
%obj.vehicleTurret = "";
%obj.mountImage(%obj.lastWeapon, $WeaponSlot, $WeaponMount);
commandToClient(%obj.client, 'PushAmmoAmountHud');
}
function Player::mountVehicles(%this,%bool)
{
// If set to false, this variable disables vehicle mounting.
%this.mountVehicle = %bool;
}
function Player::isPilot(%this)
{
%vehicle = %this.getObjectMount();
// There are two "if" statements to avoid a script warning.
if (%vehicle)
if (%vehicle.getMountNodeObject(0) == %this)
return true;
return false;
}
#13
07/31/2007 (11:56 pm)
I am sure someone out there has this working. I would really appreciate just a quick look over to tell me what I am doing wrong.
#14
Shameless Plug. Stryker IAV Pack....Coming Soon. It's already been approved by GG, we just have a few inhouse things to wrap up that have placed this on the back burner.
Multi-mount, per-mount actionMaps, TGE and TGEA versions in product, multiplayer tested and friendly, runtime skin swaps, triggered animations, explosions, projectiles, all source code, script, art and geometry in .max(8) and blender(.blend) formats, and more. An invaluable jump off point for anyone that wants to learn how to make affective multi-mount vehicles. We ran into and solved the same problem(s) you discuss above , and some that you haven't yet discovered =).
08/01/2007 (6:42 am)
Link To What You NeedShameless Plug. Stryker IAV Pack....Coming Soon. It's already been approved by GG, we just have a few inhouse things to wrap up that have placed this on the back burner.
Multi-mount, per-mount actionMaps, TGE and TGEA versions in product, multiplayer tested and friendly, runtime skin swaps, triggered animations, explosions, projectiles, all source code, script, art and geometry in .max(8) and blender(.blend) formats, and more. An invaluable jump off point for anyone that wants to learn how to make affective multi-mount vehicles. We ran into and solved the same problem(s) you discuss above , and some that you haven't yet discovered =).
#15
08/01/2007 (9:36 am)
Cool you even have working head lights. So can you tell me if it was code related or script? Or probably both?
#16
08/01/2007 (12:38 pm)
Yeah, it has working headlights and brakelights. Yeah the whole thing involves code and script.
Torque Owner Ronald J Nelson
Code Hammer Games
Thanks everyone.