Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Controlling my relay

Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-02-2004 20:48
Goshua wrote a great relay script for me to help with my elevator platform in the sky project... The code is below. I need help in stopping it from repeating what it hears too many times. Right now what's going on is each relay, there are 6, is hearing the command and it is successfuly relayed to the elevator platform. I was able to call the elevator from 230m in the sky to the ground using the relay.

The problem is that the relays continually blast the command to the elevator. I had to put them in channel 0 to figure this out, and all 6 relays just kept shouting "goto floor 1" which is the command that the elevator call button on the ground successfully passed all the way up the relay.

How can I make it so that each relay repeats the command once and only once?


CODE
//Relay Script  0.9
//By Goshua Lament
//DESCRIPTION: Repeats messages heard on a specific channel. Useful for debugging and long distance chat.
//Free to modify and distribute. Please keep it free.

string outmessage; //Message that is said. Set by script
integer channel=1001; //Set channel that script runs on
float delay=6.0; //Sets delay

default
{
state_entry()
{
llListen(channel,"",NULL_KEY, ""); //Sets script to listen on proper channel
llMinEventDelay(delay);
}

listen(integer channel, string name, key id, string message)
{
string outmessage=message;
llShout(channel, outmessage); //Repeats what it hears. Can be changed to whisper, say, or shout. Replace the channel variable with a 0 to hear messages on a channel on public. Useful for debugging.
}

}
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-02-2004 21:25
Ok, I still need help getting the script to repeat each command once and only once, but here's something I added.

I added a "data conduit" along side my elevator shaft and created a separate up/down stream for commands.

The main shaft relays data up, and my secondary conduit relays data down.

For example, the relays going up only listen to the relay below it and only speak on a channel the relay above it is listening on.

Vice versa for the conduit carrying data back down.

This prevents the relays from spamming all over the place, since each relay is now only listening to and only speaking to one other object.

My problem is still that they keep hearing the command in their channel and repeating it over and over, confusing the living hell out of the elevator, especially when a command to bring the elevator back down is given and the up conduit is still telling it to go to the top level.

:confused:
Goshua Lament
Registered User
Join date: 25 Dec 2003
Posts: 703
07-02-2004 21:33
Wow! Thanks for quoting my script. Just to clue new readers in, this script relays a command to call an elevator 250 meters in the air to the ground level. The original thread. A possible soloution would be to have the relay "freeze" itself for several seconds so that it does not hear the message again and again. Stylez Gomez suggested that we use llMessageLinked. I'll give that a try in another script version. Any other ideas, scripters?

EDIT: How would I do this with llLMessageLinked?
_____________________
Flickr Second Life Photo Gallery

I no longer regularly login to SecondLife, but please contact me if an issue arises that needs my attention.
Carnildo Greenacre
Flight Engineer
Join date: 15 Nov 2003
Posts: 1,044
07-02-2004 23:21
My solution for the relay system used for the first Impromptu Road Race was for each relay to keep a record of the last message it had sent. Each message included a timestamp, and the relays would never say the same message twice in a row.
_____________________
perl -le '$_ = 1; (1 x $_) !~ /^(11+)\1+$/ && print while $_++;'
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-02-2004 23:29
I briefly thought about timestamps, but didn't go anywhere with. That makes perfect sense!

Could you share your code with me on that?
Darwin Appleby
I Was Beaten With Satan
Join date: 14 Mar 2003
Posts: 2,779
07-02-2004 23:43
This is a breathing commandment for llWriteNotecardLine.

I'd reccomend storing them in a list, maybe.
_____________________
Touche.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-02-2004 23:55
From: someone
Originally posted by Darwin Appleby
This is a breathing commandment for llWriteNotecardLine


Actually, this looks more like a breathing commandment for working, fast, object2object communication. (a.k.a. outbound XMLRPC)
==Chris
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-03-2004 00:11
Whaaaa?

The last two comments went over my head! :confused:

Isn't XMLRPC for communicating with servers outside SL?
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-03-2004 00:12
From: someone
Originally posted by Aaron Levy
I briefly thought about timestamps, but didn't go anywhere with. That makes perfect sense!

Could you share your code with me on that?


