Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Help Is there a tool to increase chat range?

Random Padar
Registered User
Join date: 6 Oct 2005
Posts: 36
06-26-2008 08:18
We are opening a club and would like to find a tool or something that would increase the chat range on the land. The club dance floor is over 19m. Has someone come up with a way for everyone to hear each others main chat if they are out of range without shouting?
Max Pitre
Registered User
Join date: 19 Jul 2006
Posts: 370
06-26-2008 08:41
Some sort of repeater set around the club? Just name then the same as the avatars name that will be talking.
Lias Leandros
mainlander
Join date: 20 Jul 2005
Posts: 3,458
06-26-2008 08:45
Just go to http://www.slexchange.com and look up CHAT RELAY. There are various devices ranging in price from 150L to over 1,000L.

.
_____________________

http://slurl.com/secondlife/Bear/214/199/107
Join in SL open enrollment CLUB JOBS to announce new DJ and Host Jobs for free.
And on Avatar's United http://www.avatarsunited.com/groups/club-jobs
Malachi Petunia
Gentle Miscreant
Join date: 21 Sep 2003
Posts: 3,414
06-26-2008 09:04
Chat relays spanning a larger space might work, but chat normally reaches 20m from the speaker; in a 19m x 19m room (27m longest diagonal) a standard repeater is going to cause most chat to double up within that space. And, although a script can tell how far away the chat it receives is, it can't ensure how far away its listeners are.

I expect that you would either need custom scripts or wind up really annoying most chatters - or both.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-26-2008 09:51
You could have people wear an attachment that does something like (WARNING: unfiltered listen on channel zero could cause LAG, especially when used by lots of people!):

1.) Sending end: repeat everything its owner/wearer says on channel zero to a non-zero channel with llShout() or llRegionSay() (probably the latter).

2.) Receiving end: listen (unfiltered; can reuse the sending listen and use a logical test for speaker) to channel zero and the repeat channel. Remember every message from people other than the owner/wearer on each channel for a small amount of time (0.5 to 1 seconds should do). Don't repeat anything heard on channel zero, but llOwnerSay() messages heard on the repeat channel if they aren't also heard on channel zero within the wait period.

This should work in theory, but I'm scared about the amount of lag it would cause the sim, so it should be stress tested thoroughly before used on an ongoing basis!
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-26-2008 11:31
It would look something like this. Note again that this may cause lots of lag, especially when used by many residents simultaneously. I'll leave it as an exercise to add logic for turning on/off, handling attach/detach, etc.

(This script has been compiled, but not tested.)
CODE

//// Constants

integer RELAY_CHANNEL = -1464533987;

float MEMORY_PERIOD = 0.25;
integer MAX_REMEMBERED_MESSAGES = 10;
float MIN_TIMER_DELAY = 0.05;


//// Variables

list publicMessageHashes = [];
list publicMessageTimes = [];
integer nPublicMessages = 0;

list relayedMessages = [];
list relayedMessageHashes = [];
list relayedMessageTimes = [];
integer nRelayedMessages = 0;


//// Functions

string hashMessage(key speaker, string message)
{
return llMD5String((string)speaker+"/"+message, 0);
}

addPublicMessage(string messageHash)
{
publicMessageHashes =
(publicMessageHashes=[])+publicMessageHashes+[ messageHash ];
publicMessageTimes =
(publicMessageTimes=[])+publicMessageTimes+[ llGetTime() ];
++nPublicMessages;
}

removePublicMessage(integer index)
{
publicMessageHashes =
llDeleteSubList(
(publicMessageHashes=[])+publicMessageHashes, index, index);
publicMessageTimes =
llDeleteSubList(
(publicMessageTimes=[])+publicMessageTimes, index, index);
--nPublicMessages;
}

