Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Rotation difficulties

Carbon Philter
Registered User
Join date: 4 Apr 2008
Posts: 165
06-13-2009 13:39
Another scripting problem, people - looking for some help for a beginner, please.

I'm making an outboard motor which is made of 3 separate prims and am trying to set up rotation from raised to lowered position when touched. Future project is to set a control button on the dashboard but for now i have enough to worry about!

With all the problems I read about with linking prims and rotation, I decided to use a derivation of the timeless door script which Amaranthim Talon posted in a thread I found in the Forum ( /327/41/302717/1.html) which seems to do what's needed in respect of rotation for each of the three elements of the engine pretty neatly. The before and after states have all been fed in and they behave as expected.

The problem is that the three components need to be touched individually to effect the rotation. Saying 'open' and 'closed' as commands in chat makes them move as a group the way I want, but I'd like to have them all move when any one of the three parts is touched and think it has to do with IImessagelinked, but don't know how to set it up.

Could someone out there give me a steer in the right direction with what/where to insert in the script to interlink the touch event trigger, please?

Thanks for any advice.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-13-2009 17:15
what you can do, is move the code from your listen version to a link_message event handler (minus any filtering for avatars)...

then in your touch event, have it call llMessageLinked with your former chat message, sent with LINK_SET... each script will respond to it and all move (mostly at the same time, into their new position.

I'm not sure what all you may have kept from the timeless script, hopefully just the rotation stuff.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Carbon Philter
Registered User
Join date: 4 Apr 2008
Posts: 165
06-14-2009 06:28
Thanks Void.
Had hoped for a bit more detail - example maybe - but I sort of understand where you're directing me. Just need a few more long nights getting my head around it.

I just about understood Sinclair Spectrum Basic. This LSL stuff is way harder!!
:D
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-14-2009 09:12
post the original (or at least your listener code) and I'm sure one of us will tweak it in example.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Carbon Philter
Registered User
Join date: 4 Apr 2008
Posts: 165
06-16-2009 03:39
Hi Void, and others.
I've been worrying at this llMessageLinked thing for a good while now but don't seem to be getting my head round it and would very much appreciate some help.
I've been trying to dissect the timeless door script which has touchstart and voice control, and also appears to have messagelinked control for a remote control but I'm way out of my comprehension comfort zone, and can't work out how to mod the link_message component to act when the message is sent from the touched remote prim.

Apologies in advance for length of post - the door script is not short!

I started with Jopsy's Touch Toggle Controller in the prim which sends off/on message and understand the function of this. (For brevity, I've omitted some of Jopsy's comment text):

//// "Touch Toggle" CONTROLLER TEMPLATE v1 - by Jopsy Pendragon - 4/8/2008
//// You are free to use this script as you please, so long as you include this line:
//** The original 'free' version of this script came from THE PARTICLE LABORATORY. **//
// EFFECT: 'Touching' this prim will ACTIVATE or DEACTIVE particles.
// SETUP: Drop this CONTROLLER TEMPLATE script into any prim of the same
// linked object as your PARTICLE TEMPLATE. It should be responsive immediately.

integer PLAY_SOUND = TRUE; // TRUE for a click-sound, FALSE for silent.
string SOUND = "bac3e333-9624-4b1a-ade2-d2b01d5960aa"; // a click sound

string CONTROLLER_ID = "B"; // see more about CONTROL TEMPLATES at end.
integer mode = 0; // keep track of whether particles are ON(1) or OFF(0).
default {
touch_start(integer total_number) {
if ( PLAY_SOUND ) llPlaySound( SOUND, 0.5 );
mode = ! mode; // flip on to off, (or off to on).
llMessageLinked( LINK_SET, mode, CONTROLLER_ID, NULL_KEY ); // send command
}
// Listen for other controllers sending ON/OFF commands and remember changes:
link_message( integer sibling, integer num, string controller_id, key ignore ) {
if ( controller_id != CONTROLLER_ID ) return; // this message is not for us.
mode = num;
}
}

The door will need to have the matching link_message received and acted on, and this is where I lose it. I pulled what I think to be the relevant bit from another of Jopsy's particle scripts on the basis that I could apply the on/off toggle effect to the required open/close action by changing the llParticleSystem line to something else:

link_message( integer sibling, integer num, string mesg, key target_key ) {
if ( mesg != CONTROLLER_ID ) { // this message isn't for me. Bail out.
return;
} else if ( num == 0 ) { // Message says to turn particles OFF:
llParticleSystem( [ ] );
} else if ( num == 1 ) { // Message says to turn particles ON:
llParticleSystem( particle_parameters + target_parameters );
} else if ( num == 2 ) { // Turn on, and remember and use the key sent us as a target:
target_parameters = [ PSYS_SRC_TARGET_KEY, target_key ];
llParticleSystem( particle_parameters + target_parameters );
} else { // bad instruction number
// do nothing.
}
}

I've looked through the door script what seems like countless times now to try and work out where/how to mod it and insert the link-message control. Looking at the touch-start portion, I think it's got something to do with myToggleDoor but am stumped - I obviously haven't mastered anything other than the absolute basics!
Any assistance would be welcomed. I'm happy to talk in-world if that's easier than megalength posts

I've attached an abbreviated copy of the door script below.

Thanks
Carbon



string doorOpenSound = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
string doorCloseSound = "e7ff1054-003d-d134-66be-207573f2b535";
string confirmedSound = "69743cb2-e509-ed4d-4e52-e697dc13d7ac";
string accessDeniedSound = "58da0f9f-42e5-8a8f-ee51-4fac6c247c98";
string doorBellSound = "ee871042-e272-d8ec-3d40-0b0cb3371346"; // Setting to empty stops door announcements too.
float autoCloseTime = 120.0; // 0 seconds to disable auto close.
integer allowGroupToo = TRUE; // Set to FALSE to disallow same group access to door.
list allowedAgentUUIDs = ["8efecbac-35de-4f40-89c1-2c772b83cafa"]; // Comma-separated, quoted list of avatar UUIDs who are allowed access to this door.
integer listenChannel = 0;
string CONTROLLER_ID = "B"; // See comments at end regarding CONTROLLERS.
integer AUTO_START = FALSE; // Optionally FALSE only if using CONTROLLERS.

//------------------------------------------------------
// Leave the rest of the settings alone, these are
// handled by the script itself.
//------------------------------------------------------
integer isLocked = FALSE; // Only when the door is locked do the permissions apply.
integer isOpen = TRUE;
vector openPos = ZERO_VECTOR;
rotation openRot = ZERO_ROTATION;
vector openScale = ZERO_VECTOR;
vector closedPos = ZERO_VECTOR;
rotation closedRot = ZERO_ROTATION;
vector closedScale = ZERO_VECTOR;
key openerKey = NULL_KEY;
key closerKey = NULL_KEY;
integer isSetup = FALSE;
integer listenHandle = 0;
string avatarName = "";
string action;

list target_parameters=[]; // remembers targets found using TARGET TEMPLATE scripts.
integer mode = 0; // keep track of whether particles are ON(1) or OFF(0).

// code string used for the parameter encoding/decoding
string code68 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX YZ0123456789@$#&!?";

mySayName(integer channel, string objectName, string message)
{
string name = llGetObjectName();
llSetObjectName(objectName);
llSay(0, "/me " + message);
llSetObjectName(name);
}

mySay(integer channel, string message)
{
string name = llGetObjectName();
llSetObjectName("Door";);
llSay(0, message);
llSetObjectName(name);
}

myOwnerSay(string message)
{
string name = llGetObjectName();
llSetObjectName("Door";);
llOwnerSay(message);
llSetObjectName(name);
}

mySoundConfirmed()
{
if (confirmedSound != "";)
{
llTriggerSound(confirmedSound, 1.0);
}
}

mySoundAccessDenied()
{
if (accessDeniedSound != "";)
{
llTriggerSound(accessDeniedSound, 1.0);
}
}

myGetDoorParams()
{
isSetup = FALSE;
if (llSubStringIndex(llGetObjectDesc(), "door:";) == 0)
{
string s = llGetObjectDesc();
integer k = 5;

openPos.x = decode_float( llGetSubString(s,k,k+4) ); k += 5;
etc. etc. etc.....................
.............
closedScale.z = decode_float( llGetSubString(s,k,k+4) ); k += 5;

isSetup = TRUE;
}
else
{
myOwnerSay("The door prim's description is empty of has invalid syntax. Delete the door prim's description and setup the door prim again.";);
}

}

mySetDoorParams(vector openPos, rotation openRot, vector openScale, vector closedPos, rotation closedRot, vector closedScale)
{
string s = "door:";

s += encode_float(openPos.x);
etc. etc etc..............................
..............................................
s += encode_float(closedScale.z);

llSetObjectDesc(s);

isSetup = TRUE;
mySay(0,"Parameters are stored";);
}

integer myPermissionCheck(key id)
{
integer hasPermission = FALSE;
if (isLocked == FALSE)
{
hasPermission = TRUE;
}
else if (llGetOwnerKey(id) == llGetOwner())
{
hasPermission = TRUE;
}
else if (allowGroupToo == TRUE && llSameGroup(id))
{
hasPermission = TRUE;
}
else if (llListFindList(allowedAgentUUIDs, [(string)id]) != -1)
{
hasPermission = TRUE;
}
return hasPermission;
}

myOpenDoor()
{
isOpen = FALSE;
myToggleDoor();
}

myCloseDoor()
{
isOpen = TRUE;
myToggleDoor();
}

myToggleDoor()
{
if (isSetup == FALSE)
{
myOwnerSay("The door prim has not been configured yet. Please read the usage instructions in the door script.";);
}
else if (llGetLinkNumber() == 0 || llGetLinkNumber() == 1)
{
myOwnerSay("The door prim must be linked to at least one other prim and the door prim must not be the root prim";);
}
else
{
isOpen = !isOpen;
if (isOpen)
{
if (doorBellSound != "";)
{
llTriggerSound(doorBellSound, 1.0);
if (avatarName != "";)
{
mySayName(0, avatarName, "is at the door.";);
avatarName = "";
}
}
if (doorOpenSound != "";)
{
llTriggerSound(doorOpenSound, 1.0);
}
llSetPrimitiveParams([ PRIM_POSITION, openPos, PRIM_ROTATION, ZERO_ROTATION * openRot / llGetRootRotation(), PRIM_SIZE, openScale ]);
// Door API.
llMessageLinked(LINK_SET, 255, "cmd|door|opened", NULL_KEY);
}
else
{
if (doorCloseSound != "";)
{
llTriggerSound(doorCloseSound, 1.0);
}
llSetPrimitiveParams([ PRIM_POSITION, closedPos, PRIM_ROTATION, ZERO_ROTATION * closedRot / llGetRootRotation(), PRIM_SIZE, closedScale ]);
// Door API.
llMessageLinked(LINK_SET, 255, "cmd|door|closed", NULL_KEY);
}

llSetTimerEvent(0.0);
if (isOpen == TRUE && autoCloseTime != 0.0)
{
llSetTimerEvent(autoCloseTime);
}
}
}

//================================================== ========================
// encode a float with 7 digits precision into a 5-character string
// minimum=1e-31, maximum=1e+31
// example: 1.234567 --> "hAM70"
//================================================== ========================

.........................................omitted for brevity

//================================================== ========================
// decode a 5-character string into a float with 7 digits precision
// example: "hAM70" --> 1.234567
//================================================== ========================

...........................................omitted for brevity

default
{
state_entry()
{
listenHandle = llListen(listenChannel, "", NULL_KEY, "";);
myGetDoorParams();
}

touch_start(integer total_number)
{
if (myPermissionCheck(llDetectedKey(0)) == TRUE)
{
avatarName = llDetectedName(0);
myToggleDoor();
}
else
{
mySoundAccessDenied();
}
}

timer()
{
myCloseDoor();
}

//link_message(integer sender_num, integer num, string str, key id)
//{
// Door API. The API is here in case you want to create PIN entry keypads or whatever.
//if (num == llGetLinkNumber())
//{
//if (str == "cmd|door|doOpen";)
//{
//myOpenDoor();
//}
//else if (str == "cmd|door|doClose";)
//{
//myCloseDoor();
//}
//}
//if (str == "cmd|door|discover";)
//{
//llMessageLinked(LINK_SET, 255, "cmd|door|discovered|" + (string)llGetKey(), id);
//}
//}


listen(integer channel, string name, key id, string message)
{
// Performance note: it's quicker to compare the strings than to compare
// permissions each time anyone says anything on this channel.
if (message == "open";)
{
if (myPermissionCheck(id) == TRUE)
{
// Only open the door if the person is quite close to this door.
openerKey = id;
closerKey = NULL_KEY;
avatarName = name;
llSensor(name, id, AGENT, 5.0, TWO_PI);
}
else
{
mySoundAccessDenied();
}
}
else if (message == "close";)
{
if (myPermissionCheck(id) == TRUE)
{
openerKey = NULL_KEY;
closerKey = id;
avatarName = name;
// Only close the door if the person is quite close to this door.
llSensor(name, id, AGENT, 5.0, TWO_PI);
}
else
{
mySoundAccessDenied();
}
}
else if (message == "lock";)
{
if (myPermissionCheck(id) == TRUE)
{
isLocked = TRUE;
mySoundConfirmed();
}
else
{
mySoundAccessDenied();
}
}
else if (message == "unlock";)
{
if (myPermissionCheck(id) == TRUE)
{
isLocked = FALSE;
mySoundConfirmed();
}
else
{
mySoundAccessDenied();
}
}
else if (message == "/door opened" && llSubStringIndex(llGetObjectDesc(), "door:";) == -1)
{
if (llGetOwnerKey(id) == llGetOwner())
{
mySoundConfirmed();
openPos = llGetLocalPos();
openRot = llGetLocalRot();
openScale = llGetScale();
isOpen = TRUE;
if (! (closedPos == ZERO_VECTOR && closedRot == ZERO_ROTATION && closedScale == ZERO_VECTOR))
{
mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale);
}
}
else
{
mySoundAccessDenied();
}
}
else if (message == "/door closed" && llSubStringIndex(llGetObjectDesc(), "door:";) == -1)
{
if (llGetOwnerKey(id) == llGetOwner())
{
mySoundConfirmed();
closedPos = llGetLocalPos();
closedRot = llGetLocalRot();
closedScale = llGetScale();
isOpen = FALSE;
if (! (openPos == ZERO_VECTOR && openRot == ZERO_ROTATION && openScale == ZERO_VECTOR))
{
mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale);
}
}
else
{
mySoundAccessDenied();
}
}
}

