Multimove hits v2.0
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-21-2005 05:10
The experimental-turned-popular set of scripts for making large vehicles made of multiple objects has reached version 2  What's new: - rewritten from scratch - slightly less laggy - a LOT smoother - autopilot for those big slow space cruisers - simpler to use (= less confusing, hopefully) Otherwise it's the same "drop in your objects and swoosh away" kind of set of scripts Notes:Don't use autopilot AND control in the same vehicle. "unichan" should be unique for each different vehicle, and must be the same for all the scripts across all the vehicle's objects. You can (and should) change the settings in Control and Autopilot for horizontal, vertical and rotational speeds, sit target and camera offsets. These scripts are delivered "as is", feel free to modify, copy and redistribute them as long as you permit free further modification, copy and redistribution. Autopilot script (goes into an easily accessible child prim, touch it to bring up the autopilot menu): // Multimove Autopilot // // For navigating big space cruisers
integer unichan = -599981; integer listener; integer maxl = 3; integer my_chan; integer handle; integer action; string opt; list buttons;
integer azimut; float vel; float vvel; float mul;
float speed = 1.0; float vspeed = 1.0; float rspeed = 3.0; float rate = 0.15;
integer curaz;
list angles = ["225", "270", "315", "180", "back", "0", "135", "90", "45"]; list menu = ["Turn", "Move", "SelfDestruct"]; list mv = ["Forward", "Stop", "Back", "Up", "Level", "Down", "Faster", "Slower"];
doMenu() { opt = ""; buttons = [];
if (action == 0) { opt = "Commanding:\nSpeed: " + (string)speed; buttons = menu; } else if (action == 1) { opt = "Turning to:\nCurrent: " + (string)azimut; buttons = angles; } else if (action == 2) { opt = "Moving at:\nHorizontal: " + (string)((integer)(vel*mul*100)) + "%\nVertical: " + (string)((integer)(vvel*mul*100)) + "%"; buttons = mv; } else if (action == 3) { opt = "Do you confirm SELF DESTRUCTION ?"; buttons = ["YES", "NO"]; }
llDialog(llGetOwner(), opt, buttons, my_chan); }
default { on_rez(integer p) { llSleep(2.0); llResetScript(); }
state_entry() { llSetTimerEvent(0.0); azimut = 0; curaz = 0; vel = 0.0; vvel = 0.0; mul = 1.0; action = 0; opt = ""; buttons = []; llSetText(llGetRegionName() + " @ " + (string)llGetRootPosition(), <1,1,0>, 1.0); for (listener = 0; listener < maxl; listener = listener + 1) llShout(unichan + listener, (string)(llGetRootPosition() + llGetRegionCorner()) + "*0"); }
touch_start(integer c) { if (llDetectedKey(0) != llGetOwner()) return;
llListenRemove(handle); my_chan = (integer)llFrand(llAbs(unichan) - 20) + 19; handle = llListen(my_chan, "", llGetOwner(), "");
doMenu(); }
listen(integer chan, string name, key id, string mesg) { if (action == 0) { if (mesg == "Turn") { action = 1; doMenu(); } else if (mesg == "Move") { action = 2; doMenu(); } else if (mesg == "SelfDestruct") { action = 3; doMenu(); } } else if (action == 1) { action = 0; if (mesg == "back") { doMenu(); } else { azimut = (integer)mesg; llSetTimerEvent(rate); llOwnerSay("Course set to " + mesg); } } else if (action == 2) { action = 0; if (mesg == "Forward") { vel = speed; mul = 1.0; llSetTimerEvent(rate); llOwnerSay("Engines engaged."); } else if (mesg == "Stop") { vel = 0.0; llOwnerSay("Engines stopped."); } else if (mesg == "Back") { vel = -speed; mul = 1.0; llSetTimerEvent(rate); llOwnerSay("Engines reversed."); } else if (mesg == "Up") { vvel = vspeed; mul = 1.0; llSetTimerEvent(rate); llOwnerSay("Engines engaged."); } else if (mesg == "Level") { vvel = 0.0; llOwnerSay("Engines stopped."); } else if (mesg == "Down") { vvel = -vspeed; mul = 1.0; llSetTimerEvent(rate); llOwnerSay("Engines reversed."); } else if (mesg == "Faster") { mul *= 2.0; llOwnerSay("Engine power now " + (string)((integer)(mul*100)) + "%"); } else if (mesg == "Slower") { mul /= 2.0; llOwnerSay("Engine power now " + (string)((integer)(mul*100)) + "%"); } } else if (action == 3) { if (mesg == "YES") { llSetTimerEvent(0.0); llShout(unichan, "k"); } else action = 0; } }
timer() { vector pos = vel*mul*llRot2Fwd(llGetRootRotation()) + vvel*mul*llRot2Up(llGetRootRotation()) + llGetRootPosition(); listener = (listener + 1) % maxl; if (curaz != azimut) { integer doaz = azimut - curaz; if (llAbs(doaz) <= (integer)rspeed) { curaz = azimut; } else { if(((doaz > 0) && (doaz < 180)) || (doaz < -180)) { curaz = (curaz + (integer)(mul*rspeed)) % 360; } else curaz = (curaz - (integer)(mul*rspeed)) % 360; if (curaz < 0) curaz += 360; } } else { if ((vel == 0.0) && (vvel == 0.0)) llSetTimerEvent(0.0); } llShout(unichan + listener, (string)(pos + llGetRegionCorner()) + "*" + (string)curaz); llSetText(llGetRegionName() + " @ " + (string)pos, <1,1,0>, 1.0); } }
Control script (goes into the "pilot seat" child prim, tweak the constants at the beginning to suit your vehicle) // MultiMove Controller Script // // Manages pilot seat and movement for the whole set
integer unichan = -599981; // this is the channel used by the controller and // objects to sync and move
float deltat = 0.15; // interval between updates
integer controlstaken; // control keys taken by the script, initialised later
integer listener; integer maxl = 3;
vector sitoffset = <0.2,0,-0.5>; // sitting position vector camoffset = <-24,0,9>; // camera position vector camtarget = <12,0,0>; // camera direction float speed = 1.0; // distance to move within deltat float vspeed = 0.5; // vertical distance to move within deltat integer rspeed = 3; // angle in degrees to rotate left or right within deltat
integer azimut; // direction in degrees around the Z axis (vertical)
default { on_rez(integer c) { llResetScript(); }
state_entry() { llMinEventDelay(deltat); llSitTarget(sitoffset, ZERO_ROTATION); llSetCameraAtOffset(camtarget); llSetCameraEyeOffset(camoffset); controlstaken = CONTROL_FWD|CONTROL_BACK|CONTROL_ROT_LEFT|CONTROL_ROT_RIGHT|CONTROL_LEFT|CONTROL_RIGHT|CONTROL_UP|CONTROL_DOWN; }
changed(integer c) { if (c & CHANGED_LINK) { key id = llAvatarOnSitTarget(); if (id != NULL_KEY) { if (id == llGetOwner()) { llRequestPermissions(id, PERMISSION_TAKE_CONTROLS); } else llUnSit(id); } else { llReleaseControls(); } } }
run_time_permissions(integer p) { if (p & PERMISSION_TAKE_CONTROLS) { integer n; for (n=0; n<maxl; ++n) llShout(unichan + n, (string)(llGetRootPosition() + llGetRegionCorner()) + "*" + (string)azimut);
llSleep(1.0); llTakeControls(controlstaken, TRUE, FALSE); } else { llReleaseControls(); llShout(unichan, (string)llGetRootPosition() + "*" + (string)azimut); } }
control(key id, integer pressed, integer change) { vector target = llGetRootPosition() + llGetRegionCorner(); rotation rtarget = llGetRootRotation();
if (pressed & (CONTROL_LEFT|CONTROL_ROT_LEFT)) { // turning left azimut = (azimut + rspeed) % 360; rtarget *= llEuler2Rot(<0,0,DEG_TO_RAD * (float)rspeed>); } else if (pressed & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) { // turning right azimut = (azimut - rspeed) % 360; rtarget *= llEuler2Rot(<0,0,-DEG_TO_RAD * (float)rspeed>); } if (pressed & CONTROL_FWD) { // going forward target += speed * llRot2Fwd(rtarget);
} else if (pressed & CONTROL_BACK) { // going backward target += -speed * llRot2Fwd(rtarget); } if (pressed & CONTROL_UP) { // going forward target += vspeed * llRot2Up(rtarget);
} else if (pressed & CONTROL_DOWN) { // going backward target += -vspeed * llRot2Up(rtarget); } if (pressed | change) { listener = (listener + 1) % maxl; llShout(unichan + listener, (string)target + "*" + (string)azimut); } } }
And finally, the Move script (copy three times into Move0, Move1 and Move2 and put all three in each of your vehicle's objects): // Move // // Multimove follower
integer unichan = -599981; // this is the channel used by the controller and // objects to sync
integer handle; // handle for the listen function
vector my_offset; // original offset, set at first activation rotation my_orientation; // original rotation, set at first activation integer my_num; // position in the chain of redundancy
default { on_rez(integer p) { llResetScript(); } state_entry() { my_num = (integer)llGetSubString(llGetScriptName(), -1, -1); handle = llListen(unichan + my_num, "", "", ""); } listen(integer chan, string name, key id, string mesg) { if (mesg == "k") llDie();
integer index = llSubStringIndex(mesg, "*"); my_offset = llGetPos() + llGetRegionCorner() - (vector)llGetSubString(mesg, 0, index - 1); my_orientation = llGetRot(); my_offset = my_offset / my_orientation; state running; } state_exit() { llListenRemove(handle); } }
state running { on_rez(integer p) { state default; } state_entry() { handle = llListen(unichan + my_num, "", "", ""); } listen(integer chan, string name, key id, string mesg) { if (mesg == "k") llDie(); list info = llParseString2List(mesg, ["*"], []); rotation rtarget = my_orientation * llEuler2Rot(<0,0,(float)((integer)llList2String(info, 1)) * DEG_TO_RAD>); vector target = my_offset * rtarget + (vector)llList2String(info, 0) - llGetRegionCorner(); llSetPrimitiveParams([PRIM_POSITION, target, PRIM_ROTATION, rtarget]); } state_exit() { llListenRemove(handle); } }
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-26-2005 09:24
Tested successfully in v1.7  Also, here's a remote control. Use it the same way you'd use the autopilot, except you speak to it directly on chanel 128. Format of commands: "m1" for forward, "m0" for stop, "m-1" for backward "t0" for heading East, "t90" for heading North, etc... "v1" for moving up, "v0" for level, "v-1" for moving down "f" for twice faster movement, "s" for half as fast movement Yes, it's not really easy. That's because it's meant to be used with a TLTP browser/server combo that I'll release soon  Then you can pilot your ship from the HUD. // Multimove Autopilot // // For navigating big space cruisers
integer unichan = -599981; integer listener; integer maxl = 3; integer my_chan = 128; integer handle; integer action; string opt; list buttons;
integer azimut; float vel; float vvel; float mul;
float speed = 1.0; float vspeed = 1.0; float rspeed = 3.0; float rate = 0.15;
integer curaz;
default { on_rez(integer p) { llSleep(2.0); llResetScript(); }
state_entry() { llSetTimerEvent(0.0); azimut = 0; curaz = 0; vel = 0.0; vvel = 0.0; mul = 1.0; action = 0; opt = ""; buttons = []; for (listener = 0; listener < maxl; listener = listener + 1) llShout(unichan + listener, (string)(llGetRootPosition() + llGetRegionCorner()) + "*0"); handle = llListen(my_chan, "", "", ""); }
listen(integer chan, string name, key id, string msg) { if ((llGetOwner() != id) && (llGetOwnerKey(id) != llGetOwner()) return;
string t = llGetSubString(msg, 0, 0);
if (t == "t") { azimut = (integer)llDeleteSubString(msg, 0, 0); llSetTimerEvent(rate); llOwnerSay("Course set to " + (string)azimut + " degree"); } else if (t == "s") { mul /= 2.0; llOwnerSay("Engine power now " + (string)((integer)(mul*100)) + "%"); } else if (t == "f") { mul *= 2.0; llOwnerSay("Engine power now " + (string)((integer)(mul*100)) + "%"); } else if (t == "m") { vel = (integer)llDeleteSubString(msg, 0, 0); llSetTimerEvent(rate); llOwnerSay("Engine set to " + (string)((integer)vel) + " m/s"); } else if (t == "v") { vvel = (integer)llDeleteSubString(msg, 0, 0); llSetTimerEvent(rate); llOwnerSay("Vertical set to " + (string)((integer)vvel) + " m/s"); } else if (t == "k") { llSetTimerEvent(0.0); llShout(unichan, "k"); } }
timer() { vector pos = vel*mul*llRot2Fwd(llGetRootRotation()) + vvel*mul*llRot2Up(llGetRootRotation()) + llGetRootPosition(); listener = (listener + 1) % maxl; if (curaz != azimut) { integer doaz = azimut - curaz; if (llAbs(doaz) <= (integer)rspeed) { curaz = azimut; } else { if(((doaz > 0) && (doaz < 180)) || (doaz < -180)) { curaz = (curaz + (integer)(mul*rspeed)) % 360; } else curaz = (curaz - (integer)(mul*rspeed)) % 360; if (curaz < 0) curaz += 360; } } else { if ((vel == 0.0) && (vvel == 0.0)) llSetTimerEvent(0.0); } llShout(unichan + listener, (string)(pos + llGetRegionCorner()) + "*" + (string)curaz); } }
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
11-04-2005 05:57
Here is an entirely untested version that should allow for the creation of multi-vehitar. It is a set of two scripts, control and move. Control goes into the "pilot" attachment, and move goes into one of the other AV's attachments. You should adjust positions, rotations, etc... before dropping control in the main attachment. In simpler words: with this you should be able to make a group of people fly in a formation. This should let one build a large and complex build that is litterally "glued" onto a number of AVs. If an AV gets lost and goes too far from the group (s)he cmight get back by own means by touching the attachment and getting back near the group. control: // Physical MultiVehitar Controller // // Controls weare and other avatars' position to maintain the multiple vehitar as one
integer unichan = -779991; // this is the channel used by the controller and // objects to sync and move
float deltat = 0.3; // interval between updates
integer controlstaken; // control keys taken by the script, initialised later
integer listener; integer maxl = 1;
float speed = 4.0; // distance to move within deltat float vspeed = 2.0; // vertical distance to move within deltat integer rspeed = 3; // angle in degrees to rotate left or right within deltat
float delta = 0.4;
integer azimut; // direction in degrees around the Z axis (vertical)
default { on_rez(integer c) { llResetScript(); }
state_entry() { llMinEventDelay(deltat); controlstaken = CONTROL_FWD|CONTROL_BACK|CONTROL_UP|CONTROL_DOWN; }
attach(key id) { if (id != NULL_KEY) { llRequestPermissions(id, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION); return; } else if (llGetPermissions() & PERMISSION_TAKE_CONTROLS) { llReleaseControls(); llSleep(0.5); for (listener=0; listener<maxl; listener += 1) llShout(unichan + listener, (string)(llGetRootPosition() + llGetRegionCorner()) + "*" + (string)azimut); } llStopMoveToTarget(); llStopLookAt(); }
run_time_permissions(integer p) { if (p & PERMISSION_TAKE_CONTROLS) { for (listener=0; listener<maxl; listener += 1) llShout(unichan + listener, (string)(llGetRootPosition() + llGetRegionCorner()) + "*" + (string)azimut);
llSleep(1.0); llTakeControls(controlstaken, TRUE, FALSE); llSetTimerEvent(1.0); } if (p & PERMISSION_TRIGGER_ANIMATION) { llStartAnimation("hover"); } }
control(key id, integer pressed, integer change) { vector target = llGetRootPosition(); rotation rtarget = llGetRootRotation();
llResetTime(); if (pressed & CONTROL_FWD) { // going forward target += speed * llRot2Fwd(rtarget);
} else if (pressed & CONTROL_BACK) { // going backward target += -speed * llRot2Fwd(rtarget); } if (pressed & CONTROL_UP) { // going forward target += vspeed * llRot2Up(rtarget);
} else if (pressed & CONTROL_DOWN) { // going backward target += -vspeed * llRot2Up(rtarget); } if (pressed | change) { listener = (listener + 1) % maxl; llShout(unichan + listener, (string)(target + llGetRegionCorner()) + "*" + (string)rtarget); llMoveToTarget(target, delta); } }
timer() { if (llGetTime() < 0.5) return; listener = (listener + 1) % maxl; llShout(unichan + listener, (string)(llGetRootPosition() + llGetRegionCorner()) + "*" + (string)llGetRootRotation()); } }
Move: // Move // // Physical Multimove follower
integer unichan = -779991; // this is the channel used by the controller and // objects to sync
integer handle; // handle for the listen function
float delta = 0.4;
vector my_offset; // original offset, set at first activation rotation my_orientation; // original rotation, set at first activation integer my_num; // position in the chain of redundancy
default { on_rez(integer p) { llResetScript(); } state_entry() { my_num = (integer)llGetSubString(llGetScriptName(), -1, -1); handle = llListen(unichan + my_num, "", "", ""); }
attach(key id) { if (id != NULL_KEY) { llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); } else llStopAnimation("hover"); }
run_time_permissions(integer p) { if (p) llStartAnimation("hover"); } listen(integer chan, string name, key id, string mesg) { list temp = llParseString2List(mesg, ["*"], []); my_offset = llGetPos() + llGetRegionCorner() - (vector)llList2String(temp, 0); my_orientation = llGetRot() / (rotation)llList2String(temp, 1); my_offset = my_offset / my_orientation; state running; } state_exit() { llListenRemove(handle); } }
state running { state_entry() { handle = llListen(unichan + my_num, "", "", ""); }
attach(key id) { if (id != NULL_KEY) { llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); } else llStopAnimation("hover"); }
touch_start(integer c) { if (llDetectedKey(0) == llGetOwner()) { llStopMoveToTarget(); llStopLookAt(); } }
run_time_permissions(integer p) { if (p) llStartAnimation("hover"); } listen(integer chan, string name, key id, string mesg) { list info = llParseString2List(mesg, ["*"], []); rotation rtarget = my_orientation * (rotation)llList2String(info, 1); vector target = my_offset * rtarget + (vector)llList2String(info, 0) - llGetRegionCorner(); llRotLookAt(rtarget, delta, delta); llMoveToTarget(target, delta); } state_exit() { llListenRemove(handle); } }
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
chutz Anansi
Registered User
Join date: 13 Jul 2004
Posts: 6
|
12-19-2005 20:50
Awesome script but for some reason i cannot get it to work . would someone mind helping me out on this sometime?
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
12-19-2005 23:23
To use, you need either the Control OR the Autopilot script, and 3 copies of the Move scripts. Name them Move0, Move1, and Move2.
Once your build is complete, you should Take it entirely (select it all then right-click to take) just in case, re-rez it, then drop all 3 Move scripts in EACH object that composes it. Put the Control or Autopilot script in a child prim of the most central object (Control should go in the "pilot seat" prim of your object, preferably). Don't put Control or Autopilot in the root prim with the Move scripts, else it won't work. You should reselect the whole build and take it again once the scripts are all in for convenience (so you can rez the whole build at once easily).
If you use Control, sit on the object that holds it to move the vehicle. If you use Autopilot tclick on the child prim that contains it to bring up the course menu.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Brookston Holiday
Registered User
Join date: 29 May 2005
Posts: 58
|
02-06-2006 15:16
HELP!!!
I can't seem to figure this out...
no matter what i seem to do, the scripts make my objects go to the right instead of forward when i hit forward. What am i doing wrong?
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
02-06-2006 15:32
Your central object's root prim is facing sideways. Forward is the Red arrow (= X axis), it points to the East by default.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
02-09-2006 04:54
Great news ! Now Multimove can interface with any TLTP browser using this remote script: // Multimove Autopilot // // For navigating big space cruisers
integer unichan = -599599; integer listener; integer maxl = 4; integer my_chan = 128; integer handle; string opt; list buttons;
integer azimut; integer vel; integer vvel; integer rvel; float mul;
float speed = 1.0; float vspeed = 1.0; integer rspeed = 3; float rate = 0.15;
integer curaz;
default { on_rez(integer p) { llSleep(2.0); llResetScript(); }
state_entry() { llSetTimerEvent(0.0); azimut = 0; curaz = 0; vel = 0; vvel = 0; rvel = 0; mul = 1.0; opt = ""; buttons = []; for (listener = 0; listener < maxl; listener = listener + 1) llShout(unichan + listener, (string)(llGetRootPosition() + llGetRegionCorner()) + "*0"); handle = llListen(my_chan, "", "", ""); }
listen(integer chan, string name, key id, string msg) { if ((llGetOwner() != id) && (llGetOwnerKey(id) != llGetOwner())) return;
string t = llGetSubString(msg, 0, 0);
if (t == "m") { vel = (integer)llDeleteSubString(msg, 0, 0); llSetTimerEvent(rate); llOwnerSay("Engine set to " + (string)((integer)vel) + " m/s"); } else if (t == "v") { vvel = (integer)llDeleteSubString(msg, 0, 0); llSetTimerEvent(rate); llOwnerSay("Vertical set to " + (string)((integer)vvel) + " m/s"); } else if (t == "r") { rvel = (integer)llDeleteSubString(msg, 0, 0); llSetTimerEvent(rate); } else if (t == "s") { mul /= 2.0; llOwnerSay("Engine power now " + (string)((integer)(mul*100)) + "%"); } else if (t == "f") { mul *= 2.0; llOwnerSay("Engine power now " + (string)((integer)(mul*100)) + "%"); } else if (t == "t") { azimut = (integer)llDeleteSubString(msg, 0, 0); llSetTimerEvent(rate); llOwnerSay("Course set to " + (string)azimut + " degree"); } else if (t == "k") { llSetTimerEvent(0.0); llShout(unichan, "k"); } else if (t == "h") {vel = 0; vvel = 0; rvel = 0; llSetTimerEvent(0.0); } }
timer() { vector pos = vel*mul*llRot2Fwd(llGetRootRotation()) + vvel*mul*llRot2Up(llGetRootRotation()) + llGetRootPosition(); listener = (listener + 1) % maxl; if (rvel != 0) { azimut += rvel * rspeed; }
if (curaz != azimut)
{
integer doaz = azimut - curaz;
if (llAbs(doaz) <= rspeed)
{
curaz = azimut;
} else {
if(((doaz > 0) && (doaz < 180)) || (doaz < -180))
{
curaz = (curaz + rspeed) % 360;
} else curaz = (curaz - rspeed) % 360; if (curaz < 0) curaz += 360;
}
} else {
if ((vel == 0.0) && (vvel == 0.0)) llSetTimerEvent(0.0);
} llShout(unichan + listener, (string)(pos + llGetRegionCorner()) + "*" + (string)curaz); } }
Just change "chan" to the unique channel identifier of your large vehicle. And this TLML page (along with a server script): From: someone T/-99 cMultimove Interface T|0|T#-98|8201F|<.0,.0,.0>|<.05,.05,.5>|<.25,.25,.6> T|1|C!128!m1|6321F|586383e8-4d9b-4fba-9196-2b5938e79c2c|1.5707963267949|<1,1,0>|<.05,.05,.05>|<.15,.22,.6> T|2|C!128!m-1|6321F|586383e8-4d9b-4fba-9196-2b5938e79c2c|-1.5707963267949|<1,1,0>|<.05,.05,.05>|<.15,.08,.6> T|3|C!128!r1|6321F|586383e8-4d9b-4fba-9196-2b5938e79c2c|3.14159265358979|<1,1,0>|<.05,.05,.05>|<.08,.15,.6> T|4|C!128!r-1|6221F|586383e8-4d9b-4fba-9196-2b5938e79c2c|<1,1,0>|<.05,.05,.05>|<.22,.15,.6> T|5|C!128!h|6201F|<1,1,0>|<.05,.05,.05>|<.15,.15,.6> T|6|C!128!v1|6321F|586383e8-4d9b-4fba-9196-2b5938e79c2c|1.5707963267949|<0,1,0>|<.05,.05,.05>|<.08,.22,.6> T|7|C!128!v-1|6321F|586383e8-4d9b-4fba-9196-2b5938e79c2c|-1.5707963267949|<0,1,0>|<.05,.05,.05>|<.08,.08,.6> T|8|C!128!k|6221F|38ce8b3c-fb30-5c59-9926-bd643613f606|<.667,.0,.0>|<.05,.05,.05>|<.22,.22,.6>
Change the colors in there to suit your mood 
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|