Creating FlyingVehicle with TGE 1.4
by Norv Brooks · in Torque Game Engine · 09/12/2006 (3:16 pm) · 2 replies
I've been trying to implement a flyingVehicle following Bruno Grieco (Jan 30, 2005) posted thread on Simple/Complex flying vehicles. Since I haven't found anything more current since release of TGE 1.4, I decided to start a new thread. I've been able to get a flying vehicle in the air and it moves, but it doesn't seem to spawn at the location I'm using, doesn't move in the pattern I've set up and moves a short distance and makes a small circle then moves on.

I'm sure I'm omitting something simple or coded something incorrectly. The following I hope is enough code that someone might see an error:
************* Code Flow *************************
During the mission load "createNewFlyingVehicle()" is called from "levelLoader.cs" and is located in "aircraft.cs"
From "createNewFlyingVehicle()]/b] within [b]"aircraft.cs" "Aircraft::spawnOnPath()" is called
From "Aircraft::spawnOnPath()" "Aircraft::spawn() is called
From "Aircraft::spawn()" %plane is returned back through chain to "createNewFlyingVehicle()
Next, "TOBot::spawnOnPath()" is called which is located in "bot.cs" which then calls "TOBot::spawn()
Again, %player is returned up through the chain to "createFlyingVehicle()
Then "Aircraft::onPlayerMount()" is called
Then returns to "createFlyingVehicle() and calls "AIPlayer::followPath()"
Next it returns back through the chain to "layOutFlyingVehicle() in "levelLoader.cs"
The following post has the datablocks used.

