Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Sherades Game v1.02 (examples for newbies)

Graham Mondrian
Registered User
Join date: 16 Mar 2005
Posts: 59
04-10-2005 13:51
Hey peeps,

I made a sherades style game and i wanted to post it here for examples, I only really made it to teach myself the relevant elements of scripting. The basic jist of the game is that an image is displayed on the screen and people have to guess what its of. The image is covered by a number of panes specified in the config file and the panes are slowly hidden. People state single letters and are IM'ed the word (the name of the texture being displayed) with letters they have not guessed replaced by _ and spaces already filled in i.e. "Example 1" guess e -> IM user "E______e _".

Examples of :-
Having & Maintaining a pot
Inventory Accesses (for multiple different purposes).
Rezzing
Remotely changing linked objects
Large config files.
Timing Events
Permission Requests

Known errors :-
I do not state that this is the best way to accomplish what i did, im submitting my example :)
Something i found stated that the lowest possible alpha value was 0.1, this is not true and it should be swapped for 0 where found.
The rezzing of the panels needs to account for more complex trigonometry, if the object is not X aligned, the panels rez in a staggered fashion along the X axis.
The string comparison performance is sluggish and IM'ing the user the answer holds its own lag so responses during play are slow.


CODE

Script: Sherades Game Controller
integer userChan;
integer hashImages; // no. of images
integer curImage;
integer listener;
integer listener2;
integer frontFace;
list images;
integer pot;
integer maxSecs;
string toSay;

list winnerKeys;
list winnerScores;

float xSquares;
float zSquares;

integer GWC_link = 1;
integer rez_replied;
vector paneScale;
integer panesPos;
integer pane_register_count;

list shuffledLinks;
list Links;

integer letterTolerance;
list hostNames;
key host;
string theme;
integer notecardLine;
list expectedVars;
integer state_theme;

list keyResult; // alternate keys and their current results

integer include_pot;

restore_all_panes()
{
integer i = 2;
for (;i<=(xSquares*zSquares);i++)
{
llSetLinkAlpha(i,1.0,ALL_SIDES);
}
}

default_init()
{
llSay(0,"Sherades v1.01a -- Script Active");
pot = 0;
host = llGetOwner();
}

//|----- STARTUP---------------------------------------------------------------|
default
{
on_rez(integer start_param)
{
default_init();
state load_config;
}
state_entry()
{
default_init();
state load_config;
}
}

state load_config
{
state_entry()
{
llWhisper(0,"Loading Updated Configuration..");
images = [];
hashImages = llGetInventoryNumber(INVENTORY_TEXTURE);
integer i = 0;
for (;i<hashImages;i++)

{
string name = llGetInventoryName(INVENTORY_TEXTURE,i);
if (name!="Default") images = images + name;
}
hashImages--;
expectedVars = ["userChan","hosts","has_pot","maxSec","lengthTolerance"];
notecardLine = 0;
llGetNotecardLine("Config",notecardLine);

}

dataserver(key requested,string data)
{
if (data==EOF)
{
xSquares = 5;
zSquares = 5;
integer perm = llGetPermissions();
if (include_pot == 0 || (perm & PERMISSION_DEBIT) == PERMISSION_DEBIT)
{llWhisper(0,"Reconfiguration request completed.");state idle;}
else
state wait_link_permissions;
}
else
{
if(llGetSubString(data,0,0)!="/")
{
list input = llCSV2List(data);
string varName = llList2String(input,0);
if (varName==llList2String(expectedVars,0)){userChan=(integer)llList2String(input,1);}
else
if(varName==llList2String(expectedVars,1))
{hostNames = llList2List(input,1,llGetListLength(input));}
else
if(varName==llList2String(expectedVars,2))
{include_pot = llList2Integer(input,1);}
else
if(varName==llList2String(expectedVars,3))
{maxSecs = llList2Integer(input,1);}
else
if(varName==llList2String(expectedVars,4))
{letterTolerance = llList2Integer(input,1);}
}
notecardLine++;
llGetNotecardLine("Config",notecardLine);
}
}

}

