Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Advanced, semi-realistic helicopter script

Apotheus Silverman
I write code.
Join date: 17 Nov 2003
Posts: 416
06-13-2005 18:19
This is the AS-2 Advanced Helicopter that I never quite finished, so I have released it open source as an example of what is possible with vehicle and physics if you use a little imagination. My hope is that it opens people's minds so we start to see more examples of great vehicles. I apologize that it is not highly commented.

The main script has a really great extra built into it that completely fixes all sim border crossing problems for airborne vehicles. Again, I never really had a chance to finish this so that code has not been separated out.

The helicopter itself includes realistic sounds and rotor effects as well as an informational HUD and cross-hairs for a mouselook control reference point. It is available here: http://www.slexchange.com/modules.php?name=Marketplace&file=item&ItemID=16031

The vehicle flies much like a real helicopter. I leave learning how to fly it as an exercise for you to figure out yourself. :)

CODE
// RealHeli by Apotheus Silverman
// An advanced, semi-realistic helicopter vehicle script for Second Life.
// This product is released open source. Please give due credit in
// derivative works. :-)
//
// This behavior script is based on my experience with helicopter flight in
// Microsoft Flight Simulator and the included vehicle object is based on
// the Hughes 500 model helicopter.
//
// This vehicle can only be controlled properly in mouselook.
//
// Helicopter controls:
// left/right - tail rotor / rudder
// pgup/pgdn - collective
// mouse - yoke

key currentAgent = NULL_KEY;

float minSoundVolume = 0.4;
float maxSoundVolume = 1.0;

float ROTATION_RATE = 2.0; // Rate of turning
float FWD_THRUST = 20; // Forward thrust motor force
float BACK_THRUST = 7; // Backup thrust
float VERTICAL_THRUST = 7;
// Keep a running linear motor value for better response
vector linear_motor = <0,0,0>;

float collective = 0.0;
float oldCollective = 0.0;
float myMass;
string currentRegion;
vector currentVel;

vector reference_frame = <0,0,0>;

default {
state_entry() {
llPreloadSound("hughes 500");

llSitTarget(<0.88, 0.0, 0.4>, ZERO_ROTATION);
llSetCameraEyeOffset(<-7.0, 0.0, 3.0>);
llSetSitText("Fly");
llSetCameraAtOffset(<0, 0, 1>);

// Reset flags that can get set from other scripts
llSetBuoyancy(0.0);

//hover
llSetVehicleType(VEHICLE_TYPE_AIRPLANE);
llRemoveVehicleFlags(VEHICLE_FLAG_LIMIT_ROLL_ONLY|VEHICLE_FLAG_CAMERA_DECOUPLED);

llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME, llEuler2Rot(reference_frame * DEG_TO_RAD));
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.9);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 30);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 1000);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 0.5);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.5);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 120);
llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1000,1000,1000>);
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <2,2,20>);
llSetVehicleFloatParam(VEHICLE_BUOYANCY, 0.0);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.2);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 2.0);
llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.0);
llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 0.0);
llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.05);

// Hover mode (mouselook)
llRemoveVehicleFlags(VEHICLE_FLAG_MOUSELOOK_STEER);
llSetVehicleFlags(VEHICLE_FLAG_MOUSELOOK_BANK);
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, <2, 2.5, 0>);
}

touch_start(integer num) {
//llWhisper(0, "Buy me! Right click and choose 'Buy' then take me out of your inventory to fly!");
}

changed(integer change) {
if (change & CHANGED_LINK) {
key agent = llAvatarOnSitTarget();
if (agent) {
if (agent != llGetOwner()) {
// only the owner can use this vehicle
llSay(0, "You aren't the owner of this vehicle.");
llUnSit(agent);
llPushObject(agent, <0,0,10>, ZERO_VECTOR, FALSE);
} else if (currentAgent == NULL_KEY) {
// driver is entering the vehicle
llSetStatus(STATUS_PHYSICS, TRUE);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
currentRegion = llGetRegionName();
currentVel = llGetVel();
llSetTimerEvent(1.0);
llMessageLinked(LINK_SET, 1, "hud", NULL_KEY);
llLoopSound("hughes 500", minSoundVolume);
}
} else if (currentAgent) {
// driver is getting up
currentAgent = NULL_KEY;
llStopSound();
llSetStatus(STATUS_PHYSICS, FALSE);
llStopAnimation("driving generic");
llReleaseControls();
llSetTimerEvent(0.0);
llMessageLinked(LINK_SET, 0, "hud", NULL_KEY);
}
}
}

