// Myriad_Lite_Module_Character_Sheet-v0.0.10-20131019.lsl // Copyright (c) 2012-2013 by Allen Kerensky (OSG/SL) All Rights Reserved. // This work is dual-licensed under // Creative Commons Attribution (CC BY) 3.0 Unported // http://creativecommons.org/licenses/by/3.0/ // - or - // Modified BSD License (3-clause) // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Myriad Lite nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN // NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // The Myriad RPG System was designed, written, and illustrated by Ashok Desai // Myriad RPG System licensed under: // Creative Commons Attribution (CC BY) 2.0 UK: England and Wales // http://creativecommons.org/licenses/by/2.0/uk/ // VERSION CONTROL string BASENAME = "Myriad Lite Module Character Sheet"; string VERSION = "0.0.10"; // Allen Kerensky's script version string VERSIONDATE = "20131019"; // Allen Kerensky's script yyyymmdd // MODULE TO MODULE MESSAGING CONSTANTS integer MODULE_CHARSHEET = -2; integer LM_SENDTOATTACHMENT = 0x80000000; // FIXME move to SENDTOATTACH|<message> // // Prim Persistent Memory Array Support // DELETE_RECORD(string dbkey, string field) { //OWNERSAY("DELETE_RECORD=["+dbkey+"] FIELD=["+field+"] START"); // scan index or prim names for empty, get number for update integer i; string name; string desc; for ( i = 2; i <= llGetNumberOfPrims(); i++) { name = llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0); desc = llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0); if ( name == dbkey && desc == field ) { // record found, delete llSetLinkPrimitiveParamsFast(i,[PRIM_NAME,"",PRIM_DESC,"",PRIM_TEXT,"",ZERO_VECTOR,0.0]); // save to database } } //OWNERSAY("DELETE_RECORD=["+dbkey+"] FIELD=["+field+"] ENDS"); } DUMP_RECORDS() { //OWNERSAY("DUMP_RECORDS STARTS"); // scan index or prim names for empty, get number for update integer i; string name = ""; string desc = ""; string text = ""; for ( i = 2; i <= llGetNumberOfPrims(); i++) { name = llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0); desc = llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0); if ( name != "" && desc != "" ) { text = llList2String(llGetLinkPrimitiveParams(i,[PRIM_TEXT]),0); OWNERSAY("RECORD=["+(string)i+"] NAME=["+name+"] DESC=["+desc+"] TEXT=["+text+"]"); } } //OWNERSAY("DUMP_RECORDS ENDS"); } DUMP_TYPE(integer chan,string type) { //OWNERSAY("DUMP_TYPES CHAN=["+(string)chan+"] TYPE=["+type+"] STARTS"); type = llToUpper(type); // scan index or prim names for empty, get number for update integer i; string name = ""; string desc = ""; string text = ""; for ( i = 2; i <= llGetNumberOfPrims(); i++) { name = llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0); if ( name == type ) { desc = llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0); text = llList2String(llGetLinkPrimitiveParams(i,[PRIM_TEXT]),0); if ( type == "CHARACTER" ) llSay(chan,"CHARACTER|"+desc+"="+text); if ( type == "STATISTIC" ) llSay(chan,"STATISTIC|NAME="+desc+"|"+text); if ( type == "SKILL" ) llSay(chan,"SKILL|NAME="+desc+"|"+text); if ( type == "EFFECT" ) llSay(chan,"EFFECT|NAME="+desc+"|"+text); if ( type == "RESILIENCE" ) llSay(chan,"RESILIENCE|NAME="+desc+"|"+text); if ( type == "BOON" ) llSay(chan,"BOON|NAME="+desc+"|"+text); if ( type == "FLAW" ) llSay(chan,"FLAW|NAME="+desc+"|"+text); if ( type == "CAMPAIGN" ) llSay(chan,"CAMPAIGN|NAME="+desc+"|"+text); if ( type == "SPECIE" ) llSay(chan,"SPECIE|NAME="+desc+"|"+text); if ( type == "BACKGROUND" ) llSay(chan,"BACKGROUND|NAME="+desc+"|"+text); if ( type == "CAREER" ) llSay(chan,"CAREER|NAME="+desc+"|"+text); if ( type == "ITEM" ) llSay(chan,"ITEM|NAME="+desc+"|"+text); if ( type == "STUNT" ) llSay(chan,"STUNT|NAME="+desc+"|"+text); if ( type == "QUOTE" ) llSay(chan,"QUOTE|NAME="+desc+"|"+text); } } //OWNERSAY("DUMP_TYPE ENDS"); } ERASE_TYPE(string type) { //OWNERSAY("ERASE TYPE ["+type+"] STARTS"); // scan index or prim names for empty, get number for update integer i; string name = ""; string desc = ""; for ( i = 2; i <= llGetNumberOfPrims(); i++) { name = llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0); if ( name == type ) { desc = llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0); DELETE_RECORD(type,desc); } } //OWNERSAY("ERASE_TYPE ENDS"); } FORMAT_DB() { //OWNERSAY("FORMATTING DATABASE"); integer i; for ( i = 2; i <= llGetNumberOfPrims(); i++ ) { if ( llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0) != "" ) { llSetLinkPrimitiveParamsFast(i,[PRIM_NAME,"",PRIM_DESC,"",PRIM_TEXT,"",ZERO_VECTOR,0.0]); } } //OWNERSAY("DATABASE FORMAT COMPLETE"); } string KEY_NOT_FOUND = "[KEY_NOT_FOUND]"; string GET_VAL(string dbkey,string field) { //OWNERSAY("GET_VAL KEY=["+dbkey+"] FIELD=["+field+"]"); string out = KEY_NOT_FOUND; integer i; string name; string desc; for ( i = 2; i <= llGetNumberOfPrims(); i++ ) { name = llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0); desc = llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0); if ( llToLower(name) == llToLower(dbkey) && llToLower(desc) == llToLower(field) ) { out = llList2String(llGetLinkPrimitiveParams(i,[PRIM_TEXT]),0); //DEBUG("GET_VAL RETURN=["+out+"]"); return out; // bail on first match? } } //OWNERSAY("GET_VAL RETURN=["+out+"]"); return out; } LIST_TYPE(key id,string type) { integer chan = (integer)("0x"+llGetSubString(id,0,6)); type = llToUpper(type); // scan index or prim names for empty, get number for update integer i; string name = ""; string desc = ""; list out = []; for ( i = 2; i <= llGetNumberOfPrims(); i++) { name = llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0); if ( name == type ) { desc = llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0); out = out + [desc]; } } out = llListSort(out,1,TRUE); if ( type == "STATISTIC" ) llSay(chan,"STATISTICS|"+llList2CSV(out)); if ( type == "SKILL" ) llSay(chan,"SKILLS|"+llList2CSV(out)); if ( type == "EFFECT" ) llSay(chan,"EFFECTS|"+llList2CSV(out)); if ( type == "RESILIENCE" ) llSay(chan,"RESILIENCES|"+llList2CSV(out)); if ( type == "BOON" ) llSay(chan,"BOONS|"+llList2CSV(out)); if ( type == "FLAW" ) llSay(chan,"FLAWS|"+llList2CSV(out)); if ( type == "CAMPAIGN" ) llSay(chan,"CAMPAIGNS|"+llList2CSV(out)); if ( type == "SPECIE" ) llSay(chan,"SPECIES|"+llList2CSV(out)); if ( type == "BACKGROUND" ) llSay(chan,"BACKGROUNDS|"+llList2CSV(out)); if ( type == "CAREER" ) llSay(chan,"CAREERS|"+llList2CSV(out)); if ( type == "ITEM" ) llSay(chan,"ITEMS|"+llList2CSV(out)); } SET_VAL(string dbkey, string field, string val) { //OWNERSAY("SET_VAL KEY=["+dbkey+"] FIELD=["+field+"] VAL=["+val+"]"); integer i; string name; string desc; integer written = FALSE; for ( i = 2; i <= llGetNumberOfPrims(); i++ ) { name = llStringTrim(llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0),STRING_TRIM); desc = llStringTrim(llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0),STRING_TRIM); if ( ( llToLower(name) == llToLower(dbkey) && llToLower(desc) == llToLower(field) ) && written == FALSE ) { //OWNERSAY("SET_VAL UPDATE RECORD=["+(string)i+"] DBKEY=["+dbkey+"] DESC=["+field+"] VAL=["+val+"]"); llSetLinkPrimitiveParamsFast(i,[PRIM_NAME,dbkey,PRIM_DESC,field,PRIM_TEXT,val,ZERO_VECTOR,0.0]); written = TRUE; // we did an update, remember it } } if ( written == TRUE ) { //OWNERSAY("SET_VAL UPDATE COMPLETE."); return; } // data hasn't been written, scan for free prim for ( i = 2; i <= llGetNumberOfPrims(); i++ ) { name = llStringTrim(llList2String(llGetLinkPrimitiveParams(i,[PRIM_NAME]),0),STRING_TRIM); desc = llStringTrim(llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0),STRING_TRIM); if ( ( name == "" && desc == "" ) && written == FALSE ) { //OWNERSAY("SET_VAL INSERT RECORD=["+(string)i+"] DBKEY=["+dbkey+"] DESC=["+field+"] VAL=["+val+"]"); llSetLinkPrimitiveParamsFast(i,[PRIM_NAME,dbkey,PRIM_DESC,field,PRIM_TEXT,val,ZERO_VECTOR,0.0]); written = TRUE; // we did an update, remember it } } if ( written == TRUE ) { //OWNERSAY("SET_VAL INSERT COMPLETED."); return; } //OWNERSAY("SET_VAL NO FREE RECORD FOUND TO INSERT INTO! DATA LOST"); } // FLAG FUNCTIONS // INCAPACITATED - lost wounds // DEAD - lost critical wounds // IDEA: INDECISION - lost resolve? // LMIM: SET_FLAG|<name>=<TRUE|FALSE> // PPMA: FLAG,<flagname>,<TRUE|FALSE> // LMOUT: FLAG|<flagname>=<TRUE|FALSE> // LMERR: FIXME integer GET_FLAG(string flag) { string val = GET_VAL("FLAG",llToUpper(flag)); if ( val == KEY_NOT_FOUND ) { ERROR("Flag ["+flag+"] does not exist."); } if ( val != "0" && val != "1") { ERROR("Flag: "+flag+" invalid value ["+val+"]"); } integer bool = (integer)val; return bool; } // SET_FLAG // LMIM: SET_FLAG|<flagname>=<TRUE|FALSE> // PPMA: FLAG,<flagname>,<TRUE|FALSE> // LMOUT: SET_FLAG|<flagname>=<TRUE|FALSE> // LMERR: FIXME //SET_FLAG(string flag,integer value) { // if ( flag == "" ) return; // FIXME add error // if ( value != TRUE && value != FALSE ) return; // FIXME add err // SET_VAL("FLAG",llToUpper(flag),(string)value); //} // // GET_MYRIAD // Requires a MYRIAD CONSTANT NAME // Returns the amount of that Myriad rules constant or defaultif the player does not currently have that constant // integer GET_MYRIAD(string setting) { integer retval; string value = GET_VAL("MYRIAD",setting); if ( value == KEY_NOT_FOUND ) { if ( setting == "MINSTAT" ) retval = 1; if ( setting == "MAXSTAT" ) retval = 10; if ( setting == "MINSKILL" ) retval = 0; if ( setting == "MAXSKILL" ) retval = 7; if ( setting == "MINEFFECT" ) retval = 0; if ( setting == "MAXEFFECT" ) retval = 5; if ( setting == "MINRESILIENCE" ) retval = 0; if ( setting == "MAXRESILIENCE" ) retval = 20; if ( setting == "MINBOON" ) retval = 0; if ( setting == "MAXBOON" ) retval = 5; if ( setting == "MINFLAW" ) retval = 0; if ( setting == "MAXFLAW" ) retval = 5; if ( setting == "MINRP" ) retval = 0; if ( setting == "MAXRP" ) retval = 10; if ( setting == "MINITEM" ) retval = 0; if ( setting == "MAXITEM" ) retval = 100; if ( setting == "MINARMOR" ) retval = 0; if ( setting == "MAXARMOR" ) retval = 5; if ( setting == "MINDAMAGE" ) retval = 1; if ( setting == "MAXDAMAGE" ) retval = 5; ERROR("Unable to locate Myriad setting "+setting+" returning "+(string)retval); } else { retval = (integer)value; } return retval; } /////////////////// // ASPECTS /////////////////// // STATISTICS // LMIN: GET_STATISTIC|<name> // PPMA: STATISTIC,<name>,<rank> // LMOUT: STATISTIC|<name>=<rank> // LMERR: FIXME integer GET_STATISTIC(string stat) { // FIXME how to verify stat? integer rank = (integer)GET_VAL("STATISTIC",stat); if ( rank < GET_MYRIAD("MINSTAT") ) { rank = GET_MYRIAD("MINSTAT"); SET_STATISTIC(stat,rank); } if ( rank > GET_MYRIAD("MAXSTAT") ) { rank = GET_MYRIAD("MAXSTAT"); SET_STATISTIC(stat,rank); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"STATISTIC|"+stat+"="+(string)rank,llGetOwner()); // REMOVEME return rank; } // LMIN: SET_STATISTIC|<name>=<rank> // PPMA: STATISTIC,<name>,<rank> // LMOUT: SET_STATISTIC|<name>,<rank> // LMERR: FIXME SET_STATISTIC(string stat,integer rank) { // FIXME how to verify stat names are valid? if ( rank < GET_MYRIAD("MINSTAT") ) rank = GET_MYRIAD("MINSTAT"); if ( rank > GET_MYRIAD("MAXSTAT") ) rank = GET_MYRIAD("MAXSTAT"); SET_VAL("STATISTIC",stat,(string)rank); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_STATISTIC|"+stat+"="+(string)rank,llGetOwner()); // REMOVEME } // SKILLS // LMIN: GET_SKILL|<name> // PPMA: SKILL,<name>,<rank> // LMOUT: SKILL|<name>=<rank> // LMERR: FIXME integer GET_SKILL(string skill) { integer rank = (integer)GET_VAL("SKILL",skill); if ( rank < GET_MYRIAD("MINSKILL") ) { rank = GET_MYRIAD("MINSKILL"); SET_SKILL(skill,rank); } if ( rank > GET_MYRIAD("MAXSKILL") ) { rank = GET_MYRIAD("MAXSKILL"); SET_SKILL(skill,rank); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SKILL|"+skill+"="+(string)rank,llGetOwner()); // REMOVEME return rank; } // LMIN: SET_SKILL|<name>=<rank> // PPMA: SKILL,<name>,<rank> // LMOUT: SET_SKILL|<name>=<rank> // LMERR: FIXME SET_SKILL(string skill,integer rank) { // TODO how to verify skill names are valid? if ( rank < GET_MYRIAD("MINSKILL") ) rank = GET_MYRIAD("MINSKILL"); if ( rank > GET_MYRIAD("MAXSKILL") ) rank = GET_MYRIAD("MAXSKILL"); SET_VAL("SKILL",skill,(string)rank); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_SKILL|"+skill+"="+(string)rank,llGetOwner()); // REMOVEME } // SFX // LMIN: GET_EFFECT|<name> // PPMA: EFFECT,<name>,<rank> // LMOUT: EFFECT|<name>=<rank> // LMERR: FIXME integer GET_EFFECT(string name) { integer rank = (integer)GET_VAL("EFFECT",name); if ( rank < GET_MYRIAD("MINEFFECT") ) { rank = GET_MYRIAD("MINEFFECT"); SET_EFFECT(name,rank); } if ( rank > GET_MYRIAD("MAXEFFECT") ) { rank = GET_MYRIAD("MAXEFFECT"); SET_EFFECT(name,rank); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"EFFECT|"+name+"="+(string)rank,llGetOwner()); // REMOVEME return rank; } // LMIN: SET_EFFECT|<name>=<rank> // PPMA: EFFECT,<name>,<rank> // LMOUT: SET_EFFECT|<name>=<rank> // LMERR: FIXME SET_EFFECT(string name,integer rank) { // TODO how to verify effect name? if ( rank < GET_MYRIAD("MINEFFECT") ) rank = GET_MYRIAD("MINEFFECT"); if ( rank > GET_MYRIAD("MAXEFFECT") ) rank = GET_MYRIAD("MAXEFFECT"); SET_VAL("EFFECT",name,(string)rank); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_EFFECT|"+name+"="+(string)rank,llGetOwner()); // REMOVEME } // RESILIENCES // LMIN: GET_RESILIENCE|<name> // PPMA: RESILIENCE,<name>,<amount> // LMOUT: RESILIENCE|<name>=<amount> // LMERR: FIXME integer GET_RESILIENCE(string name) { integer amount = (integer)GET_VAL("RESILIENCE",name); if ( amount < GET_MYRIAD("MINRESILIENCE") ) { amount = GET_MYRIAD("MINRESILIENCE"); SET_RESILIENCE(name,amount); } if ( amount > GET_MYRIAD("MAXRESILIENCE") ) { amount = GET_MYRIAD("MAXRESILIENCE"); SET_RESILIENCE(name,amount); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"RESILIENCE|"+name+"="+(string)amount,llGetOwner()); // REMOVEME return amount; } // LMIN: SET_RESILIENCE|<name>=<amount> // PPMA: RESILIENCE,<name>,<amount> // LMOUT: SET_RESILIENCE|<name>=<amount> // LMERR: FIXME SET_RESILIENCE(string name,integer amount) { // TODO how to verify resilience names are valid? if ( amount < GET_MYRIAD("MINRESILIENCE") ) amount = GET_MYRIAD("MINRESILIENCE"); if ( amount > GET_MYRIAD("MAXRESILIENCE") ) amount = GET_MYRIAD("MAXRESILIENCE"); SET_VAL("RESILIENCE",name,(string)amount); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_RESILIENCE|"+name+"="+(string)amount,llGetOwner()); // REMOVEME } // BOONS // LMIN: GET_BOON|<name> // PPMA: BOON,<name>,<rank> // LMOUT: BOON|<name>=<rank> // LMERR: FIXME integer GET_BOON(string boon) { integer rank = (integer)GET_VAL("BOON",boon); if ( rank < GET_MYRIAD("MINBOON") ) { rank = GET_MYRIAD("MINBOON"); SET_BOON(boon,rank); } if ( rank > GET_MYRIAD("MAXBOON") ) { rank = GET_MYRIAD("MAXBOON"); SET_BOON(boon,rank); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"BOON|"+boon+"="+(string)rank,llGetOwner()); // REMOVEME return rank; } // LMIN: SET_BOON|<name>=<rank> // PPMA: BOON,<name>,<rank> // LMOUT: SET_BOON|<name>=<rank> // LMERR: FIXME SET_BOON(string boon,integer rank) { // TODO how to verify boon names are valid? if ( rank < GET_MYRIAD("MINBOON") ) rank = GET_MYRIAD("MINBOON"); if ( rank > GET_MYRIAD("MAXBOON") ) rank = GET_MYRIAD("MAXBOON"); SET_VAL("BOON",boon,(string)rank); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_BOON|"+boon+"="+(string)rank,llGetOwner()); // REMOVEME } // FLAWS // LMIN: GET_FLAW|<name> // PPMA: FLAW,<name>,<rank> // LMOUT: FLAW|<name>=<rank> // LMERR: FIXME integer GET_FLAW(string flaw) { integer rank = (integer)GET_VAL("FLAW",flaw); if ( rank < GET_MYRIAD("MINFLAW") ) { rank = GET_MYRIAD("MINFLAW"); SET_FLAW(flaw,rank); } if ( rank > GET_MYRIAD("MAXFLAW") ) { rank = GET_MYRIAD("MAXFLAW"); SET_FLAW(flaw,rank); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"FLAW|"+flaw+"="+(string)rank,llGetOwner()); // REMOVEME return rank; } // LMIN: SET_FLAW|<name>=<rank> // PPMA: FLAW,<name>,<rank> // LMOUT: SET_FLAW|<name>=<rank> // LMERR: FIXME SET_FLAW(string flaw,integer rank) { // TODO how to verify flaw names are valid? if ( rank < GET_MYRIAD("MINFLAW") ) rank = GET_MYRIAD("MINFLAW"); if ( rank > GET_MYRIAD("MAXFLAW") ) rank = GET_MYRIAD("MAXFLAW"); SET_VAL("FLAW",flaw,(string)rank); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_FLAW|"+flaw+"="+(string)rank,llGetOwner()); } // SPECIES // LMIN: GET_SPECIE|<name> // PPMA: SPECIE,<name>,<data> // LMOUT: SPECIE|<name>=<data> // LMERR: FIXME string GET_SPECIE(string name) { // FIXME how to verify requested species name? string speciedata = GET_VAL("SPECIE",name); if ( speciedata == KEY_NOT_FOUND ) speciedata = "None"; // FIXME how to verify species data llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SPECIE|"+name+"="+speciedata,llGetOwner()); // REMOVEME return speciedata; } // FIXME LIST_SPECIES //string LIST_SPECIES() { // return ""; //} // LMIN: SET_SPECIE|<name>=<data> // PPMA: SPECIE,<name>,<data> // LMOUT: SET_SPECIE|<name>=<data> // LMERR: FIXME SET_SPECIE(string aspecies,string data) { // FIXME how to verify a good species name? // FIXME how to verify data SET_VAL("SPECIE",aspecies,data); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_SPECIE|"+aspecies+"="+data,llGetOwner()); // REMOVEME } // BACKGROUND // LMIN: GET_BACKGROUND|<name>=<data> // PPMA: BACKGROUND,<name>,<data> // LMOUT: BACKGROUND|<name>=<data> // LMERR: FIXME string GET_BACKGROUND(string name) { string bkgnddata = GET_VAL("BACKGROUND",name); if ( bkgnddata == KEY_NOT_FOUND ) bkgnddata = "None"; // FIXME how to verify background data? llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"BACKGROUND|"+name+"="+bkgnddata,llGetOwner()); return bkgnddata; } // FIXME LIST_BACKGROUNDS //string LIST_BACKGROUNDS() { // return ""; //} // LMIN: SET_BACKGROUND|<name>=<data> // PPMA: BACKGROUND,<name>,<data> // LMOUT: SET_BACKGROUND|<name>,<data> // LMERR: FIXME SET_BACKGROUND(string abkgnd,string data) { // FIXME how to verify background? SET_VAL("BACKGROUND",abkgnd,data); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_BACKGROUND|"+abkgnd+"="+data,llGetOwner()); // REMOVEME } // CAREER // LMIN: GET_CAREER|<name> // PPMA: CAREER,<name>,<data> // LMOUT: CAREER|<name>=<data> // LMERR: FIXME string GET_CAREER(string name) { string careerdata = GET_VAL("CAREER",name); if ( careerdata == KEY_NOT_FOUND ) careerdata = "None"; // FIXME how to verify career? llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"CAREER|"+name+"="+careerdata,llGetOwner()); return careerdata; } // FIXME LIST_CAREERS //string LIST_CAREERS() { // return ""; //} // LMIN: SET_CAREER|<name>=<data> // PPMA: CAREER,<name>,<data> // LMOUT: SET_CAREER|<name>=<data> // LMERR: FIXME SET_CAREER(string acareer,string data) { // FIXME how to verify name // FIXME how to verify data SET_VAL("CAREER",acareer,data); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_CAREER|"+acareer+"="+data,llGetOwner()); } // EQUIPMENT // LMIN: GET_ITEM|<name> // PPMA: ITEM,<name>,<amount> // LMOUT: ITEM|<name>=<amount> // LMERR: FIXME integer GET_ITEM(string name) { // FIXME verify equipment name is valid? integer amt = (integer)GET_VAL("ITEM",name); if ( amt < GET_MYRIAD("MINITEM") ) { amt = GET_MYRIAD("MINITEM"); SET_ITEM(name,amt); } if ( amt > GET_MYRIAD("MAXITEM") ) { amt = GET_MYRIAD("MAXITEM"); SET_ITEM(name,amt); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"ITEM|"+name+"="+(string)amt,llGetOwner()); return amt; } // LMIN: SET_ITEM|<name>=<amount> // PPMA: ITEM,<name>,<amount> // LMOUT: SET_ITEM|<name>=<amount> // LMERR: FIXME SET_ITEM(string name,integer amt) { // TODO how to verify the equipment name is valid? if ( amt < GET_MYRIAD("MINITEM") ) amt = GET_MYRIAD("MINITEM"); if ( amt > GET_MYRIAD("MAXITEM") ) amt = GET_MYRIAD("MAXITEM"); SET_VAL("ITEM",name,(string)amt); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_ITEM|"+name+"="+(string)amt,llGetOwner()); } /////////// /// Player Only aspects /////////// // NAME // LMIN: GET_NAME // PPMA: CHARACTER,NAME,<firstname> <lastname> // LMOUT: NONE // LMERR: Undefined // RSOUT: CHARACTER|NAME=<firstname> <lastname> // RSERR: Undefined // RETURN: NONE GET_NAME(key id) { string name = GET_VAL("CHARACTER","NAME"); if ( name == KEY_NOT_FOUND ) { OWNERSAY("Name not found. Resetting to default name Myriad Player"); name = "Myriad Player"; // set a default name if none is in the database SET_NAME(name); } string out = "CHARACTER|NAME="+name; if ( id != NULL_KEY ) { integer chan = (integer)("0x"+llGetSubString(id,0,6)); llRegionSay(chan,out); } // FIXME how to verify good name? //llMessageLinked(LINK_THIS,MODULE_CHARSHEET,out,llGetOwner()); // REMOVEME //return name; } // LMIN: SET_NAME|NAME=<firstname> <lastname> // PPMA: CHARACTER,NAME,<firstname> <lastname> // LMOUT: SET_CHARACTER|NAME=<firstname> <lastname> // LMERR: Undefined SET_NAME(string aname) { if ( aname == "" ) { // set NAME empty = delete SET_VAL("CHARACTER","NAME","Myriad Player"); OWNERSAY("Name deleted. Resetting name to Myriad Player."); return; } // FIXME how to verify a good name? SET_VAL("CHARACTER","NAME",aname); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_CHARACTER|NAME="+aname,llGetOwner()); // REMOVEME } // NICKNAME // LMIN: GET_NICKNAME // PPMA: CHARACTER,NICKNAME,<nickname> // LMOUT: NONE // LMERR: Undefined // RSOUT: CHARACTER|NICKNAME=<nickname> // RSERR: Undefined // RETURN: NONE GET_NICKNAME(key id) { string nickname = GET_VAL("CHARACTER","NICKNAME"); string out = "CHARACTER|NICKNAME="+nickname; if ( id != NULL_KEY ) { integer chan = (integer)("0x"+llGetSubString(id,0,6)); llRegionSay(chan,out); } // FIXME how to verify good name? //llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"CHARACTER|NICKNAME="+nickname,llGetOwner()); // REMOVEME //return nickname; } // LMIN: SET_CHARACTER|NICKNAME=<nickname> // PPMA: CHARACTER,NICKNAME,<nickname> // LMOUT: SET_CHARACTER|NICKNAME=<nickname> // LMERR: Undefined SET_NICKNAME(string anick) { if ( anick == "" ) { // set NICK empty = delete DELETE_RECORD("CHARACTER","NICKNAME"); OWNERSAY("Nickname deleted"); return; } // FIXME how to verify a good name? SET_VAL("CHARACTER","NICKNAME",anick); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_CHARACTER|NICKNAME="+anick,llGetOwner()); // REMOVEME } // TITLE // LMIN: GET_TITLE // PPMA: CHARACTER,TITLE,<title> // LMOUT: NONE // LMERR: Undefined // RSOUT: CHARACTER|TITLE=<title> // RSERR: Undefined // RETURN: NONE GET_TITLE(key id) { string title = GET_VAL("CHARACTER","TITLE"); string out = "CHARACTER|TITLE="+title; if ( id != NULL_KEY ) { integer chan = (integer)("0x"+llGetSubString(id,0,6)); llRegionSay(chan,out); } // FIXME how to verify good name? //llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"CHARACTER|TITLE="+title,llGetOwner()); // REMOVEME //return title; } // LMIN: SET_TITLE|TITLE=<title> // PPMA: CHARACTER,TITLE,<title> // LMOUT: SET_CHARACTER|TITLE=<title> // LMERR: Undefined SET_TITLE(string atitle) { if ( atitle == "" ) { // set TITLE empty = delete DELETE_RECORD("CHARACTER","TITLE"); OWNERSAY("Title deleted"); return; } // FIXME how to verify a good name? SET_VAL("CHARACTER","TITLE",atitle); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_CHARACTER|TITLE="+atitle,llGetOwner()); // REMOVEME } // FACTION // LMIN: GET_FACTION // PPMA: CHARACTER,FACTION,<factionname> // LMOUT: NONE // LMERR: Undefined // RSOUT: CHARACTER|FACTION=<factionname> // RSERR: Undefined // RETURN: NONE GET_FACTION(key id) { string faction = GET_VAL("CHARACTER","FACTION"); // FIXME how to verify good faction name? string out = "CHARACTER|FACTION="+faction; if ( id != NULL_KEY ) { integer chan = (integer)("0x"+llGetSubString(id,0,6)); llRegionSay(chan,out); } //llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"CHARACTER|FACTION="+faction,llGetOwner()); // REMOVEME //return faction; } // LMIN: SET_FACTION|FACTION=<factionname> // PPMA: CHARACTER,FACTION,<factionname> // LMOUT: SET_CHARACTER|FACTION=<factionname> // LMERR: Undefined SET_FACTION(string afaction) { if ( afaction == "" ) { // set FACTION empty = delete DELETE_RECORD("CHARACTER","FACTION"); OWNERSAY("Faction deleted"); return; } // FIXME how to verify a good name? SET_VAL("CHARACTER","FACTION",afaction); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_CHARACTER|FACTION="+afaction,llGetOwner()); // REMOVEME } // RP - GENERATOR POINTBUY // LMIN: // PPMA: // LMOUT: // LMERR: integer GET_RP() { integer rp = (integer)GET_VAL("CHARACTER","RP"); if ( rp < GET_MYRIAD("MINRP") ) { rp = GET_MYRIAD("MINRP"); SET_RP(rp); } if ( rp > GET_MYRIAD("MAXRP") ) { rp = GET_MYRIAD("MAXRP"); SET_RP(rp); } llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"PROGRESS|RP="+(string)rp,llGetOwner()); // REMOVEME return rp; } // LMIN: // PPMA: // LMOUT: // LMERR: SET_RP(integer rpamt) { if ( rpamt < GET_MYRIAD("MINRP") ) rpamt = GET_MYRIAD("MINRP"); if ( rpamt > GET_MYRIAD("MAXRP") ) rpamt = GET_MYRIAD("MAXRP"); SET_VAL("CHARACTER","RP",(string)rpamt); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"PROGRESS|RP="+(string)rpamt,llGetOwner()); // REMOVEME } // STUNTS // LMIN: // PPMA: // LMOUT: // LMERR: string GET_STUNT(string name) { string stunt = GET_VAL("STUNT",name); // TODO how to verify stunt? llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"STUNT|"+name+"="+stunt,llGetOwner()); // REMOVEME return stunt; } // LMIN: // PPMA: // LMOUT: // LMERR: SET_STUNT(string name,string stunt) { // TODO how to verify stunt? SET_VAL("STUNT",name,stunt); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_STUNT|"+name+"="+stunt,llGetOwner()); } // QUOTES // LMIN: // PPMA: // LMOUT: // LMERR: string GET_QUOTE(string name) { string quote = GET_VAL("QUOTE",name); // TODO how to verify quote? llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"QUOTE|"+name+"="+quote,llGetOwner()); // REMOVEME return quote; } // LMIN: // PPMA: // LMOUT: // LMERR: SET_QUOTE(string name,string quote) { // TODO how to verify quote? SET_VAL("QUOTE",name,quote); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_QUOTE|"+name+"="+quote,llGetOwner()); } DEBUG(string debugmsg) { if ( GET_FLAG("DEBUG") == TRUE ) llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"DEBUG|"+debugmsg,llGetOwner()); } DUMP_SHEET(key id) { // dump current character sheet key objectowner = llList2Key(llGetObjectDetails(id,[OBJECT_OWNER]),0); key regionowner = llList2Key(llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]),0); if ( objectowner != regionowner ) { ERROR("DUMP_SHEET called by object or player who is not region owner. ["+(string)objectowner+"]["+(string)regionowner+"]"); return; } DEBUG("Dumping character sheet to "+llKey2Name(id)+" ("+(string)id+")"); integer chan = (integer)("0x"+llGetSubString((string)id,0,6)); DUMP_TYPE(chan,"CHARACTER"); // FIXME DUMP_TYPE(chan,"STATISTIC"); // dump list of stats and values DUMP_TYPE(chan,"RESILIENCE"); // dump list of resiliences and values DUMP_TYPE(chan,"BOON"); // dump list of boons and values DUMP_TYPE(chan,"FLAW"); // dump list of flaws and values DUMP_TYPE(chan,"EFFECT"); // dump list of mortal sfx and values DUMP_TYPE(chan,"SKILL"); // dump list of skills and values DUMP_TYPE(chan,"ITEM"); // dump list of equipment DUMP_TYPE(chan,"STUNT"); // dump list of stunts DUMP_TYPE(chan,"QUOTE"); // dump list of quotes llSay(chan,"CHARACTER_LOADED"); } ERASE_SHEET(key id) { // erase current character sheet key objectowner = llList2Key(llGetObjectDetails(id,[OBJECT_OWNER]),0); key regionowner = llList2Key(llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]),0); if ( objectowner != regionowner || objectowner != llGetOwner() || id != llGetOwner() ) { ERROR("ERASE_SHEET called by object or player who is not player or region owner. ["+(string)objectowner+"]["+(string)regionowner+"]"); return; } DEBUG("Eraseing character sheet"); ERASE_TYPE("CHARACTER"); // FIXME ERASE_TYPE("STATISTIC"); // dump list of stats and values ERASE_TYPE("RESILIENCE"); // dump list of resiliences and values ERASE_TYPE("BOON"); // dump list of boons and values ERASE_TYPE("FLAW"); // dump list of flaws and values ERASE_TYPE("EFFECT"); // dump list of mortal sfx and values ERASE_TYPE("SKILL"); // dump list of skills and values ERASE_TYPE("ITEM"); // dump list of equipment ERASE_TYPE("STUNT"); // dump list of stunts ERASE_TYPE("QUOTE"); // dump list of quotes OWNERSAY("Character Sheet erased."); } ERROR(string errmsg) { llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"ERROR|"+errmsg,llGetOwner()); } // MEMORY GET_MEMORY() { OWNERSAY(BASENAME+" free memory: "+(string)llGetFreeMemory()); } // GETVERSION GET_VERSION() { OWNERSAY(BASENAME+" v"+VERSION+"-"+VERSIONDATE); } OWNERSAY(string msg) { llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"OWNERSAY|"+msg,llGetOwner()); } PARSE(string message,key id) { // debugged in chat and link message events // First - handle type 1 messages that do not require breaking down list tokens = llParseString2List(message,["|"],[]); string cmd = llToLower(llStringTrim(llList2String(tokens,0),STRING_TRIM)); string data = llList2String(tokens,1); list subtokens = llParseString2List(data,["="],[]); string attrib = llList2String(subtokens,0); integer idata = llList2Integer(subtokens,1); string sdata = llList2String(subtokens,1); // REMOVEME all GET_* command blocks once PPMA is integrated in all HUD scripts if ( cmd == "memory" ) { GET_MEMORY(); return;} // dump script memory if ( cmd == "reset" ) { RESET(); } // reset on request if ( cmd == "version") { GET_VERSION(); return; } // respond with version info when requested if ( cmd == "get_status" ) { GET_STATUS(id); return; } // respond to character sheet status requests if ( cmd == "set_status" ) { SET_STATUS(sdata); return; } // save character status if ( cmd == "dump_sheet" ) { DUMP_SHEET(id); return; } // id is UUID of character builder, sent over from HUD script if ( cmd == "dump_records") { DUMP_RECORDS(); return; } // dump prim persistent memory array if ( cmd == "erase_sheet" ) { ERASE_SHEET(id); return;} // erase character sheet if ( cmd == "format_db" ) { FORMAT_DB(); return;} if ( cmd == "region_setting" && llToLower(attrib) == "progression" ) { SET_PROGRESSION(sdata); return;} // ASPECTS if ( cmd == "get_statistic" ) { GET_STATISTIC(attrib); return;} if ( cmd == "set_statistic" ) { SET_STATISTIC(attrib,idata); return;} if ( cmd == "get_skill" ) { GET_SKILL(attrib); return;} if ( cmd == "set_skill" ) { SET_SKILL(attrib,idata); return;} if ( cmd == "get_effect" ) { GET_EFFECT(attrib); return;} if ( cmd == "set_effect" ) { SET_EFFECT(attrib,idata); return;} if ( cmd == "get_resilience" ) { GET_RESILIENCE(attrib); return;} if ( cmd == "set_resilience" ) { SET_RESILIENCE(attrib,idata); return;} if ( cmd == "get_boon" ) { GET_BOON(attrib); return;} if ( cmd == "set_boon" ) { SET_BOON(attrib,idata); return;} if ( cmd == "get_flaw" ) { GET_FLAW(attrib); return;} if ( cmd == "set_flaw" ) { SET_FLAW(attrib,idata); return;} if ( cmd == "get_specie" ) { GET_SPECIE(attrib); return;} if ( cmd == "set_specie" ) { SET_SPECIE(attrib,sdata); return;} if ( cmd == "get_background" ) { GET_BACKGROUND(attrib); return;} if ( cmd == "set_background" ) { SET_BACKGROUND(attrib,sdata); return;} if ( cmd == "get_career" ) { GET_CAREER(attrib); return;} if ( cmd == "set_career" ) { SET_CAREER(attrib,sdata); return;} if ( cmd == "get_item" ) { GET_ITEM(attrib); return;} if ( cmd == "set_item" ) { SET_ITEM(attrib,idata); return;} if ( cmd == "get_name" ) { GET_NAME(id); return;} if ( cmd == "set_name" ) { SET_NAME(sdata); return;} if ( cmd == "get_nickname" ) { GET_NICKNAME(id); return;} if ( cmd == "set_nickname" ) { SET_NICKNAME(sdata); return;} if ( cmd == "get_title" ) { GET_TITLE(id); return;} if ( cmd == "set_title" ) { SET_TITLE(sdata); return;} if ( cmd == "get_faction") { GET_FACTION(id); return;} if ( cmd == "set_faction" ) { SET_FACTION(sdata); return;} if ( cmd == "get_stunt" ) { GET_STUNT(sdata); return;} if ( cmd == "set_stunt" ) { SET_STUNT(attrib,sdata); return;} if ( cmd == "get_quote" ) { GET_QUOTE(sdata); return;} if ( cmd == "set_quote" ) { SET_QUOTE(attrib,sdata); return;} if ( cmd == "get_rp" ) { GET_RP(); return;} if ( cmd == "set_rp" ) { SET_RP(idata); return;} // LIST FUNCTIONS if ( cmd == "list_statistics" ) { LIST_TYPE(id,"STATISTIC"); return;} if ( cmd == "list_skills" ) { LIST_TYPE(id,"SKILL"); return;} if ( cmd == "list_effects" ) { LIST_TYPE(id,"EFFECT"); return;} if ( cmd == "list_resiliences" ) { LIST_TYPE(id,"RESILIENCE"); return;} if ( cmd == "list_boons" ) { LIST_TYPE(id,"BOON"); return;} if ( cmd == "list_flaws" ) { LIST_TYPE(id,"FLAW"); return;} if ( cmd == "list_species" ) { LIST_TYPE(id,"SPECIE"); return;} if ( cmd == "list_backgrounds" ) { LIST_TYPE(id,"BACKGROUND"); return;} if ( cmd == "list_careers" ) { LIST_TYPE(id,"CAREER"); return;} if ( cmd == "list_items" ) { LIST_TYPE(id,"ITEM"); return;} } RESET() { // do any final work, then reset llResetScript(); } string PROGRESSION; // Progression Method: LEVEL, GRADUAL, or RANDOM GET_PROGRESSION() { integer CHANMYRIAD = -999; // REMOVEME llRegionSay(CHANMYRIAD,"GET_REGION_SETTING|PROGRESSION"); // ask for this first, asking for estate triggers find_notecard function } SET_PROGRESSION(string method) { method = llToUpper(method); if ( method == "LEVEL-BASED" || method == "GRADUAL" || method == "RANDOM" ) { PROGRESSION = method; DEBUG("Character progression method set to: "+method); } else { ERROR("Unknown progression method: "+method+"! Roleplay progress will not be counted."); } } GET_STATUS(key id) { DEBUG("Sending character sheet status to "+llKey2Name(id)+" ("+(string)id+")"); integer chan = (integer)("0x"+llGetSubString((string)id,0,6)); string status = GET_VAL("CHARACTER","STATUS"); if ( status != "NONE" && status != "DRAFT" && status != "COMPLETE" ) { status = "NONE"; } llSay(chan,"CHARACTER|STATUS="+status); llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"CHARACTER|STATUS="+status,llGetOwner()); } SET_STATUS(string status) { if ( status == "NONE" || status == "DRAFT" || status == "COMPLETE" ) { SET_VAL("CHARACTER","STATUS",status); } else { ERROR("SET_STATUS: Invalid character status: "+status); } } SETUP() { GET_PROGRESSION(); OWNERSAY("Character Sheet module active."); } default { link_message(integer sender_num,integer num,string str,key id) { if ( num == MODULE_CHARSHEET || num == LM_SENDTOATTACHMENT ) return; // ignore link messages not sent to us specifically list tokens = llParseString2List(str,["|"],[]); string cmd = llToLower(llStringTrim(llList2String(tokens,0),STRING_TRIM)); if ( cmd == "debug" || cmd == "error" || cmd == "help" || cmd == "ownersay" || cmd == "rpevent" ) return; // ignore WELL commands // debug after message we're ignoring DEBUG("EVENT link_message sender_num=["+(string)sender_num+"] num=["+(string)num+"] str=["+str+"] id=["+(string)id+"]"); PARSE(str,id); // parse incoming message } state_entry() { SETUP(); } } // END