sensor(integer num_detected)
{
if (openerKey != NULL_KEY)
{
integer i;
for (i = 0; i < num_detected; i++)
{
if (llDetectedKey(i) == openerKey && myPermissionCheck(llDetectedKey(i)) == TRUE)
{
myOpenDoor();
}
}
openerKey = NULL_KEY;
}
else
{
integer i;
for (i = 0; i < num_detected; i++)
{
if (llDetectedKey(i) == closerKey && myPermissionCheck(llDetectedKey(i)) == TRUE)
{
myCloseDoor();
}
}
closerKey = NULL_KEY;
}
}
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-16-2009 06:38
I'm going to presume that the touch even is the one sought after in this script. here's the original code segment....

CODE

touch_start(integer total_number)
{
if (myPermissionCheck(llDetectedKey(0)) == TRUE)
{
avatarName = llDetectedName(0);
myToggleDoor();
}
else
{
mySoundAccessDenied();
}
}


and here's what you do to it...

CODE

touch_start(integer total_number){
if (myPermissionCheck( llDetectedKey( 0 ) ) == TRUE){
avatarName = llDetectedName( 0 );
llMessgaLinked( LINK_SET, 0, "safetyString", "" );
}
else{
mySoundAccessDenied();
}
}

link_message( integer vInt, integer vIntNull, string vStrCheck, key vKey ){
if ("safetyString" == vStrCheck){
myToggleDoor();
}
}


safetyString could be any text, it's just to make sure that the data coming in is something this script wants to act on, and not some other data from/for a different script

PS you really shouldn't use the timeless script for this, there are other scripts more suited to it, including other plain door scripts, or any of the incremental orbit scripts
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Carbon Philter
Registered User
Join date: 4 Apr 2008
Posts: 165
06-16-2009 08:11
Thanks for reply, Void.

I was going towards the Timeless Door script as it's for rotating a sculpty which doesn't have the correct centre of rotation for what I wanted.

Innula Zenovka was kind enough to contact me in-world and help me out with another - hopefully simpler - door script which does the same re. the rotation centre, and I'm presently worrying that one to death.

I'd like to ultimately get my head round all the complexities of the Timeless script as part of the learning LSL process but I admit it's a challenge and a half for a novice scripter!

This Forum has my vote for helpfulness so thanks again to all.

Carbon