run_time_permissions(integer perm) {
if (perm) {
currentAgent = llAvatarOnSitTarget();
llStartAnimation("driving generic");
myMass = llGetMass();
collective = 7.3;
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_UP | CONTROL_DOWN, TRUE, FALSE);
}
}

timer() {
// Check for and attempt to correct bad sim border crossing
string newRegion = llGetRegionName();
if (newRegion != currentRegion) {
llApplyImpulse((currentVel - llGetVel()) * myMass, FALSE);
currentRegion = newRegion;
llSleep(0.2);
}


// Update VEHICLE_ANGULAR_DEFLECTION_TIMESCALE based on current velocity to simulate drag on the tail
currentVel = llGetVel();
float timescale = llVecMag(currentVel) * -0.05 + 0.7;
if (timescale < 0.01) {
timescale = 0.01;
}
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, timescale);
// Simulate drag
llApplyImpulse(-currentVel * 0.3, FALSE);
}

control(key id, integer level, integer edge) {
if (level & CONTROL_LEFT) {
llApplyRotationalImpulse(<0,0,2> * myMass, TRUE);
}
if (level & CONTROL_RIGHT) {
llApplyRotationalImpulse(<0,0,-2> * myMass, TRUE);
}

if (level & CONTROL_UP) {
collective += 0.25;
}
if (level & CONTROL_DOWN) {
collective -= 0.25;
}
if (oldCollective != collective) {
//llWhisper(0, "Collective " + (string)collective);
if (llFabs(collective - 9.8) < 0.1) {
// Make sure we can always hover
collective = 9.8;
}
if (collective > 12.8) {
collective = 12.8;
} else if (collective < 7.3) {
collective = 7.3;
}
llSetForce(<0, 0, collective> * llGetMass(), TRUE);
llMessageLinked(LINK_SET, (integer)(((collective - 7.3) / 5.5) * 100.0), "throttle", NULL_KEY);
llAdjustSoundVolume(((collective - 7.3) / 5.5) * (maxSoundVolume - minSoundVolume) + minSoundVolume);
}
oldCollective = collective;
}
}
_____________________
Apotheus Silverman
Shop SL on the web - SLExchange.com

Visit Abbotts Aerodrome for gobs of flying fun.
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Discussion Thread
06-18-2005 09:51
/54/77/50709/1.html
_____________________
i've got nothing. ;)
electricity Moonlight
Registered User
Join date: 4 Sep 2005
Posts: 0
non working sctript
09-17-2005 01:06
hi
it seems when ever i paste a script fomr the library includin yours i get an error


this was your script

// RealHeli by Apotheus Silverman
// An advanced, semi-realistic helicopter vehicle script for Second Life.
// This product is released open source. Please give due credit in
// derivative works. :-)
//
// This behavior script is based on my experience with helicopter flight in
// Microsoft Flight Simulator and the included vehicle object is based on
// the Hughes 500 model helicopter.
//
// This vehicle can only be controlled properly in mouselook.
//
// Helicopter controls:
// left/right - tail rotor / rudder
// pgup/pgdn - collective
// mouse - yoke

key currentAgent = NULL_KEY;

float minSoundVolume = 0.4;
float maxSoundVolume = 1.0;

float ROTATION_RATE = 2.0; // Rate of turning
float FWD_THRUST = 20; // Forward thrust motor force
float BACK_THRUST = 7; // Backup thrust
float VERTICAL_THRUST = 7;
// Keep a running linear motor value for better response
vector linear_motor = <0,0,0>;