Im not Carnildo, but I think I know how to solve your problem with a quick modification of the code you posted.

CODE

//Relay Script 0.9
//By Goshua Lament
//Modifyed by Christopher Omega
//DESCRIPTION: Repeats messages heard on a specific channel. Useful for debugging and long distance chat.
//Free to modify and distribute. Please keep it free.

// This is the string that seperates the timestamp and the real message sent.
// Make this as unique as possible.
string TIMESTAMP_SEPERATOR = "|~|";

integer channel=1001; //Set channel that script runs on
float delay=6.0; //Sets delay

// The timestamp of the previous message heard by this script.
integer prevTimestamp = 0;

// This function seperates out the code necessary for extracting the timestamp from the relayed message.
integer extractTimestampFrom(string message)
{
// Seperates 'message' into two seperate entities:
// the timestamp and the real message.
list stampSeperate = llParseString2List(message, [TIMESTAMP_SEPERATOR], []);

return (integer) llList2String(stampSeperate, 0);
}

default
{
state_entry()
{
llListen(channel,"",NULL_KEY, ""); //Sets script to listen on proper channel
llMinEventDelay(delay);
}

listen(integer channel, string name, key id, string message)
{
integer timestamp = extractTimestampFrom(message);
if (timestamp != prevTimestamp)
{
llShout(channel, message); //Repeats what it hears. Can be changed to whisper, say, or shout. Replace the channel variable with a 0 to hear messages on a channel on public. Useful for debugging.
}
}

}


However, with this code, you need to modify how you send messages into the system. All *new* messages need to have a timestamp put on them before they are said.

Here's a function that does it for you, just replace "llShout" with "shout":

CODE

// This is the string that seperates the timestamp and the real message sent.
// Make sure this as unique as possible and that the
// TIMESTAMP_SEPERATOR in the repeaters is identical to this one.
string TIMESTAMP_SEPERATOR = "|~|";

shout(integer channel, string message)
{
llShout(channel, (string) llGetWallclock() + TIMESTAMP_SEPERATOR + message);
}


EDIT: Seperated timestamp extraction code from the listen event into its own function. (The previous code functions identically, this change is only done to improve readability).
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-03-2004 00:18
From: someone
Originally posted by Aaron Levy
Whaaaa?

The last two comments went over my head! :confused:

Isn't XMLRPC for communicating with servers outside SL?


Currently, XML-RPC can only be used when an outside computer starts the conversation, this type of XML-RPC is called "inbound" XML-RPC, since outside computers are sending data "in" to SL first. In the (hopefully not-to-distant) future, LL will give us the ability to start the conversation with LSL scripts. This type of XML-RPC is called "outbound" XMLRPC, since scripts inside are sending data "out" into the world from SL. It doesnt matter who the conversation is between, it can be between two scripts (need outbound though, since scripts cant start convos) or an outside computer and a script (possible now).
==Chris
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-03-2004 00:34
Cool! Thanks for the help Christopher! Can't wait to get in and try this out, but it's 3:30 AM here... I need sleep!!

One quick question to clarify XMLRPC, please.

So right now, I could have my web server send data to a prim in game... if the outside server starts the conversation, can the prim in the game respond out to it? Or is only one-way right now (outside -> in).

Assuming they do implent full inbound-outbound communication, my problem could be solved by having the call elevator button tell my webserver to send a message to the elevator, telling it to go to the ground floor (or whatever floor its needed at)?

If that's the case... um... what are they waiting for?! :)
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-03-2004 00:48
*baleted* see below
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-03-2004 00:54
I switched the channel to 0 on the elevator button and the first relay to see what's being sent. "Call Transport Two" is the call button.

Call Transport Two shouts: 3019.000000|~|goto floor 1
relay 1 shouts: 3019.000000|~|goto floor 1

From what I can tell, the routine that is supposed to separate the timestamp from the actual message isn't working, and the entire string is being shouted out loud, instead of just the message.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-03-2004 01:21
From: someone
Originally posted by Aaron Levy
How can I make the elevator hear and recognize that "goto floor 1" no matter what else is before it?


That depends on how you filter your messages. If your using an elevator, I suspect you open 1 listen handle on the specific channel you want, then filter in your listen event.

In that case, your code looks something like this:

CODE

default
{
state_entry()
{
llListen(channel, "", "", "");
}
listen(integer channel, string name, key id, string message) {
// Check if the message begins with "goto floor".
if (llGetSubString(message, 0, 9) == "goto floor")
{
// Get the result of deleting "goto floor " from the message.
integer floorNumber = (integer) llDeleteSubString(message, 0, 10);
// etc...
}
}
}


What you need to do is perform the same extraction process the relays do to get the timestamp from the message, except you want to get the message without the timestamp. I've edited the relay script to make that extraction process more noticable.

Here's how you can do that:
CODE

// This is the string that seperates the timestamp and the real message sent.
// Make sure this as unique as possible and that the
// TIMESTAMP_SEPERATOR in the repeaters is identical to this one.
string TIMESTAMP_SEPERATOR = "|~|";

// Extracts the "true" message sent
// through the relay system.
string extractMessageFrom(string relayData) {
list stampSeperate = llParseString2List(relayData, [TIMESTAMP_SEPERATOR], []);

return llList2String(stampSeperate, 1);
}

default
{
state_entry()
{
llListen(channel, "", "", "");
}
listen(integer channel, string name, key id, string message) {
message = extractMessageFrom(message);
// Check if the message begins with "goto floor".
if (llGetSubString(message, 0, 9) == "goto floor")
{
// Get the result of deleting "goto floor " from the message.
integer floorNumber = (integer) llDeleteSubString(message, 0, 10);
// etc...
}
}
}


The red line is all you need to add to your elevator script's listen event. Make sure it is above all other code in the listen event, or some may be exposed to the "raw" message coming directly from the relay system.

==Chris
EDIT: Typo :o
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-03-2004 01:31
From: someone
Originally posted by Aaron Levy
So right now, I could have my web server send data to a prim in game... if the outside server starts the conversation, can the prim in the game respond out to it? Or is only one-way right now (outside -> in).

Yes, the prim can in game can reply to data sent to it from the outside source. Many people are attempting to get around the lack of outbound XML-RPC by implementing a polling mechanism, where the outside source occasionally polls the script in world, asking it if it wants to send any data out. This workaround has some flaws. Eventually, if the outside source is responsible for maintaining many script's connections, it will be swamped with its polling duties. Also, if it caught on enough, polling would create massive amounts of unnecessarry network traffic that would severely affect the Linden's XMLRPC server.

From: someone
Originally posted by Aaron Levy
Assuming they do implent full inbound-outbound communication, my problem could be solved by having the call elevator button tell my webserver to send a message to the elevator, telling it to go to the ground floor (or whatever floor its needed at)?