state wait_link_permissions
{
state_entry()
{
integer perm = llGetPermissions();
if (include_pot == 0 || (perm & PERMISSION_DEBIT) == PERMISSION_DEBIT)
{llWhisper(0,"Reconfiguration request completed.");state idle;}
else
{
llInstantMessage(llGetOwner(),"You have enabled pot management, this script needs to be able to transfer money to you, please confirm the dialog");
llRequestPermissions(llGetOwner(),PERMISSION_DEBIT);
}

}
run_time_permissions(integer permissions)
{llWhisper(0,"Reconfiguration request completed.");state idle;}
}

//|---- REZZING---------------------------------------------------------------|

state rez_panels
{
state_entry()
{
integer i = 2;
while (i<26)
{
Links = Links + i;
i++;
}
restore_all_panes();
state startup;
}
}

//|---- INTERACTION LOOP-------------------------------------------------------|
state idle
{
state_entry()
{
winnerKeys = [];
winnerScores = [];
listener = llListen(userChan,"","","");
}

listen(integer channel, string name, key id, string message)
{
if (id == host)
{
if (message == "config")
{
state load_config;
}
else
if (message == "startup")
{
llListenRemove(listener);
state rez_panels;
}
else
if (message == "shutdown")
{
state shutdown;
}

}else
if (message == "host")
{
integer i = 0;
integer hnSize = llGetListLength(hostNames);
for(;i<hnSize;i++)
if (llKey2Name(id) == llList2String(hostNames,i))
{
host = id;
toSay = llKey2Name(id);
toSay = llInsertString(toSay,0,"Host is now ");
llSay(0,toSay);
}
}
}
}

state startup
{
state_entry()
{
images = llListRandomize(images,0);
if (include_pot == 1)
state wait_pot;
else state imageComplete;
}
}
//|----- WAIT POT---------------------------------------------------------------|
state wait_pot
{

state_entry()
{
curImage = 0;
frontFace = 3;
winnerKeys = [];
winnerScores = [];

if (pot > 0)
{
toSay = " has been restored from a previous round of play.";
toSay = llInsertString(toSay,0,(string)pot);
toSay = llInsertString(toSay,0,"A pot of L$");
llSay(0,toSay);
}
llSay(0,"Awaiting any donations to the pot!");
listener = llListen(userChan,"",host,"");
}

listen(integer channel, string name, key id, string message)
{
if (message == "start")
{
llListenRemove(listener);
toSay = ".";
toSay = llInsertString(toSay,0,(string)pot);
toSay = llInsertString(toSay,0,"Starting round with a pot of L$");
llSay(0,toSay);
state imageComplete;
}else if (message == "shutdown"){state shutdown;}
}

money(key giver, integer amount)
{
pot+=amount;
toSay = ".";
toSay = llInsertString(toSay,0,(string)pot);
toSay = llInsertString(toSay,0," to the pot taking it up to L$");
toSay = llInsertString(toSay,0,(string)amount);
toSay = llInsertString(toSay,0," donated L$");
toSay = llInsertString(toSay,0,llKey2Name(giver));
llSay(0,toSay);
}
}

//|---- CHANGE IMG--------------------------------------------------------------|