float collective = 0.0;
float oldCollective = 0.0;
float myMass;
string currentRegion;
vector currentVel;

vector reference_frame = <0,0,0>;

default {
state_entry() {
llPreloadSound("hughes 500";);

llSitTarget(<0.88, 0.0, 0.4>, ZERO_ROTATION);
llSetCameraEyeOffset(<-7.0, 0.0, 3.0>;);
llSetSitText("Fly";);
llSetCameraAtOffset(<0, 0, 1>;);

// Reset flags that can get set from other scripts
llSetBuoyancy(0.0);

//hover
llSetVehicleType(VEHICLE_TYPE_AIRPLANE);
llRemoveVehicleFlags(VEHICLE_FLAG_LIMIT_ROLL_ONLY| VEHICLE_FLAG_CAMERA_DECOUPLED);

llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME, llEuler2Rot(reference_frame * DEG_TO_RAD));
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_ EFFICIENCY, 0.9);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_E FFICIENCY, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_ TIMESCALE, 30);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_T IMESCALE, 1000);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESC ALE, 0.5);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_ TIMESCALE, 0.5);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMES CALE, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY _TIMESCALE, 120);
llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TI MESCALE, <1000,1000,1000>;);
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_T IMESCALE, <2,2,20>;);
llSetVehicleFloatParam(VEHICLE_BUOYANCY, 0.0);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION _EFFICIENCY, 0.2);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION _TIMESCALE, 2.0);
llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.0);
llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 0.0);
llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.05);

// Hover mode (mouselook)
llRemoveVehicleFlags(VEHICLE_FLAG_MOUSELOOK_STEER) ;
llSetVehicleFlags(VEHICLE_FLAG_MOUSELOOK_BANK);
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRE CTION, <2, 2.5, 0>;);
}

touch_start(integer num) {
//llWhisper(0, "Buy me! Right click and choose 'Buy' then take me out of your inventory to fly!";);
}

changed(integer change) {
if (change & CHANGED_LINK) {
key agent = llAvatarOnSitTarget();
if (agent) {
if (agent != llGetOwner()) {
// only the owner can use this vehicle
llSay(0, "You aren't the owner of this vehicle.";);
llUnSit(agent);
llPushObject(agent, <0,0,10>, ZERO_VECTOR, FALSE);
} else if (currentAgent == NULL_KEY) {
// driver is entering the vehicle
llSetStatus(STATUS_PHYSICS, TRUE);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
currentRegion = llGetRegionName();
currentVel = llGetVel();
llSetTimerEvent(1.0);
llMessageLinked(LINK_SET, 1, "hud", NULL_KEY);
llLoopSound("hughes 500", minSoundVolume);
}
} else if (currentAgent) {
// driver is getting up
currentAgent = NULL_KEY;
llStopSound();
llSetStatus(STATUS_PHYSICS, FALSE);
llStopAnimation("driving generic";);
llReleaseControls();
llSetTimerEvent(0.0);
llMessageLinked(LINK_SET, 0, "hud", NULL_KEY);
}
}
}

run_time_permissions(integer perm) {
if (perm) {
currentAgent = llAvatarOnSitTarget();
llStartAnimation("driving generic";);
myMass = llGetMass();
collective = 7.3;
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_UP | CONTROL_DOWN, TRUE, FALSE);
}
}

timer() {
// Check for and attempt to correct bad sim border crossing
string newRegion = llGetRegionName();
if (newRegion != currentRegion) {
llApplyImpulse((currentVel - llGetVel()) * myMass, FALSE);
currentRegion = newRegion;
llSleep(0.2);
}


// Update VEHICLE_ANGULAR_DEFLECTION_TIMESCALE based on current velocity to simulate drag on the tail
currentVel = llGetVel();
float timescale = llVecMag(currentVel) * -0.05 + 0.7;
if (timescale < 0.01) {
timescale = 0.01;
}
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_ TIMESCALE, timescale);
// Simulate drag
llApplyImpulse(-currentVel * 0.3, FALSE);
}