I'm sure I'm omitting something simple or coded something incorrectly. The following I hope is enough code that someone might see an error:
************* Code Flow *************************
During the mission load "createNewFlyingVehicle()" is called from "levelLoader.cs" and is located in "aircraft.cs"
switch$($FLYINGVEHICLESCLASS[%flyVehType])
{
// 2a
case TWINOTTER:
echo("Loading TwinOtter");
[b]%twinOtterObj = createNewFlyingVehicle("twinOtter");[/b]
echo("%twinOtterObj = ",%twinOtterObj);
flyingVehiclesGroup.add(%twinOtterObj);
}From "createNewFlyingVehicle()]/b] within [b]"aircraft.cs" "Aircraft::spawnOnPath()" is called
function createNewFlyingVehicle(%aircraftType)
{
echo("is %aircraftType a string ",%aircraftType);
if(%aircraftType $= "twinOtter")
{
%dblock = Aircraft;
%path = "MissionGroup/TwinOtterPath";
[b]%twinOtter = Aircraft::spawnOnPath(%path,%dblock,%aircraftType);[/b]
// set aircrat position
%aircraft = %twinOtter;
// Now create pilot
%num = %twinOtter;
%spawnName = "TOBot " @ %num;
%pathName = "MissionGroup/TwinOtterPath";
%nodeNum = %pathName.getCount();
[b]%pilot = TOBot::spawnOnPath(%spawnName, %pathName);[/b]
%pilot.path = %pathName;
%pilot.currentNode = 0;
%pilot.targetNode = 2;
[b]Aircraft::onPlayerMount(%pilot,%pilot,%aircraft,0);[/b]
$pilot = %pilot;
$moveNode = 1;
[b]AIPlayer::followPath(%pilot,%pathName,%pilot.targetNode);[/b]
%aircraft.player[%num] = $pilot;
return(%twinOtter);
}
else
return(NULL);
}From "Aircraft::spawnOnPath()" "Aircraft::spawn() is called
function Aircraft::spawnOnPath(%path,%dblock,%name)
{
// Spawn a player and place him on the first node of the path
if (!isObject(%path))
return;
%node = %path.getObject(0);
[b]%plane = Aircraft::spawn(%node.getTransform(),%dblock,%path,%name);[/b]
return %plane;
}
function Aircraft::spawn(%spawnPoint,%dblock,%path,%name)
{
// Create the plane object
%plane = new FlyingVehicle() {
dataBlock = %dblock;
path = %path;
};
//%plane = serverCmdAddFlyer(%name);
%plane.setTransform(%spawnPoint);
MissionCleanup.add(%plane);
[b]return %plane;[/b]
}From "Aircraft::spawn()" %plane is returned back through chain to "createNewFlyingVehicle()
Next, "TOBot::spawnOnPath()" is called which is located in "bot.cs" which then calls "TOBot::spawn()
function TOBot::spawnOnPath( %name, %path )
{
// Spawn a bot and place him on the first node of the path
if( !isObject( %path ) )
{
echo( "TOBot::spawnOnPath failed - Bad Path!" );
%this.path = "";
return;
}
%node = %path.getObject(0);
[b]%player = TOBot::spawn( %name, %node.getTransform() );[/b]
return %player;
}
function TOBot::spawn( %name, %spawnPoint )
{
// Create the A.I. driven bot object...
%player = new AIPlayer()
{
dataBlock = DemoPlayer;
path = "MissionGroup/TwinOtterPath";
};
%player.mountable = true;
MissionCleanup.add( %player );
%player.setShapeName( %name );
%player.setTransform( %spawnPoint );
[b]return %player;[/b]
}Again, %player is returned up through the chain to "createFlyingVehicle()
Then "Aircraft::onPlayerMount()" is called
function Aircraft::onPlayerMount(%player,%obj,%vehicle,%node)
{
CommandToClient(%obj.client, 'PopActionMap', moveMap);
CommandToClient(%obj.client, 'PushActionMap', $Vehicle::moveMaps[%node]);
CommandToClient(%obj.client,'HideCommandMenuServer');
%obj.setTransform(%vehicle.getDataBlock().mountPointTransform[%node]);
%obj.lastWeapon = %obj.getMountedImage($WeaponSlot);
%obj.unmountImage($WeaponSlot);
%obj.setActionThread(%vehicle.getDatablock().mountPose[%node],true,true);
// Are we driving this vehicle?
if (%node == 0) {
%obj.setControlObject(%vehicle);
}
}Then returns to "createFlyingVehicle() and calls "AIPlayer::followPath()"
function AIPlayer::followPath(%this,%path,%node)
{
// Start the player following a path
%this.setAimLocation($Aircraft::markerLocation[$moveNode]);
%this.stopThread(0);
if (!isObject(%path)) {
%this.path = "";
return;
}
if (%node > %path.getCount() - 1)
%this.targetNode = %path.getCount() - 1;
else
%this.targetNode = %node;
if (%this.path $= %path)
%this.moveToNode(%this.currentNode,0);
else {
%this.path = %path;
%this.moveToNode(0);
}
}
function AIPlayer::moveToNode(%this,%index)
{
// Move to the given path node index
%node = %this.path.getObject(%this.currentNode+1);
%this.setMoveDestination(%node.getTransform(), %index == %this.targetNode);
}Next it returns back through the chain to "layOutFlyingVehicle() in "levelLoader.cs"
The following post has the datablocks used.
About the author
#2
*********************** AIPlayer Datablocks ************************
// ----------------Defines in aircraft.cs-------------------
I'm just using simple prop driven aircraft; so, I probably could omit a good portion of data in these datablocks. However, I didn't know if the terms referring to "jets" was just generic and prop driven planes would still use the same data.
Thanks for any help give.
Norv
09/12/2006 (3:34 pm)
Follow up datablocks cont.*********************** AIPlayer Datablocks ************************
datablock PlayerData(PlayerBody)
{
renderFirstPerson = false;
emap = true;
className = SJPlayer;
shapeFile = "~/data/shapes/player/player.dts";
cameraMaxDist = 3;
computeCRC = true;
canObserve = true;
cmdCategory = "Clients";
cameraDefaultFov = 90.0;
cameraMinFov = 5.0;
cameraMaxFov = 120.0;
debrisShapeName = "~/data/shapes/player/debris_player.dts";
debris = playerDebris;
aiAvoidThis = true;
minLookAngle = -1.4;
maxLookAngle = 1.4;
maxFreelookAngle = 3.0;
mass = 90;
drag = 0.3;
maxdrag = 0.4;
density = 10;
maxDamage = 100;
maxEnergy = 60;
repairRate = 0.33;
energyPerDamagePoint = 75.0;
rechargeRate = 0.256;
runForce = 48 * 90;
runEnergyDrain = 0;
minRunEnergy = 0;
maxForwardSpeed = 14;
maxBackwardSpeed = 13;
maxSideSpeed = 13;
maxUnderwaterForwardSpeed = 8.4;
maxUnderwaterBackwardSpeed = 7.8;
maxUnderwaterSideSpeed = 7.8;
jumpForce = 8.3 * 90;
jumpEnergyDrain = 0;
minJumpEnergy = 0;
jumpDelay = 15;
recoverDelay = 9;
recoverRunForceScale = 1.2;
minImpactSpeed = 45;
speedDamageScale = 0.4;
boundingBox = "1.2 1.2 2.3";
pickupRadius = 0.75;
// Damage location details
boxNormalHeadPercentage = 0.83;
boxNormalTorsoPercentage = 0.49;
boxHeadLeftPercentage = 0;
boxHeadRightPercentage = 1;
boxHeadBackPercentage = 0;
boxHeadFrontPercentage = 1;
// Foot Prints
decalData = PlayerFootprint;
decalOffset = 0.25;
footPuffEmitter = LightPuffEmitter;
footPuffNumParts = 10;
footPuffRadius = 0.25;
dustEmitter = LiftoffDustEmitter;
splash = PlayerSplash;
splashVelocity = 4.0;
splashAngle = 67.0;
splashFreqMod = 300.0;
splashVelEpsilon = 0.60;
bubbleEmitTime = 0.4;
splashEmitter[0] = PlayerFoamDropletsEmitter;
splashEmitter[1] = PlayerFoamEmitter;
splashEmitter[2] = PlayerBubbleEmitter;
mediumSplashSoundVelocity = 10.0;
hardSplashSoundVelocity = 20.0;
exitSplashSoundVelocity = 5.0;
// Controls over slope of runnable/jumpable surfaces
runSurfaceAngle = 70;
jumpSurfaceAngle = 80;
minJumpSpeed = 20;
maxJumpSpeed = 30;
horizMaxSpeed = 68;
horizResistSpeed = 33;
horizResistFactor = 0.35;
upMaxSpeed = 80;
upResistSpeed = 25;
upResistFactor = 0.3;
footstepSplashHeight = 0.35;
//NOTE: some sounds commented out until wav's are available
// Footstep Sounds
FootSoftSound = FootLightSoftSound;
FootHardSound = FootLightHardSound;
FootMetalSound = FootLightMetalSound;
FootSnowSound = FootLightSnowSound;
FootShallowSound = FootLightShallowSplashSound;
FootWadingSound = FootLightWadingSound;
FootUnderwaterSound = FootLightUnderwaterSound;
groundImpactMinSpeed = 10.0;
groundImpactShakeFreq = "4.0 4.0 4.0";
groundImpactShakeAmp = "1.0 1.0 1.0";
groundImpactShakeDuration = 0.8;
groundImpactShakeFalloff = 10.0;
//exitingWater = ExitingWaterLightSound;
observeParameters = "0.5 4.5 4.5";
// Allowable Inventory Items
maxInv[BulletAmmo] = 20;
maxInv[HealthKit] = 1;
maxInv[RifleAmmo] = 100;
maxInv[CrossbowAmmo] = 50;
maxInv[Crossbow] = 1;
maxInv[Rifle] = 1;
maxInv[mountedImage] = 10;
maxInv[mountedImageAmmo] = 50;
};
datablock PlayerData(DemoPlayer : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
shootingDelay = 2000;
};// ----------------Defines in aircraft.cs-------------------
// Defines for TwinOtter marker locations $Aircraft::markerLocation[0] = "-26.002 -124.037 75.9451 1 0 0 0"; $Aircraft::markerLocation[1] = "-130.406 -123.041 75.9451 1 0 0 0"; $Aircraft::markerLocation[2] = "-138.890 -168.453 75.9451 1 0 0 0";
I'm just using simple prop driven aircraft; so, I probably could omit a good portion of data in these datablocks. However, I didn't know if the terms referring to "jets" was just generic and prop driven planes would still use the same data.
Thanks for any help give.
Norv
Torque Owner Norv Brooks
************ FlyingVehicle Datablocks ****************
//------------------------------------------------------------------------
// Flying vehicles datablock FlyingVehicleData(Drone) { spawnOffset = "0 0 2"; emap = true; category = "Vehicles"; shapeFile = "~/data/vehicles/buggyGT.dts"; multipassenger = false; computeCRC = true; debrisShapeName = "~/data/vehicles/buggyGT.dts"; debris = DroneShapeDebris; renderWhenDestroyed = false; mountPose[0] = sitting; numMountPoints = 1; isProtectedMountPoint[0] = true; cameraMaxDist = 0.5; cameraOffset = 4.5; cameraLag = 0.0; cameraRoll = true; // Roll the camera with the vehicle // explosion = DroneVehicleExplosion; explosionDamage = 10.5; explosionRadius = 15.0; maxDamage = 50.40; destroyedLevel = 50.40; isShielded = true; energyPerDamagePoint = 160; maxEnergy = 280; // Afterburner and any energy weapon pool rechargeRate = 0.8; integration = 4; // Physics integration: TickSec/Rate collisionTol = 0.2; // Collision distance tolerance contactTol = 0.1; drag = 0.6; density = 6.0; minDrag = 30; // Linear Drag (eventually slows you down when not thrusting...constant drag) rotationalDrag = 5; // Anguler Drag (dampens the drift after you stop moving the mouse...also tumble drag) maxAutoSpeed = 10; // Autostabilizer kicks in when less than this speed. (meters/second) autoAngularForce = 200; // Angular stabilizer force (this force levels you out when autostabilizer kicks in) autoLinearForce = 200; // Linear stabilzer force (this slows you down when autostabilizer kicks in) autoInputDamping = 0.95; // Dampen control input so you don't' whack out at very slow speeds // Maneuvering maxSteeringAngle = 0.385; // -***Max radiens you can rotate the wheel. Smaller number is more maneuverable. horizontalSurfaceForce = 6; // Horizontal center "wing" (provides "bite" into the wind for climbing/diving and turning) verticalSurfaceForce = 0.5; // Vertical center "wing" (controls side slip. lower numbers make MORE slide.) maneuveringForce = 1400; // Horizontal jets (W,S,D,A key thrust) steeringForce = 200; // Steering jets (force applied when you move the mouse) steeringRollForce = 10; // Steering jets (how much you heel over when you turn) rollForce = 20; // Auto-roll (self-correction to right you after you roll/invert) hoverHeight = 45; // Height off the ground at rest createHoverHeight = 45; // Height off the ground when created maxForwardSpeed = 100; // +***speed in which forward thrust force is no longer applied (meters/second) // Turbo Jet jetForce = 3000; // Afterburner thrust (this is in addition to normal thrust) minJetEnergy = 28; // Afterburner can't be used if below this threshhold. jetEnergyDrain = 2.8; // Energy use of the afterburners (low number is less drain...can be fractional) // Auto stabilize speed vertThrustMultiple = 3.0; // Rigid body mass = 90; // Mass of the vehicle bodyFriction = 0; // Don't mess with this. bodyRestitution = 0.4; // When you hit the ground, how much you rebound. (between 0 and 1) minRollSpeed = 2000; // Don't mess with this. softImpactSpeed = 3; // Sound hooks. This is the soft hit. hardImpactSpeed = 15; // Sound hooks. This is the hard hit. // Ground Impact Damage (uses DamageType::Ground) minImpactSpeed = 10; // If hit ground at speed above this then it's an impact. Meters/second speedDamageScale = 0.06; // Object Impact Damage (uses DamageType::Impact) collDamageThresholdVel = 23.0; collDamageMultiplier = 0.02; // minTrailSpeed = 15; // The speed your contrail shows up at. triggerDustHeight = 4.0; dustHeight = 1.0; damageEmitterOffset[0] = "0.0 -3.0 0.0 "; damageLevelTolerance[0] = 0.3; damageLevelTolerance[1] = 0.7; numDmgEmitterAreas = 3; minMountDist = 0.2; // -*** maxMountSpeed = 0.1; mountDelay = 2; dismountDelay = 1; stationaryTreshold = 0.5; maxDismountSpeed = 100; mountable = true; mountPointTransform[0] = "1 0 0 0 0 0 0"; checkRadius = 5.5; observeParameters = "0 0 0"; shieldEffectScale = "0.937 1.125 0.60"; }; // Load dts shapes and merge animations datablock TSShapeConstructor(TwinOtter_rootDts) { baseShape = "~/data/shapes/aircraft/TwinOtter.dts"; sequence0 = "~/data/shapes/aircraft/TwinOtter_root.dsq"; }; // Flying vehicles datablock FlyingVehicleData(Aircraft : Drone) { numMountPoints = 3; };