If you would be willing to sync the button and the elevator (the button needs to know the elevator's RPC UUID) your webserver wouldn't even need to be a part of the process.

==Chris

EDIT: Oops! Forgot this last one:
From: someone
Originally posted by Aaron Levy
If that's the case... um... what are they waiting for?! :)


There is some security concerns with letting scripts have direct access to the internet. Most of it has already been discussed by members of the community. Here's a weblink to that discussion:

http://www.badgeometry.com/wiki/XMLRPCDiscussion

Basicly, if scripts had direct, un-filtered access, there would be no stopping GrieferBoi1101 Smith from scripting a massive Denial of Service attack against an unsuspecting webserver. Since the attack came from a script in-world, the owners of the targeted webserver would point fingers at Linden Lab.
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-03-2004 01:44
I'm sorry... I can't make heads or tails of the elevator scripts... it's one being distributed at the GNU store with their tower in a box package... Because I learn best by example, I'm going to post it here and kindly ask that you show me where the changes need to be made. Thanks for all your help!

CODE
vector  alignment;
vector targetVector;
integer travelDistance;
integer publicListen;
integer privateListen;
integer privateChannel = 1001;
integer targetFloor;
list floorHeights = [22,211.500];
float fixedFloorHeight = -1; //Set to floor heights, or set to -1 to use floorHeights list
float speed = 1; //Valid values are 0.01 to 1.0, a Percentage of maxSpeed;
float maxSpeed = 125;
float precision = 0.5;
integer autoSpeed = TRUE;
integer initialDistance;
float lastRelayTime;
integer TTL = 5;

elevate (vector end)
{
vector current = llGetPos();
travelDistance = llRound(current.z-end.z);
travelDistance = llAbs(travelDistance);

if (autoSpeed)
{
if (travelDistance < (initialDistance / 2))
{
speed -= (precision / 50);
if (speed < 0.25)
speed = 0.25;
}
else
{
speed += (precision / 25);
if (speed > 1)
speed = 1;
}
}
if (travelDistance > 30)
{
travelDistance = 30;
if (end.z > current.z)
{
end.z = current.z + 30;
}
else
{
end.z = current.z - 30;
}
}
float i = travelDistance/(maxSpeed*speed);
llMoveToTarget(end,i);
}

GotoFloor (integer floor, key id)
{
if (floor == 0)
{
llSay(0, "Moving to Ground");
}
else
{
llSay(0, "Going to Heaven!");
// llSay(0, "Moving to Floor#" + (string)(floor+ 1));
}
llSetStatus(STATUS_PHYSICS, TRUE);
llLoopSound("ElevatorNoises", 1);

targetFloor = floor;

if (fixedFloorHeight > 0)
{
targetVector = alignment;
targetVector.z = alignment.z + (fixedFloorHeight * floor);
}
else
{
targetVector = alignment;
targetVector.z = llList2Float(floorHeights, floor);
}
llSay(0, "At " + (string)((integer)targetVector.z) + " Meters...");

vector current = llGetPos();
initialDistance = llRound(current.z-targetVector.z);
initialDistance = llAbs(initialDistance);

if (autoSpeed)
{
speed = 0.01;
}

elevate(targetVector);
llSetTimerEvent(precision);
}

reset()
{
lastRelayTime = llGetTimeOfDay();
llSay(0, "Resetting Elevator...");
llSetStatus(STATUS_ROTATE_X| STATUS_ROTATE_Y| STATUS_ROTATE_Z, FALSE);

alignment = llGetPos();
llSetStatus(STATUS_PHYSICS, FALSE);
llStopSound();
llListenRemove(publicListen);
llListenRemove(privateListen);
// CHANGE publicListen = llListen(0, "", NULL_KEY, "");
publicListen = llListen(1100, "", NULL_KEY, "");
privateListen = llListen(privateChannel, "", NULL_KEY, "");
}
default
{
state_entry()
{
reset();
}
object_rez(key id)
{
llResetScript();
}
listen(integer a, string n, key id, string m)
{
vector pos;
integer Floor;
float tempFloat;
list tempList;


if ((a == privateChannel) && ((llGetTimeOfDay() - lastRelayTime) > TTL))
{
lastRelayTime = llGetTimeOfDay();
tempList = llCSV2List(m);
m = llList2String(tempList, 1);
}

if (llSubStringIndex(m, "goto floor") == 0)
{
lastRelayTime = llGetTimeOfDay();
Floor = (integer)llGetSubString(m, 10, llStringLength(m)) - 1;

if (Floor < 0) Floor = 0;
if (Floor > 9) Floor = 9;

GotoFloor(Floor, NULL_KEY);
}
if (llSubStringIndex(m, "speed") == 0)
{
tempFloat = (float)llGetSubString(m, 5, llStringLength(m));
if ((tempFloat > 0.001) && (tempFloat <= 1.0))
{
speed = tempFloat;
}
}
if ((m=="elevator reset") && (id==llGetOwner()))
{
reset();
}
}

timer()
{
vector CurrentPos;
float tempfloat;

CurrentPos = llGetPos();
tempfloat = (CurrentPos.z - targetVector.z);

if (llFabs(tempfloat) < 2)
{
if (llFabs(tempfloat) < 0.05)
{
//Arrived at Floor
llSetTimerEvent(0);
if (targetFloor == 0)
{
llSay(0, "Welcome Back!");
}
else
{
llSay(0, "Welcome to Heaven!");
// llSay(0, "Arrived at Floor #" + (string)(targetFloor+1));
}
llSetStatus(STATUS_PHYSICS, FALSE);
llStopSound();
}
else
{
llMoveToTarget(targetVector,1.0);
}
}
else
{
if (fixedFloorHeight > 0)
{
targetVector = alignment;
targetVector.z = alignment.z + (fixedFloorHeight * targetFloor);
}
else
{
targetVector = alignment;
targetVector.z = llList2Float(floorHeights, targetFloor);
}
elevate(targetVector);
}
}
}


If there's anything I can do in return for your help, let me know.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-03-2004 02:06
Hmm. What exactly is relayed? Just the "go to floor" command?
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
07-03-2004 05:15
Why are people still using complicated relay systems instead of llEmail?
Goshua Lament
Registered User
Join date: 25 Dec 2003
Posts: 703
07-03-2004 08:42
From: someone
Originally posted by Eggy Lippmann
Why are people still using complicated relay systems instead of llEmail?



Doesnt llEmail cause the script to freeze for a minute before it sends? Or is it after? Waiting 1 minute for the elevator would not be good.
_____________________
Flickr Second Life Photo Gallery

I no longer regularly login to SecondLife, but please contact me if an issue arises that needs my attention.
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-03-2004 08:47
Goshua's exactly right, Eggy... When you use llEmail it causes an automatic 20 second delay -- WAY WAY too long to wait for an elevator that can get to it's destination is 4-5 seconds.

---

Yes, Christopher, the only thing that needs relayed is the "goto floor x" comand.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-03-2004 14:20
From: someone
Originally posted by Aaron Levy
Yes, Christopher, the only thing that needs relayed is the "goto floor x" comand.


In that case, this code should work:

CODE

vector alignment;
vector targetVector;
integer travelDistance;
integer publicListen;
integer privateListen;
integer privateChannel = 1001;
integer targetFloor;
list floorHeights = [22,211.500];
float fixedFloorHeight = -1; //Set to floor heights, or set to -1 to use floorHeights list
float speed = 1; //Valid values are 0.01 to 1.0, a Percentage of maxSpeed;
float maxSpeed = 125;
float precision = 0.5;
integer autoSpeed = TRUE;
integer initialDistance;
float lastRelayTime;
integer TTL = 5;

elevate (vector end)
{
vector current = llGetPos();
travelDistance = llRound(current.z-end.z);
travelDistance = llAbs(travelDistance);

if (autoSpeed)
{
if (travelDistance < (initialDistance / 2))
{
speed -= (precision / 50);
if (speed < 0.25)
speed = 0.25;
}
else
{
speed += (precision / 25);
if (speed > 1)
speed = 1;
}
}
if (travelDistance > 30)
{
travelDistance = 30;
if (end.z > current.z)
{
end.z = current.z + 30;
}
else
{
end.z = current.z - 30;
}
}
float i = travelDistance/(maxSpeed*speed);
llMoveToTarget(end,i);
}

GotoFloor (integer floor, key id)
{
if (floor == 0)
{
llSay(0, "Moving to Ground");
}
else
{
llSay(0, "Going to Heaven!");
// llSay(0, "Moving to Floor#" + (string)(floor+ 1));
}
llSetStatus(STATUS_PHYSICS, TRUE);
llLoopSound("ElevatorNoises", 1);

targetFloor = floor;

if (fixedFloorHeight > 0)
{
targetVector = alignment;
targetVector.z = alignment.z + (fixedFloorHeight * floor);
}
else
{
targetVector = alignment;
targetVector.z = llList2Float(floorHeights, floor);
}
llSay(0, "At " + (string)((integer)targetVector.z) + " Meters...");

vector current = llGetPos();
initialDistance = llRound(current.z-targetVector.z);
initialDistance = llAbs(initialDistance);

if (autoSpeed)
{
speed = 0.01;
}

elevate(targetVector);
llSetTimerEvent(precision);
}

reset()
{
lastRelayTime = llGetTimeOfDay();
llSay(0, "Resetting Elevator...");
llSetStatus(STATUS_ROTATE_X| STATUS_ROTATE_Y| STATUS_ROTATE_Z, FALSE);

alignment = llGetPos();
llSetStatus(STATUS_PHYSICS, FALSE);
llStopSound();
llListenRemove(publicListen);
llListenRemove(privateListen);
// CHANGE publicListen = llListen(0, "", NULL_KEY, "");
publicListen = llListen(1100, "", NULL_KEY, "");
privateListen = llListen(privateChannel, "", NULL_KEY, "");
}

// This is the string that seperates the timestamp and the real message sent.
// Make sure this as unique as possible and that the
// TIMESTAMP_SEPERATOR in the repeaters is identical to this one.
string TIMESTAMP_SEPERATOR = "|~|";

// Extracts the "true" message sent
// through the relay system.
string extractMessageFrom(string relayData) {
list stampSeperate = llParseString2List(relayData, [TIMESTAMP_SEPERATOR], []);

return llList2String(stampSeperate, 1);
}

default
{
state_entry()
{
reset();
}
object_rez(key id)
{
llResetScript();
}
listen(integer a, string n, key id, string m)
{
vector pos;
integer Floor;
float tempFloat;
list tempList;


if ((a == privateChannel) && ((llGetTimeOfDay() - lastRelayTime) > TTL))
{
lastRelayTime = llGetTimeOfDay();
tempList = llCSV2List(m);
m = llList2String(tempList, 1);
}

if (llSubStringIndex(extractMessageFrom(m), "goto floor") == 0)
{
m = extractMessageFrom(m);
lastRelayTime = llGetTimeOfDay();
Floor = (integer)llGetSubString(m, 10, llStringLength(m)) - 1;

if (Floor < 0) Floor = 0;
if (Floor > 9) Floor = 9;

GotoFloor(Floor, NULL_KEY);
}
if (llSubStringIndex(m, "speed") == 0)
{
tempFloat = (float)llGetSubString(m, 5, llStringLength(m));
if ((tempFloat > 0.001) && (tempFloat <= 1.0))
{
speed = tempFloat;
}
}
if ((m=="elevator reset") && (id==llGetOwner()))
{
reset();
}
}

timer()
{
vector CurrentPos;
float tempfloat;

CurrentPos = llGetPos();
tempfloat = (CurrentPos.z - targetVector.z);

if (llFabs(tempfloat) < 2)
{
if (llFabs(tempfloat) < 0.05)
{
//Arrived at Floor
llSetTimerEvent(0);
if (targetFloor == 0)
{
llSay(0, "Welcome Back!");
}
else
{
llSay(0, "Welcome to Heaven!");
// llSay(0, "Arrived at Floor #" + (string)(targetFloor+1));
}
llSetStatus(STATUS_PHYSICS, FALSE);
llStopSound();
}
else
{
llMoveToTarget(targetVector,1.0);
}
}
else
{
if (fixedFloorHeight > 0)
{
targetVector = alignment;
targetVector.z = alignment.z + (fixedFloorHeight * targetFloor);
}
else
{
targetVector = alignment;
targetVector.z = llList2Float(floorHeights, targetFloor);
}
elevate(targetVector);
}
}
}
Alondria LeFay
Registered User
Join date: 2 May 2003
Posts: 725
07-03-2004 15:10
Why not use something like:

ELEVATOR:
CODE


key button;
integer tty;

default
state_entry()
{
llSetTimerEvent(10);
}
timer()
{
integer tmpi = (integer)llKey2Name(button);
if (tmpi > tty)
{
tty = tmpi;
[... CODE to move elevator ...]
}
}
}


And the button just needs to change it's name when pressed....

Another possibility: Rez a phantom object, shoot it down or up which physically transmits the message.

/edit: The was a quicky job.. probably forgot a bit of something but it illustrates a posibility.
Archanox Underthorn
Registered User
Join date: 20 May 2003
Posts: 168
07-03-2004 16:28
I tested it just to be sure, llEmail causes the script to freeze AFTER it sends the email. In the tests I did the max wait time for the email to be received was about 3 seconds.

If you dont mind the button for the elevator freezing after you press it for a bit(prolly not right?) that should work just fine

The freeze is only there to prevent SL email spammers(Im assuming).
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
07-03-2004 20:01
I should start carving notches in my sig for every time people think I'm wrong and I turn out to be right :)
Alondria LeFay
Registered User
Join date: 2 May 2003
Posts: 725
07-03-2004 20:06
From: someone
Originally posted by Eggy Lippmann
I should start carving notches in my sig for every time people think I'm wrong and I turn out to be right :)


:)
1 2