Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How should I reference string variable when I'm reading a notecard?

Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
03-23-2009 05:49
I have an object that, when touched, responds with llSay(0, strToucherFirstName+ " has just touched "+strOwnerFirstName+ "'s "+ strPrimName);. Rather than set this in the script, I would like to read a list of phrases to say from a notecard, and then have the object come out with a random one at runtime.

I'm a bit confused about the best way to do this -- should I have the notecard contain things like %OwnerFirstName%'s %PartName% has just been caressed by %Toucher% and then have the script make the appropriate replacements each time someone touches me?

That seems a terribly wasteful way of doing things. Ideally I'd like to replace %OwnerFirstName% and the rest with strOwnerFirstName, strToucherFirstName and so on when I read the notecard into a strided list in the dataserver event, but I don't really understand how to do that. Or is that the wrong way to approach things?

Related question -- if I have a hug/kiss attachment that says, by default, something like strFirstName + " gives "+ strTargetName + " a big "+strEmbraceName, can I readily change this with a chat command? That is, set my preferred phrase by saying something like /99 kissphrase strTargetName gets a really huge smooch from strFirstName?
Tanith Rosenbaum
Registered User
Join date: 10 Sep 2008
Posts: 42
03-23-2009 08:29
hi Innula,

no, you're on the right path, Replacing it at startup time in the dataserver event saves your users a lot of scipt lag.

What I'd do is the following: Do add some placehoders, like %OwnerFirstName%. When you get a line back in the Dataserver event use llSubStringIndex to search for the index of that placehoder, and then remove it with llDeleteSubString, and insert the string that goes for the placeholder with llInsertString at the same index. Do that for all the placeholders, and once done save the stings into a list to recall from.

Something like this:

integer index = llGetSubstringIndex(in_string, "%PLACEHOLDER%";);
if(index1 != -1)
{
in_string = llDeleteSubString(in_string, index, llStringLength("%PLACEHOLDER%";));
in_string = llInsertString(in_string, index, string_for_placeholder);
}

// do that again for every placeholder you got

strings_list += in_string;


As to your related question: Do you have access to the code of that emoterß If you haven't, and it wasn't built in by the creator then you can't.
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
03-23-2009 11:12
Thanks for the swift reply. It's got me part-way there.

At the moment, I've got this (I used list functions because I understand them a bit better than I do string functions, but I think the end result is the same):
CODE
list remarks;
string fullname;
string firstname;
string myname;
string touchername;

string getFirstName(string fullName)
{
return llList2String(llParseString2List(fullName,[" "],[]),0);
}
integer position = 0;
string notecard;
key query;


default
{
state_entry()
{
fullname = llKey2Name(llGetOwner());
firstname = getFirstName(fullname);
myname = llGetObjectName();
notecard = llGetInventoryName(INVENTORY_NOTECARD, 0);

if(llGetInventoryType(notecard) == INVENTORY_NOTECARD)
{
llOwnerSay("Reading Configuration Notecard.");
query = llGetNotecardLine(notecard, position);
}

else
{
llOwnerSay( "Configuration notecard is not present in the object's inventory.");
}

}

dataserver(key request, string data)
{
list scratch;
if(query == request) {
if(data == EOF) {

llOwnerSay("Ready");
}
else {
scratch =[];
scratch = llParseString2List (data,[" "],[""]);
integer index = llListFindList (scratch, ["%firstname%"]);
if(index != -1){
scratch = llListReplaceList(scratch, [firstname],index, index);
}
index = llListFindList (scratch, ["%myname%"]);
if(index != -1){
scratch = llListReplaceList(scratch, [myname],index, index);
}
index = llListFindList (scratch, ["%touchername%"]);
if(index != -1){
scratch = llListReplaceList(scratch, [touchername],index, index);
}
remarks += llDumpList2String(scratch, " ");
position ++;
query = llGetNotecardLine(notecard, position);
}
}
}


touch_start(integer total_number)
{
touchername = llDetectedName(0);

llSay(0, llList2String(remarks,0));
}

changed(integer change)
{
if (change & CHANGED_INVENTORY){
llResetScript();
}
}
}


With a one-line config card reading
From: someone
%touchername% has just touched %firstname% 's %myname%
this gives me " box: has just touched Innula 's box" when I touch it.

My problem is that firstname and myname have values by the time we get to the dataserver event, but touchername doesn't. Is there any way round this other than not replacing touchername in the dataserver but in the touch_start event instead?

There's also a more minor problem that I have to put in a space between the 's and firstname; if my card reads, "has just touched %firstname%'s box", but I think I can figure that out.

My question about setting what a hug/kiss attachment was a general one; I'm trying to write one at the moment and wanted to give people the option of changing what the device says without having to edit the script or -- if I can avoid it -- their having to edit a notecard either.

It's really the same problem -- how do I reference variables other than by editing the script itself?