Myriad Lite Point Pools Server
Myriad_Lite_Point_Pools_Server-v0.0.1-20120129.lsl
// Myriad_Lite_Point_Pools_Server-v0.0.1-20120129.lsl
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad RPG licensed under the Creative Commons Attribution 2.0 UK: England and Wales
// http://creativecommons.org/licenses/by/2.0/uk/
// Myriad Lite software Copyright (c) 2011 by Allen Kerensky (OSG/SL)
// Myriad Lite licensed under the
// Creative Commons Attribution-Share Alike-Non-Commercial 3.0 Unported
// http://creativecommons.org/licenses/by-nc-sa/3.0/
// CONSTANTS - DO NOT CHANGE DURING RUN
string VERSION = "0.0.1"; // Allen Kerensky's script version
string VERSIONDATE = "20120129"; // Allen Kerensky's script yyyymmdd
integer CHAN_MYRIAD = -999; // regionwide channel for Myriad events
string CARD = "Myriad_Lite_Point_Pools-v0.0.0-20110928.csv"; // notecard data table
// RUNTIME GLOBALS - CAN CHANGE DURING RUN
integer HAND_MYRIAD; // llListenRemove handle for Myriad regional channel
list POWER_LEVELS; // names of power levels loaded
list STAT_POOLS; // stat pool of power level, indexed by name order
list SKILL_POOLS; // skill pool of power level, indexed by name order
list PER_SKILLS; // number of skills per pool, indexed by name order
list SFX_POOLS; // special effect ability pools, indexed by name order
list HEALTH_POOLS; // resilience pools, indexed by name order
list GP_POOLS; // general point pools, indexed by name order
list MAX_STAT_CAPS; // max stat value per power level, indexed by name order
list MAX_SKILL_CAPS; // max skill value per power level, indexed by name order
list RESOURCE_POINTS; // initial resource points per power level indexed by name order
integer LINE = 0; // reading line number
key QUERY = NULL_KEY; // track notecard queries
// DEBUG - show debug messages
DEBUG(string dmessage) {
llOwnerSay("DEBUG: "+dmessage);
}
// SETUP - begin
SETUP() {
if ( HAND_MYRIAD != 0 ) llListenRemove(HAND_MYRIAD); // is there already a listener? clear it
HAND_MYRIAD = llListen(CHAN_MYRIAD,"",NULL_KEY,""); // start region channel listener
DEBUG("Point Pool server "+VERSION+" "+VERSIONDATE+" loading point pools. Please wait..."); // tell player we're waiting for data server
QUERY = llGetNotecardLine(CARD,LINE++); // ask for line from notecard and advance to next line
}
// RESET - reload
RESET() {
llResetScript(); // now reset
}
LIST_POINT_POOLS(key id) {
integer replyto = (integer)("0x"+llGetSubString((string)id,0,6)); // calculate requestor-specific chat channel to reply to
// we have to work around llRegionSay max string length 1023 characters
integer items = llGetListLength(POWER_LEVELS); // how many total items to send?
integer count; // which item are we processing now?
string out = "POINT_POOLS|"; // start an output list
integer firstflag = TRUE; // is this first item in new list?
while (count < items ) { // do we still have items in list to send?
string name = llList2String(POWER_LEVELS,count); // get the name of current item
if ( llStringLength(out+","+name) <= 1016) { // is our output list under the string length limit?
if ( firstflag == TRUE ) { // first item in list does not need a comma prefix
out += name; // add this item as first in the output list
firstflag = FALSE; // turn off first flag since next item won't be
} else { // not first item in list, prefix with comma
out += ","+name; // add a comma and this power level to existing list
}
} else { // output string > 1016 chars long
llRegionSay(replyto,out); // send current output string
out = "POINT_POOLS|"+name; // start a new one and add current item to that
}
count++; // done putting this item in a list, set counter to next
}
llRegionSay(replyto,out); // say last line of output
}
GET_POINT_POOL(key id,string msg) {
integer replyto = (integer)("0x"+llGetSubString((string)id,0,6)); // calculate requestor-specific chat channel to reply to
list tokens = llParseString2List(msg,["|"],[]); // split msg into list around pipe symbols
string powerlevel = llList2String(tokens,1); // the name of the item to get
integer listpos = llListFindList(POWER_LEVELS,[powerlevel]); // get the position of that item in the list
string reply = "POINT_POOL"; // start output item data NO PLURAL here - we're sending 1 point pool
if ( listpos != -1 ) { // was item name in the list?
reply += "|POWER_LEVEL="+llList2String(POWER_LEVELS,listpos); // add power level name to output
reply += "|STAT_POOL="+llList2String(STAT_POOLS,listpos); // add stat pool to output
reply += "|SKILL_POOL="+llList2String(SKILL_POOLS,listpos); // add skill pool to output
reply += "|PER_SKILLS="+llList2String(PER_SKILLS,listpos); // add skills per pool to output
reply += "|SFX_POOL="+llList2String(SFX_POOLS,listpos); // add special effect ability pool to output
reply += "|HEALTH_POOL="+llList2String(HEALTH_POOLS,listpos); // add resilience pool to output
reply += "|GP_POOL="+llList2String(GP_POOLS,listpos); // add general point pool to output
reply += "|MAX_STAT_CAP="+llList2String(MAX_STAT_CAPS,listpos); // add max stat value to output
reply += "|MAX_SKILL_CAP="+llList2String(MAX_SKILL_CAPS,listpos); // add max skill value to output
reply += "|RESOURCE_POINTS="+llList2String(RESOURCE_POINTS,listpos); // add resource points value to output
llRegionSay(replyto,reply); // send it to requestor FIXME what if output greater than 1016 chars?
} else {
llRegionSay(replyto,"CAMPAIGN|ERROR=Requested Point Pool ("+powerlevel+") not found"); // item requested does not exist, return an error
}
}
SET_POINT_POOL() {
// FIXME - do we need this?
}
// DEFAULT STATE
default {
// STATE ENTRY - called on Reset
state_entry() {
SETUP(); // show credits and start of notecard data load
}
// on_rez - when rezzed to ground or from inventory as attachment during login
on_rez(integer params) {
params = 0; // LSLINT
RESET(); // force to go through state entry
}
// attach - when attached or detached from inventory or during login
attach(key id) {
id = NULL_KEY; // LSLINT
RESET(); // force to go through state entry
}
// dataserver called for each line of notecard requested
dataserver(key queryid,string data) {
if ( queryid == QUERY ) { // dataserver gave us line we asked for?
if ( data != EOF ) { // we're not at end of notecard file?
if ( llGetSubString(data,0,0) == "#" ) { // does this line start with comment mark?
QUERY = llGetNotecardLine(CARD,LINE++); // ignore comment and ask for the next line
return;
}
// Parse non-comment lines in keyword = value[,value,...] format
list fields = llParseString2List(data,[","],[]); // break line of text into = delimited fields
POWER_LEVELS = POWER_LEVELS + [llStringTrim(llList2String(fields,0),STRING_TRIM)]; // add name field to name list
STAT_POOLS = STAT_POOLS + [llList2Integer(fields,1)]; // add stat pool field to list
SKILL_POOLS = SKILL_POOLS + [llList2Integer(fields,2)]; // add skill pool field to list
PER_SKILLS = PER_SKILLS + [llList2Integer(fields,3)]; // add per-skills field to list
SFX_POOLS = SFX_POOLS + [llList2Integer(fields,4)]; // add sfx pool field to list
HEALTH_POOLS = HEALTH_POOLS + [llList2Integer(fields,5)]; // add resilience pool field to list
GP_POOLS = GP_POOLS + [llList2Integer(fields,6)]; // add general pool field to list
MAX_STAT_CAPS = MAX_STAT_CAPS + [llList2Integer(fields,7)]; // add max stat field to list
MAX_SKILL_CAPS = MAX_SKILL_CAPS + [llList2Integer(fields,8)]; // add max skill field to list
RESOURCE_POINTS = RESOURCE_POINTS + [llList2Integer(fields,9)]; // add resource point field to list
QUERY = llGetNotecardLine(CARD,LINE++); // finished with known keywords, get next line
} else { // end of notecard
DEBUG("Point Pools Loaded. Server ready. Free Memory: "+(string)llGetFreeMemory()); // done, ready to serve
} // end if data not equal eof
} // end if query id equal
} // end if data server event
listen(integer channel,string name,key id,string msg) {
channel = 0; // LSLINT
name = ""; // LSLINT
list tokens = llParseString2List(msg,["|"],[ ]); // split msg into list around pipe symbols
string command = llList2String(tokens,0); // first field is some sort of command
if ( command == "LIST_POINT_POOLS" ) { // is this a list all point pools request?
LIST_POINT_POOLS(id); // call it
return; // return early instead of processing more
}
if ( command == "GET_POINT_POOL" ) { // GET_POINT_POOL|string power level name
GET_POINT_POOL(id,msg); // call it
return; // return early instead of processing more
}
if ( command == "SET_POINT_POOL" ) { // is this a set point-pool request?
SET_POINT_POOL(); //call it
return; // return early in case we add more later
}
}
} // end default state