state imageComplete
{
state_entry()
{
if (curImage<hashImages)
{
restore_all_panes();
keyResult = [];
llSay(0,"Loading an image, get ready...");
llSetTexture(llList2String(images,curImage),3);
shuffledLinks = llListRandomize(Links,1);
state waitGuess;
}
else
{
llSetTexture("Default",frontFace);
curImage = 0;
llSay(0,"Out Of Images -- Game Over!");

if (llGetListLength(winnerScores) > 0)
{
list winners;
integer i = 0;
integer score = 0;
integer bestScore = 0;
for (;i<llGetListLength(winnerScores);i++)
{
score = llList2Integer(winnerScores,i);
if (score>bestScore) bestScore = score;
}

i = 0;
for (;i<llGetListLength(winnerKeys);i++)
{
score = llList2Integer(winnerScores,i);
if (score == bestScore)
winners = winners + llList2Key(winnerKeys,i);
}
integer winLen = llGetListLength(winners);

// end of listing winners

list randWin = [];
key extraWinner;

if ((pot%2)>0)
{
randWin = llListRandomize(winners,1);
extraWinner = llList2Key(randWin,0);
pot--;
}

pot/=winLen;

integer pot4you = pot;

if (winLen>1)
llSay(0,"The winners are ");
else llSay (0,"The winner is ");


i = 0;
for (;i<winLen;i++)
{
key winner = llList2Key(winners,i);

integer pot4you = pot;

if (llGetListLength(randWin)>0 && winner == extraWinner)
{ // if this is the randomly selected person who gets 1 extra because the pot is uneven.
pot4you++;
}

toSay = "";
if (pot4you>0)
{
llGiveMoney(winner,pot4you);
// IM winner
toSay = llGetRegionName();
toSay = llInsertString(toSay,0," from the 'Sherades' pot in ");
toSay = llInsertString(toSay,0,(string)pot4you);
toSay = llInsertString(toSay,0,"Congratulations! You just won L$");
llInstantMessage(winner,toSay);
// Announce winner
toSay = (string)pot4you;
toSay = llInsertString(toSay,0," receives L$");
if (winLen>1) toSay=llInsertString(toSay,0," who ");
}
toSay = llInsertString(toSay,0,llKey2Name(winner));
llSay(0,toSay);
}



toSay = " correct answer(s).";
toSay = llInsertString(toSay,0,(string)bestScore);
toSay = llInsertString(toSay,0,"with ");
llSay(0,toSay);

}
else llSay(0,"There were no correct answers this round."); // winnerScores.len = 0;
state shutdown; // change to reset all rezzed cards and wait pot.
}
}
}

//|-
//|--- TAKE GUESS--------------------------------------------------------------|

state waitGuess
{
state_entry()
{
listener = llListen(0,"","","");
listener2 = llListen(userChan,"",host,"");
// insert time-based validation here.
panesPos = 0;
llSetTimerEvent(maxSecs);
}
timer()
{

llSetTimerEvent(0.0);
if (panesPos<llGetListLength(shuffledLinks))
{
llSetLinkAlpha(llList2Integer(shuffledLinks,panesPos),0.1,ALL_SIDES);
panesPos++;
llSetTimerEvent(maxSecs);
}
else
{
if (panesPos == llGetListLength(shuffledLinks)) {llSetTimerEvent(2*maxSecs);panesPos++;}
else
{
llListenRemove(listener);
llListenRemove(listener2);
toSay = " seconds has elapsed.";
toSay = llInsertString(toSay,0,(string)(maxSecs*(integer)zSquares*(integer)xSquares
));
toSay = llInsertString(toSay,0,"The maximum guess time of ");
llSay(0,toSay);
curImage++;
state imageComplete;
}
}
}
listen(integer channel, string name, key id, string message)
{

string comparison = llToLower(llList2String(images,curImage));
string msg = llToLower(message);
integer comparisonLen = llStringLength(comparison);
integer msgLen = llStringLength(msg);
list resultAsList;
string result;

if (channel!=userChan)
{
if (msgLen<=letterTolerance)
{
integer score = 0;
integer i = 0;
integer resultFlag = 0;
integer found = 0;

integer kRLen = llGetListLength(keyResult);

for (;i<kRLen;)
{
if (llList2Key(keyResult,i)==id)
{
resultAsList = llList2List(keyResult,i+1,i+comparisonLen);
keyResult = llDeleteSubList(keyResult,i,i+comparisonLen);
i=kRLen;
resultFlag = 1;
}
i+=comparisonLen+1;
}


if(resultFlag == 0)
{
for (i = 0;i<comparisonLen;i++)
{
if (llGetSubString(comparison,i,i) == " ")
resultAsList = resultAsList + " "; // spaces are free
else
resultAsList = resultAsList + "_";
}
}

integer j = 0;
for (;j<msgLen;j++)
for (i = 0;i<comparisonLen;i++)
if (llGetSubString(comparison,i,i) == llGetSubString(msg,j,j))
{
resultAsList = llListReplaceList(resultAsList,[llGetSubString(msg,j,j)],i,i);
found++;
}


integer ralSize = llGetListLength(resultAsList);
result = llList2String(resultAsList,ralSize - 1);

for(i = 1;i<ralSize;i++)
result = llInsertString(result,0,llList2String(resultAsList,(ralSize - 1) - i));
keyResult = keyResult + id + resultAsList;

if (result == comparison)
{

curImage++;
llListenRemove(listener);
llSetTimerEvent(0.0);
llSay(0,"The correct answer was given!");

list toFind = [id];
integer foundPos = llListFindList(winnerKeys,toFind);
if (foundPos>-1)
{
list temp; // perform an array copy function to increment id's score
integer i = 0;
for (;i<llGetListLength(winnerScores);i++)
{
integer score = llList2Integer(winnerScores,i);
if (i==foundPos) score++;
temp = temp + score;
}
winnerScores = temp;
}else {winnerKeys = winnerKeys+id;winnerScores = winnerScores + 1;}

state imageComplete;
} // guess good
else
{
if (found>0)
{

llInstantMessage(id,result);
}
// keep guessing.
}
} else llInstantMessage(id,"Sorry your guess exceeds the current character limit, try guessing more conservatively!"); // too long

}
else
{
if (channel == userChan && message == "shutdown")
{
state shutdown;
}
} // else


} // listen
} // state