control(key id, integer level, integer edge) {
if (level & CONTROL_LEFT) {
llApplyRotationalImpulse(<0,0,2> * myMass, TRUE);
}
if (level & CONTROL_RIGHT) {
llApplyRotationalImpulse(<0,0,-2> * myMass, TRUE);
}

if (level & CONTROL_UP) {
collective += 0.25;
}
if (level & CONTROL_DOWN) {
collective -= 0.25;
}
if (oldCollective != collective) {
//llWhisper(0, "Collective " + (string)collective);
if (llFabs(collective - 9.8) < 0.1) {
// Make sure we can always hover
collective = 9.8;
}
if (collective > 12.8) {
collective = 12.8;
} else if (collective < 7.3) {
collective = 7.3;
}
llSetForce(<0, 0, collective> * llGetMass(), TRUE);
llMessageLinked(LINK_SET, (integer)(((collective - 7.3) / 5.5) * 100.0), "throttle", NULL_KEY);
llAdjustSoundVolume(((collective - 7.3) / 5.5) * (maxSoundVolume - minSoundVolume) + minSoundVolume);
}
oldCollective = collective;
}
}

thank you
electricity Moonlight
Registered User
Join date: 4 Sep 2005
Posts: 0
non workign script
09-17-2005 01:08
hi
it seems when ever i paste a script fomr the library includin yours i get an error


this was your script

// RealHeli by Apotheus Silverman
// An advanced, semi-realistic helicopter vehicle script for Second Life.
// This product is released open source. Please give due credit in
// derivative works. :-)
//
// This behavior script is based on my experience with helicopter flight in
// Microsoft Flight Simulator and the included vehicle object is based on
// the Hughes 500 model helicopter.
//
// This vehicle can only be controlled properly in mouselook.
//
// Helicopter controls:
// left/right - tail rotor / rudder
// pgup/pgdn - collective
// mouse - yoke

key currentAgent = NULL_KEY;

float minSoundVolume = 0.4;
float maxSoundVolume = 1.0;

float ROTATION_RATE = 2.0; // Rate of turning
float FWD_THRUST = 20; // Forward thrust motor force
float BACK_THRUST = 7; // Backup thrust
float VERTICAL_THRUST = 7;
// Keep a running linear motor value for better response
vector linear_motor = <0,0,0>;

float collective = 0.0;
float oldCollective = 0.0;
float myMass;
string currentRegion;
vector currentVel;

vector reference_frame = <0,0,0>;

default {
state_entry() {
llPreloadSound("hughes 500";);

llSitTarget(<0.88, 0.0, 0.4>, ZERO_ROTATION);
llSetCameraEyeOffset(<-7.0, 0.0, 3.0>;);
llSetSitText("Fly";);
llSetCameraAtOffset(<0, 0, 1>;);

// Reset flags that can get set from other scripts
llSetBuoyancy(0.0);

//hover
llSetVehicleType(VEHICLE_TYPE_AIRPLANE);
llRemoveVehicleFlags(VEHICLE_FLAG_LIMIT_ROLL_ONLY| VEHICLE_FLAG_CAMERA_DECOUPLED);

llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME, llEuler2Rot(reference_frame * DEG_TO_RAD));
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_ EFFICIENCY, 0.9);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_E FFICIENCY, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_ TIMESCALE, 30);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_T IMESCALE, 1000);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESC ALE, 0.5);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_ TIMESCALE, 0.5);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMES CALE, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY _TIMESCALE, 120);
llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TI MESCALE, <1000,1000,1000>;);
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_T IMESCALE, <2,2,20>;);
llSetVehicleFloatParam(VEHICLE_BUOYANCY, 0.0);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION _EFFICIENCY, 0.2);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION _TIMESCALE, 2.0);
llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.0);
llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 0.0);
llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.05);

// Hover mode (mouselook)
llRemoveVehicleFlags(VEHICLE_FLAG_MOUSELOOK_STEER) ;
llSetVehicleFlags(VEHICLE_FLAG_MOUSELOOK_BANK);
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRE CTION, <2, 2.5, 0>;);
}