addRelayedMessage(string speakerName, string message, string messageHash)
{
string fullMessage = speakerName+": "+message;

relayedMessages =
(relayedMessages=[])+relayedMessages+[ fullMessage ];
relayedMessageHashes =
(relayedMessageHashes=[])+relayedMessageHashes+[ messageHash ];
relayedMessageTimes =
(relayedMessageTimes=[])+relayedMessageTimes+[ llGetTime() ];
++nRelayedMessages;

if (nRelayedMessages == 1)
{
float waitPeriod = MEMORY_PERIOD*llGetRegionTimeDilation();
if (waitPeriod <= MIN_TIMER_DELAY)
{
waitPeriod = MIN_TIMER_DELAY;
}

llSetTimerEvent(waitPeriod);
}
}

removeRelayedMessage(integer index)
{
relayedMessages =
llDeleteSubList((relayedMessages=[])+relayedMessages, index, index);
relayedMessageHashes =
llDeleteSubList(
(relayedMessageHashes=[])+relayedMessageHashes, index, index);
relayedMessageTimes =
llDeleteSubList(
(relayedMessageTimes=[])+relayedMessageTimes, index, index);
--nRelayedMessages;

if (index == 0)
{
if (nRelayedMessages > 0)
{
float waitPeriod = getNextRepeatPeriod();
if (waitPeriod <= MIN_TIMER_DELAY)
{
waitPeriod = MIN_TIMER_DELAY;
}

llSetTimerEvent(waitPeriod);
} else
{
llSetTimerEvent(0.0);
}
}
}

trimOldestMessage()
{
if (nPublicMessages <= 0)
{
if (nRelayedMessages > 0)
{
giveRelayedMessage();
} else
{
return;
}
} else if (nRelayedMessages <= 0)
{
removePublicMessage(0);
} else
{
return;
}

float publicTime = llList2Float(publicMessageTimes, 0);
float relayedTime = llList2Float(relayedMessageTimes, 0);
if (publicTime < relayedTime)
{
removePublicMessage(0);
} else
{
giveRelayedMessage();
}
}

float getNextRepeatPeriod()
{
return llList2Float(relayedMessageTimes, 0)+
MEMORY_PERIOD*llGetRegionTimeDilation()-
llGetTime();
}

giveRelayedMessage()
{
string message = llList2String(relayedMessages, 0);
removeRelayedMessage(0);

llOwnerSay(message);
}

handleOwnerMessage(string message)
{
llRegionSay(RELAY_CHANNEL, message);
}

handlePublicMessage(key speaker, string message)
{
string messageHash = hashMessage(speaker, message);

integer index = llListFindList(relayedMessageHashes, [ messageHash ]);
if (index >= 0)
{
removeRelayedMessage(index);
} else
{
while (nPublicMessages+nRelayedMessages >= MAX_REMEMBERED_MESSAGES)
{
trimOldestMessage();
}
addPublicMessage(messageHash);
}
}

handleRelayedMessage(key speaker, string speakerName, string message)
{
string messageHash = hashMessage(speaker, message);

integer index = llListFindList(publicMessageHashes, [ messageHash ]);
if (index >= 0)
{
removePublicMessage(index);
} else
{
while (nPublicMessages+nRelayedMessages >= MAX_REMEMBERED_MESSAGES)
{
trimOldestMessage();
}
addRelayedMessage(speakerName, message, messageHash);
}
}


//// States

default
{
state_entry()
{
llListen(RELAY_CHANNEL, "", NULL_KEY, "");

// The EXPENSIVE part!
llListen(0, "", NULL_KEY, "");
}

listen(integer channel, string name, key id, string message)
{
if (channel == 0)
{
if (id == llGetOwner())
{
handleOwnerMessage(message);
} else
{
handlePublicMessage(id, message);
}
} else
{
key speaker = llGetOwnerKey(id);
if (speaker == llGetOwner() || speaker == id)
{
return;
}

handleRelayedMessage(id, name, message);
}
}

timer()
{
giveRelayedMessage();

if (nRelayedMessages > 0)
{
float waitPeriod = getNextRepeatPeriod();
while (waitPeriod <= 0.0)
{
giveRelayedMessage();
if (nRelayedMessages == 0)
{
return;
}
waitPeriod = getNextRepeatPeriod();
}
}
}
}