state shutdown
{
state_entry()
{
llSetTexture("Default",ALL_SIDES);
//kill_panes();
restore_all_panes();
llWhisper(0,"Shut-Down request successful.");
if (pot>0)
{
toSay = " will be kept for the next round of play.";
toSay = llInsertString(toSay,0,(string)pot);
toSay = llInsertString(toSay,0,"The pot of L$");
llSay(0,toSay);
}
state idle;
}
}

Config File (example):
// Sherades v1.01a
// This file is read in by the script and is sensitive to tampering
// Comments below variables explain their use in the script.

userChan,234
// The channel used for YOU to communicate with the script
// This cannot be set to 0 else you will not be able to send commands that
// run in parallel with public guessing such as 'pause'
// i..e /234 config
// would be your first command

hosts,Graham Mondrian,MJ Mondrian
// comma seperated. case-sensitive with spaces only if they exist in the actual name.

has_pot,1
// Include the 'get pot donations' stage?

maxSec,1
// This is the number of seconds between panels dissappearing

lengthTolerance,2
// A filter to keep out letter spammers and people typing full sentences for other
// reasons. number of characters to take as input answer.
// Be warned: this will lag the server a lot if you take it above 10 for a game involving a lot of avs.
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
discussion thread
04-12-2005 20:43
/54/3a/42569/1.html
_____________________
i've got nothing. ;)
Graham Mondrian
Registered User
Join date: 16 Mar 2005
Posts: 59
04-14-2005 10:20
Apologies, there's a lot of details i changed which you need to know if you want to put this thing together (which someone has just asked me about).

Firstly, it doesn't rez the panels anymore. It took 25 seconds to rez a number of panels worth playing the game with and it wasnt worth the time-cost. You need 1 boad prim (a square flattened to like a poster) and then 25 panel prims that are arranged in 5 rows and columns on top of the panel board. These now need to be linked by linking all the panels to each other and then linking them to the board (-- the board *must* be last). The script should be attached to the board prim.

You also need a 'Default' texture in the boards inventory which it will apply to itself when it is idle. You should now be ready to go, load it up with named textures to play w/.
Judy Brodie
Divinational Sweetie
Join date: 20 Apr 2004
Posts: 138
06-02-2005 15:32
sounds like the game concentration.