touch_start(integer num) {
//llWhisper(0, "Buy me! Right click and choose 'Buy' then take me out of your inventory to fly!";);
}

changed(integer change) {
if (change & CHANGED_LINK) {
key agent = llAvatarOnSitTarget();
if (agent) {
if (agent != llGetOwner()) {
// only the owner can use this vehicle
llSay(0, "You aren't the owner of this vehicle.";);
llUnSit(agent);
llPushObject(agent, <0,0,10>, ZERO_VECTOR, FALSE);
} else if (currentAgent == NULL_KEY) {
// driver is entering the vehicle
llSetStatus(STATUS_PHYSICS, TRUE);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
currentRegion = llGetRegionName();
currentVel = llGetVel();
llSetTimerEvent(1.0);
llMessageLinked(LINK_SET, 1, "hud", NULL_KEY);
llLoopSound("hughes 500", minSoundVolume);
}
} else if (currentAgent) {
// driver is getting up
currentAgent = NULL_KEY;
llStopSound();
llSetStatus(STATUS_PHYSICS, FALSE);
llStopAnimation("driving generic";);
llReleaseControls();
llSetTimerEvent(0.0);
llMessageLinked(LINK_SET, 0, "hud", NULL_KEY);
}
}
}

run_time_permissions(integer perm) {
if (perm) {
currentAgent = llAvatarOnSitTarget();
llStartAnimation("driving generic";);
myMass = llGetMass();
collective = 7.3;
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_UP | CONTROL_DOWN, TRUE, FALSE);
}
}

timer() {
// Check for and attempt to correct bad sim border crossing
string newRegion = llGetRegionName();
if (newRegion != currentRegion) {
llApplyImpulse((currentVel - llGetVel()) * myMass, FALSE);
currentRegion = newRegion;
llSleep(0.2);
}


// Update VEHICLE_ANGULAR_DEFLECTION_TIMESCALE based on current velocity to simulate drag on the tail
currentVel = llGetVel();
float timescale = llVecMag(currentVel) * -0.05 + 0.7;
if (timescale < 0.01) {
timescale = 0.01;
}
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_ TIMESCALE, timescale);
// Simulate drag
llApplyImpulse(-currentVel * 0.3, FALSE);
}

control(key id, integer level, integer edge) {
if (level & CONTROL_LEFT) {
llApplyRotationalImpulse(<0,0,2> * myMass, TRUE);
}
if (level & CONTROL_RIGHT) {
llApplyRotationalImpulse(<0,0,-2> * myMass, TRUE);
}

if (level & CONTROL_UP) {
collective += 0.25;
}
if (level & CONTROL_DOWN) {
collective -= 0.25;
}
if (oldCollective != collective) {
//llWhisper(0, "Collective " + (string)collective);
if (llFabs(collective - 9.8) < 0.1) {
// Make sure we can always hover
collective = 9.8;
}
if (collective > 12.8) {
collective = 12.8;
} else if (collective < 7.3) {
collective = 7.3;
}
llSetForce(<0, 0, collective> * llGetMass(), TRUE);
llMessageLinked(LINK_SET, (integer)(((collective - 7.3) / 5.5) * 100.0), "throttle", NULL_KEY);
llAdjustSoundVolume(((collective - 7.3) / 5.5) * (maxSoundVolume - minSoundVolume) + minSoundVolume);
}
oldCollective = collective;
}
}

thank you
jefferey Heart
Registered User
Join date: 25 Jan 2006
Posts: 45
Hud
11-12-2006 11:28
Your Ad stated there was a HUD with this unit... It does not turn left or right very well. Very unresponsive to key strokes except for the page up and down.
Belenos Stardust
Registered User
Join date: 1 Nov 2006
Posts: 10
Sweet mother of pearl!
05-03-2007 12:26
I don't suppose you have this in keyboard control too? Or is there a way to have the control inputs be from a joystick? (I use that often in other games)

I am very interested in trying this script out also... so with your ok I am gonna save it to my harddrive as a text file.