// Myriad_Lite_Module_RLV-v0.0.0-20131024.lsl
// Copyright (c) 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/
// SEE: http://wiki.secondlife.com/wiki/LSL_Protocol/RestrainedLoveAPI
// RLV_VERSIONNUM();
// ... more setup functions here
// RLV Functions http://wiki.secondlife.com/wiki/LSL_Protocol/RestrainedLoveAPI
// LOAD current from PPMA
// -- VERSIONS
// Automated version @version=<channel>
// RPG: Automated version @versionnew=<channel>
// RPG: Automated version @versionnum=<channel>
// Manual version IM @version
// --- BLACKLIST
// Automated version followed by blacklist: @versionnumbl=<channel>
// Get contents of the blacklist with filter: @getblacklist[:filter]=<channel>
// Manual blacklist checking: IM @getblacklist
// --- MISCELLANEOUS
// Start/stop notifications on a private channel: @notify:<channel>[;word]=<rem/add>
// /accepted_in_rlv inv_offer <folder> accepted and available under #RLV/
// /accepted_in_inv inv_offer <folder> accepted but not shared
// /declined inv_offer <folder>
// /worn legally <layer>
// /unworn legally <layer>
// /attached legally <attach_point_name>
// /attached illegally <attach_point_name>
// /detached legally <attach_point_name>
// /detached illegally <attach_point_name>
// Allow/deny permissive exceptions: @permissive=y/n RLV,PERMISSIVE,y/n
// Clear all rules tied to an object: @clear
// Clear a subset of the rules tied to an object: @clear=<string>
// RPG: Get the list of restrictions the avatar is currently submitted to: @getstatus[:<part_of_rule>[;<custom_separator>]]=<channel>
// Get the list of ALL restrictions the avatar is currently submitted to: @getstatusall[:<part_of_rule>[;<custom_separator>]]=<channel>
// --- MOVEMENT
// RPG: Allow/prevent flying @fly=<y/n>
// Allow/prevent run by double-tap an arrow: @temprun=<y/n>
// RPG: Allow/prevent always running: @alwaysrun=<y/n>
// Force rotate the avatar to a set direction: @setrot=<angle_in_radians>=force
// BROKEN w/SSA Change the height of the avatar: @adjustheight:<distance_pelvis_to_foot_in_meters>;<factor>[;delta_in_meters]=force
// --- CHAT
// Allow/prevent sending chat: @sendchat=<y/n> - blocks channel 0, / works, /me 30 chars, /message 15 chars, punctuation blocked, . ends the string
// Allow/prevent shouting: @chatshout=<y/n> - forces llShout to llSay range
// Allow/prevent chatting at normal volume: @chatnormal=<y/n> - forces llSay to llWhisper range
// Allow/prevent whispering: @chatwhisper=<y/n> - force whisper to llSay range
// RPG: Redirect public chat to private channels: @redirchat:<channel>=<rem/add> -- turn ON OFF with Emoter control
// Allow/prevent receiving chat messages : "@recvchat=<y/n>"
// Allow/prevent receiving chat messages, secure way : "@recvchat_sec=<y/n>"
// Remove/add exceptions to the chat message receiving prevention : "@recvchat:<UUID>=<rem/add>"
// Allow/prevent receiving chat messages from someone in particular : "@recvchatfrom:<UUID>=<y/n>"
// --- EMOTES
// Remove/add an exception to the emote truncation above : "@emote=<rem/add>"
// Redirect public emotes to private channels : "@rediremote:<channel_number>=<rem/add>"
// Allow/prevent seeing emotes : "@recvemote=<y/n>"
// Allow/prevent receiving emotes seen in public chat from someone in particular : "@recvemotefrom:<UUID>=<y/n>"
// Allow/prevent seeing emotes, secure way : "@recvemote_sec=<y/n>"
// Remove/add exceptions to the emote seeing prevention : "@recvemote:<UUID>=<rem/add>"
// --- PRIVATE CHANNELS
// RPG: Allow/prevent using any chat channel but certain channels : @sendchannel[:<channel>]=<y/n> - only allow Myriad channels
// RPG: Allow/prevent using any chat channel but certain channels, secure way : @sendchannel_sec[:<channel>]=<y/n>
// --- INSTANT MESSAGES
// RPG: Allow/prevent sending instant messages : "@sendim=<y/n>"
// RPG: Allow/prevent sending instant messages, secure way : "@sendim_sec=<y/n>"
// Remove/add exceptions to the instant message sending prevention : "@sendim:<UUID>=<rem/add>"
// RPG: Allow/prevent sending instant messages to someone in particular : "@sendimto:<UUID>=<y/n>" - allow to region staff
// Allow/prevent starting an IM session with anyone : "@startim=<y/n>"
// Remove/add exceptions to the IM session start prevention : "@startim:<UUID>=<rem/add>"
// RPG: Allow/prevent starting an IM session with someone in particular : "@startimto:<UUID>=<y/n>" -- allow to region staff
// RPG: Allow/prevent receiving instant messages : "@recvim=<y/n>"
// RPG: Allow/prevent receiving instant messages, secure way : "@recvim_sec=<y/n>"
// Remove/add exceptions to the instant message receiving prevention : "@recvim:<UUID>=<rem/add>"
// RPG: Allow/prevent receiving instant messages from someone in particular : "@recvimfrom:<UUID>=<y/n>" - allow from Region staff
// --- TELEPORT
// RPG: Allow/prevent teleporting to a landmark : "@tplm=<y/n>" - enable TP in OOC, disable in IC
// RPG: Allow/prevent teleporting to a location : "@tploc=<y/n>" - enable TP in OOC, disable in IC
// RPG: Allow/prevent teleporting by a friend : "@tplure=<y/n>"
// RPG: Allow/prevent teleporting by a friend, secure way : "@tplure_sec=<y/n>"
// Remove/add exceptions to the friend teleport prevention : "@tplure:<UUID>=<rem/add>"
// RPG: Unlimit/limit sit-tp : "@sittp=<y/n>"
// RPG: Allow/prevent standing up at a different location than where we sat down : @standtp=<y/n>
// Force-Teleport the user : @tpto:<X>/<Y>/<Z>=force (*)
// RPG: Remove/add auto-accept teleport offers from a particular avatar : "@accepttp[:<UUID>]=<rem/add>" -- region owner and RPG staff?
// --- INVENTORY
// RPG: Allow/prevent using inventory : @showinv=<y/n>
// RPG: Allow/prevent reading notecards : @viewnote=<y/n>
// RPG: Allow/prevent opening scripts : @viewscript=<y/n>
// RPG: Allow/prevent opening textures : @viewtexture=<y/n>
// RPG: Allow/prevent editing objects : "@edit=<y/n>"
// Remove/add exceptions to the edit prevention : "@edit:<UUID>=<rem/add>"
// RPG: Allow/prevent rezzing inventory : "@rez=<y/n>"
// Allow/prevent editing particular objects : "@editobj:<UUID>=<y/n>"
// --- SITTING
// Allow/prevent standing up : @unsit=<y/n>
// Force sit on an object : @sit:<UUID>=force (*)
// Get the UUID of the object the avatar is sitting on : @getsitid=<channel_number>
// Force unsit : @unsit=force (*)
// Allow/prevent sitting down : @sit=<y/n>
// --- CLOTHING
// Render an object detachable/nondetachable : "@detach=<y/n>"
// Unlock/Lock an attachment point : "@detach:<attach_point_name>=<y/n>"
// Unlock/Lock an attachment point empty : "@addattach[:<attach_point_name>]=<y/n>"
// Unlock/Lock an attachment point full : "@remattach[:<attach_point_name>]=<y/n>"
// Allow/deny the "Wear" contextual menu : "@defaultwear=<y/n>
// Force removing attachments : @detach[:attachpt]=force (*)
// chest|skull|left shoulder|right shoulder|left hand|right hand|left foot|right foot|spine|
// pelvis|mouth|chin|left ear|right ear|left eyeball|right eyeball|nose|r upper arm|r forearm|
// l upper arm|l forearm|right hip|r upper leg|r lower leg|left hip|l upper leg|l lower leg|stomach|left pec|
// right pec|center 2|top right|top|top left|center|bottom left|bottom|bottom right|neck|root
// If part is not specified, removes everything.
// Force removing attachments (alias) : @remattach[:attachpt]=force (*)
// Allow/prevent wearing clothes : @addoutfit[:<part>]=<y/n>
// gloves|jacket|pants|shirt|shoes|skirt|socks|underpants|undershirt|skin|eyes|hair|shape|alpha|tattoo|physics
// If part is not specified, prevents from wearing anything beyond what the avatar is already wearing.
// Allow/prevent removing clothes : @remoutfit[:<part>]=<y/n> (underpants and undershirt are kept for teens)
// gloves|jacket|pants|shirt|shoes|skirt|socks|underpants|undershirt|skin|eyes|hair|shape|alpha|tattoo|physics
// If part is not specified, prevents from removing anything in what the avatar is wearing
// Force removing clothes : @remoutfit[:<part>]=force (*) (teens can't be forced to remove underpants and undershirt)
// gloves|jacket|pants|shirt|shoes|skirt|socks|underpants|undershirt|alpha|tattoo|physics
// If part is not specified, removes everything.
// Get the list of worn clothes : @getoutfit[:part]=<channel_number>
// gloves,jacket,pants,shirt,shoes,skirt,socks,underpants,undershirt,skin,eyes,hair,shape
// gloves,jacket,pants,shirt,shoes,skirt,socks,underpants,undershirt,skin,eyes,hair,shape,alpha,tattoo
// Get the list of worn attachments : @getattach[:attachpt]=<channel_number>
// none,chest,skull,left shoulder,right shoulder,left hand,right hand,left foot,right foot,spine,
// pelvis,mouth,chin,left ear,right ear,left eyeball,right eyeball,nose,r upper arm,r forearm,
// l upper arm,l forearm,right hip,r upper leg,r lower leg,left hip,l upper leg,l lower leg,stomach,left pec,
// right pec,center 2,top right,top,top left,center,bottom left,bottom,bottom right,neck,root
// Force the viewer to automatically accept attach and take control permission requests : @acceptpermission=<rem/add>
// Allow/prevent accepting attach and take control permissions : @denypermission=<rem/add>
// Force detach an item : @detachme=force (*)
// --- SHARED FOLDERS
// Allow/prevent wearing clothes and attachments that are not part of the #RLV folder : @unsharedwear=<y/n>
// Allow/prevent removing clothes and attachments that are not part of the #RLV folder : @unsharedunwear=<y/n>
// Get the list of shared folders in the avatar's inventory : @getinv[:folder1/.../folderN]=<channel_number>
// Get the list of shared folders in the avatar's inventory, with information about worn items : @getinvworn[:folder1/.../folderN]=<channel_number>
// Get the path to a shared folder by giving a search criterion : @findfolder:part1[&&...&&partN]=<channel_number>
// Force attach items contained inside a shared folder : @attach:<folder1/.../folderN>=force (*)
// Force attach items contained inside a shared folder, without replacing what is already being worn : @attachover:<folder1/.../folderN>=force (*)
// Force attach items contained inside a shared folder : @attachoverorreplace:<folder1/.../folderN>=force (*)
// Force attach items contained inside a shared folder, and its children recursively : @attachall:<folder1/.../folderN>=force (*)
// Force attach items contained inside a shared folder, and its children recursively, without replacing what is already being worn : @attachallover:<folder1/.../folderN>=force (*)
// Force attach items contained inside a shared folder, and its children recursively : @attachalloverorreplace:<folder1/.../folderN>=force (*)
// Force detach items contained inside a shared folder : @detach:<folder_name>=force (*)
// Force detach items contained inside a shared folder, and its children recursively : @detachall:<folder1/.../folderN>=force (*)
// Get the path to the shared folder containing a particular object/clothing worn on a point : @getpath[:<attachpt> or <clothing_layer>]=<channel_number>
// Get the all paths to the shared folders containing the objects/clothing worn on a point : @getpathnew[:<attachpt> or <clothing_layer>]=<channel_number>
// Force attach items contained into a shared folder that contains a particular object/clothing : @attachthis[:<attachpt> or <clothing_layer>]=force (*)
// Force attach items contained inside a shared folder, without replacing what is already being worn : @attachthisover[:<attachpt> or <clothing_layer>]=force (*)
// Force attach items contained inside a shared folder : @attachthisoverorreplace[:<attachpt> or <clothing_layer>]=force (*)
// Force attach items contained into a shared folder that contains a particular object/clothing, and its children folders : @attachallthis[:<attachpt> or <clothing_layer>]=force (*)
// Force attach items contained inside a shared folder, without replacing what is already being worn : @attachallthisover[:<attachpt> or <clothing_layer>]=force (*)
// Force attach items contained inside a shared folder : @attachallthisoverorreplace[:<attachpt> or <clothing_layer>]=force (*)
// Force detach items contained into a shared folder that contains a particular object/clothing : @detachthis[:<attachpt> or <clothing_layer>]=force (*)
// Force detach items contained into a shared folder that contains a particular object/clothing, and its children folders : @detachallthis[:<attachpt> or <clothing_layer>]=force (*)
// Allow/prevent removing some folders : @detachthis[:<layer>|<attachpt>|<path_to_folder>]=<y/n>
// Allow/prevent removing some folders and their children : @detachallthis[:<layer>|<attachpt>|<path_to_folder>]=<y/n>
// Allow/prevent wearing some folders : @attachthis:<layer>|<attachpt>|<path_to_folder>=<y/n>
// Allow/prevent wearing some folders and their children : @attachallthis[:<layer>|<attachpt>|<path_to_folder>]=<y/n>
// Remove/add exceptions to the detachallthis restriction, for one folder only : "@detachthis_except:<folder>=<rem/add>"
// Remove/add exceptions to the detachallthis restriction, for one folder and its children : "@detachallthis_except:<folder>=<rem/add>"
// Remove/add exceptions to the attachallthis restriction, for one folder only : "@attachthis_except:<folder>=<rem/add>"
// Remove/add exceptions to the attachallthis restriction, for one folder and its children : "@attachallthis_except:<folder>=<rem/add>"
// --- TOUCH
// RPG: Allow/prevent touching objects located further than 1.5 meters away from the avatar : @fartouch=<y/n>
// Allow/prevent touching objects located further than 1.5 meters away from the avatar : @touchfar=<y/n>
// Allow/prevent touching any objects : @touchall=<y/n>
// Allow/prevent touching objects in-world : @touchworld=<y/n>
// Remove/add exceptions to the touchworld prevention : "@touchworld:<UUID>=<rem/add>"
// Allow/prevent touching one object in particular : @touchthis:<UUID>=<rem/add>
// Remove/add an exception to the touch* preventions, for one object only : "@touchme=<rem/add>"
// Allow/prevent touching attachments : @touchattach=<y/n>
// Allow/prevent touching one's attachments : @touchattachself=<y/n>
// ???: Allow/prevent touching other people's attachments : @touchattachother=<y/n>
// --- LOCATION
// RPG: Allow/prevent viewing the world map : @showworldmap=<y/n> -- only allow when holding MAP item
// RPG: Allow/prevent viewing the mini map : @showminimap=<y/n> -- only allow when holding SCANNER item
// RPG: Allow/prevent knowing the current location : @showloc=<y/n>
// --- NAME TAGS
// RPG: Allow/prevent seeing the names of the people around : @shownames=<y/n>
// RPG: Allow/prevent seeing all the hovertexts : @showhovertextall=<y/n>
// RPG: Allow/prevent seeing one hovertext in particular : @showhovertext:<UUID>=<y/n> -- allow see region owner and staff?
// RPG: Allow/prevent seeing the hovertexts on the HUD of the user : @showhovertexthud=<y/n>
// RPG: Allow/prevent seeing the hovertexts in-world : @showhovertextworld=<y/n>
// --- GROUP
// RPG: Force the agent to change the active group : @setgroup:<group_name>=force
// RPG: Allow/prevent activating a group : @setgroup=<y/n>
// Get the name of the active group : @getgroup=<channel_number>
// --- VIEWER
// Allow/prevent changing some debug settings : @setdebug=<y/n>
// Force change a debug setting : @setdebug_<setting>:<value>=force (*)
// Get the value of a debug setting : @getdebug_<setting>=<channel_number>
// RPG: Allow/prevent changing the environment settings : @setenv=<y/n>
// Allow/prevent changing the environment settings : @setenv=<y/n>
// RPG: Force change an environment setting : @setenv_<setting>:<value>=force (*) -- set world, drug effects, incapacitated and dead effects and more
// _daytime 0.0-1.0 and <0 Time of day (sunrise:0.25, midday:0.567, sunset:0.75, midnight:0.0, set back to region default:<0). Attention, resets all other Windlight parameters
// _preset String A Preset environment, e.g. Gelatto, Foggy. Attention, loading a Preset is heavy on the viewer and can slow it down for a short while, don't do it every second
// _ambientr 0.0-1.0 Ambient light, Red channel
// _ambientg 0.0-1.0 Ambient light, Green channel
// _ambientb 0.0-1.0 Ambient light, Blue channel
// _ambienti 0.0-1.0 Ambient light, Intensity
// _bluedensityr 0.0-1.0 Blue Density, Red channel
// _bluedensityg 0.0-1.0 Blue Density, Green channel
// _bluedensityb 0.0-1.0 Blue Density, Blue channel
// _bluedensityi 0.0-1.0 Blue Density, Intensity
// _bluehorizonr 0.0-1.0 Blue Horizon, Red channel
// _bluehorizong 0.0-1.0 Blue Horizon, Green channel
// _bluehorizonb 0.0-1.0 Blue Horizon, Blue channel
// _bluehorizoni 0.0-1.0 Blue Horizon, Intensity
// _cloudcolorr 0.0-1.0 Cloud color, Red channel
// _cloudcolorg 0.0-1.0 Cloud color, Green channel
// _cloudcolorb 0.0-1.0 Cloud color, Blue channel
// _cloudcolori 0.0-1.0 Cloud color, Intensity
// _cloudcoverage 0.0-1.0 Cloud coverage
// _cloudx 0.0-1.0 Cloud offset X
// _cloudy 0.0-1.0 Cloud offset Y
// _cloudd 0.0-1.0 Cloud density
// _clouddetailx 0.0-1.0 Cloud detail X
// _clouddetaily 0.0-1.0 Cloud detail Y
// _clouddetaild 0.0-1.0 Cloud detail density
// _cloudscale 0.0-1.0 Cloud scale
// _cloudscrollx 0.0-1.0 Cloud scroll X
// _cloudscrolly 0.0-1.0 Cloud scroll Y
// _densitymultiplier 0.0-0.9 Density multiplier of the fog
// _distancemultiplier 0.0-100.0 Distance multiplier of the fog
// _eastangle 0.0-1.0 Position of the east, 0.0 is normal
// _hazedensity 0.0-1.0 Density of the haze
// _hazehorizon 0.0-1.0 Haze at the horizon
// _maxaltitude 0.0-4000.0 Maximum altitude of the fog
// _scenegamma 0.0-10.0 Overall gamma, 1.0 is normal
// _starbrightness 0.0-2.0 Brightness of the stars
// _sunglowfocus 0.0-0.5 Focus of the glow of the sun
// _sunglowsize 1.0-2.0 Size of the glow of the sun
// _sunmooncolorr 0.0-1.0 Sun and moon, Red channel
// _sunmooncolorg 0.0-1.0 Sun and moon, Green channel
// _sunmooncolorb 0.0-1.0 Sun and moon, Blue channel
// _sunmooncolori 0.0-1.0 Sun and moon, Intensity
// _sunmoonposition 0.0-1.0 Position of the sun/moon, different from "daytime", use this to set the apparent sunlight after loading a Preset
// Get the value of an environment setting : @getenv_<setting>=<channel_number>
// CONSTANTS - DO NOT CHANGE DURING RUN
string BASENAME = "Myriad Lite Module RLV";
string VERSION = "0.0.0"; // Allen Kerensky's script version
string VERSIONDATE = "20131024"; // Allen Kerensky's script yyyymmdd
// Module to Module Messaging Constants
integer MODULE_RLV = -15;
integer LM_SENDTOATTACHMENT = 0x80000000;
// Configurable
integer SPACE_OFFSET = 300; // How high over ground are we to be "in space" FIXME PPMA CONFIG,SPACEALTITIDE,<meters>
// Runtime globals - may change anytime during run
integer RLV_CHAN;
integer RLV_HAND;
string RLV_CMD;
integer RLV_AVAIL; // is RLV available?
vector CURPOS; // current X,Y,Z location of avatar
integer GROUND_LEVEL; // the current Z altitude of ground level under the av.
// FIXME move to PPMA RLV,<regionname>,<settingname>
//list SETTINGS = [
// "Myriad_Central", "Fine Day",
// "Myriad_Combat", "Rot",
// "Myriad_Medieval", "Alchemy Immortalis - Foggy Morning",
// "Myriad_Modern", "[EUPHORIA] air pollution 2",
// "Myriad_Future", "Blizzard",
// "Lani", "Arrakis",
// "ixi", "Arrakis",
// //"Bade Plaza", "",
// "Lbsa Plaza", "Annyka's Soft Lavender Day",
// //"Recreation Plaza", "",
// //"Sandbox Plaza", "",
// //"Sandbox Plaza II", "",
// "Seaprior Plaza", "Sailor's Delight",
// //"Teravus Plaza", "",
// //"Wright Plaza", "",
// //"Zaius Plaza", "",
// //"Jump4000", "",
// //"Jump8000", "",
// //"Cuteulala Park", "",
// "OSgrid Welcome Station", "Default"
//];
//
// PPMA GET_VAL
//
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;
}
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
// DEBUG - show debug messages or not
// 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_RLVREGION - check PPMA for RLV,<regionname>,<setting>
//
string GET_RLV(string setting) {
if ( setting == "" ) {
ERROR("GET_RLV passed empty setting");
return "";
}
string value = GET_VAL("RLV",setting);
if ( value == KEY_NOT_FOUND ) value = "";
return value;
}
//
// SET_RLV
//
SET_RLV(string setting,string value) {
if ( setting == "" || value == "" ) {
ERROR("SET_RLV passed empty setting or value.");
return;
}
SET_RLV(setting,value);
}
// DEBUG - show debug chat with wearer name for sorting
DEBUG(string dmessage) {
if ( GET_FLAG("DEBUG") == TRUE ) llMessageLinked(LINK_THIS,MODULE_RLV,"DEBUG|"+dmessage,llGetOwner());
}
// ERROR - show errors on debug channel with wearer name for sorting
ERROR(string emessage) {
llMessageLinked(LINK_THIS,MODULE_RLV,"ERROR|"+emessage,llGetOwner());
}
// MEMORY
GET_MEMORY() {
OWNERSAY(BASENAME+" free memory: "+(string)llGetFreeMemory()); // show this module's free memory info
}
// GETVERSION
GET_VERSION() {
OWNERSAY(BASENAME+" v"+VERSION+"-"+VERSIONDATE); // show this module's version info
}
// HELP
HELP(string help) {
llMessageLinked(LINK_THIS,MODULE_RLV,"HELP|"+help,llGetOwner());
}
OWNERSAY(string str) {
llMessageLinked(LINK_THIS,MODULE_RLV,"OWNERSAY|"+str,llGetOwner());
}
PARSE(string message,key id) {
DEBUG("PARSE message=["+message+"] id=["+(string)id+"]");
// Debug handled in say and link 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);
if ( cmd == "memory" ) { GET_MEMORY(); return; }
if ( cmd == "reset" ) { RESET(); return;}
if ( cmd == "version" ) { GET_VERSION(); return;}
// REMOVEME all GET_* command blocks once PPMA is integrated in all HUD scripts
if ( cmd == "rlv_ic" ) { RLV_IC(); return;} // switch to IC mode
if ( cmd == "rlv_ooc" ) { RLV_OOC(); return;} // switch to OOC mode
if ( cmd == "rlv_version" ) { RLV_VERSION(); return;}
if ( cmd == "rlv_versionnew" ) { RLV_VERSIONNEW(); return;}
if ( cmd == "rlv_versionnum" ) { RLV_VERSIONNUM(); return;}
}
//
// RESET
//
RESET() {
// do anything to clean up before reset
llResetScript();
}
RLV_CLOSE() {
if (RLV_HAND != 0) llListenRemove(RLV_HAND);
RLV_CHAN = -1;
llSetTimerEvent(0.0);
RLV_CMD = "";
}
RLV_IC() {
// FIXME region tool to enable OOC and in IC - location narrator?
//if ( RLV_AVAIL == TRUE ) {
list details = llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]);
key parcelowner = llList2String(details,0);
llOwnerSay("@fly=n"); // RPG: Allow/prevent flying @fly=<y/n>
llOwnerSay("@alwaysrun=n"); // RPG: Allow/prevent always running: @alwaysrun=<y/n>
llOwnerSay("@redirchat:44=add"); // RPG: Redirect public chat to private channels: @redirchat:<channel>=<rem/add>
// llOwnerSay("@sendchannel:<channel>=y"); // RPG: Allow/prevent using any chat channel but certain channels : @sendchannel[:<channel>]=<y/n> -- FIXME only allow Myriad channels
// llOwnerSay("@sendchannel:<channe>=y"); // RPG: Allow/prevent using any chat channel but certain channels, secure way : @sendchannel_sec[:<channel>]=<y/n> -- FIXME only allow Myriad channels
llOwnerSay("@sendim=n"); // RPG: Allow/prevent sending instant messages : "@sendim=<y/n>"
llOwnerSay("@sendim_sec=n"); // RPG: Allow/prevent sending instant messages, secure way : "@sendim_sec=<y/n>"
llOwnerSay("@sendimto:"+(string)parcelowner+"=y"); // RPG: Allow/prevent sending instant messages to someone in particular : "@sendimto:<UUID>=<y/n>" -- FIXME allow to region owner/staff
llOwnerSay("@startimto:"+(string)parcelowner+"=y"); // RPG: Allow/prevent starting an IM session with someone in particular : "@startimto:<UUID>=<y/n>" -- FIXME allow to region owner/staff
llOwnerSay("@recvim=n"); // RPG: Allow/prevent receiving instant messages : "@recvim=<y/n>"
llOwnerSay("@recvim_sec=n"); // RPG: Allow/prevent receiving instant messages, secure way : "@recvim_sec=<y/n>"
llOwnerSay("@recvimfrom:"+(string)parcelowner+"=y"); // RPG: Allow/prevent receiving instant messages from someone in particular : "@recvimfrom:<UUID>=<y/n>" - FIXME allow from region owner/staff
llOwnerSay("@tplm=n"); // RPG: Allow/prevent teleporting to a landmark : "@tplm=<y/n>"
llOwnerSay("@tploc=n"); // RPG: Allow/prevent teleporting to a location : "@tploc=<y/n>"
llOwnerSay("@tplure=n"); // RPG: Allow/prevent teleporting by a friend : "@tplure=<y/n>"
llOwnerSay("@tplure_sec=n"); // RPG: Allow/prevent teleporting by a friend, secure way : "@tplure_sec=<y/n>"
llOwnerSay("@sittp=n"); // RPG: Unlimit/limit sit-tp : "@sittp=<y/n>"
llOwnerSay("@standtp=n"); // RPG: Allow/prevent standing up at a different location than where we sat down : @standtp=<y/n>
llOwnerSay("@accepttp:"+(string)parcelowner+"=add"); // RPG: Remove/add auto-accept teleport offers from a particular avatar : "@accepttp[:<UUID>]=<rem/add>" -- FIXME allow from region owner/staff
llOwnerSay("@showinv=n"); // RPG: Allow/prevent using inventory : @showinv=<y/n>
llOwnerSay("@viewnote=n"); // RPG: Allow/prevent reading notecards : @viewnote=<y/n>
llOwnerSay("@viewscript=n"); // RPG: Allow/prevent opening scripts : @viewscript=<y/n>
llOwnerSay("@viewtexture=n"); // RPG: Allow/prevent opening textures : @viewtexture=<y/n>
llOwnerSay("@edit=n"); // RPG: Allow/prevent editing objects : "@edit=<y/n>"
llOwnerSay("@rez=n"); // RPG: Allow/prevent rezzing inventory : "@rez=<y/n>" -- FIXME TEST IF THIS AFFECTS BULLETS
llOwnerSay("@fartouch=n"); // RPG: Allow/prevent touching objects located further than 1.5 meters away from the avatar : @fartouch=<y/n>
llOwnerSay("@showworldmap=n"); // RPG: Allow/prevent viewing the world map : @showworldmap=<y/n> -- FIXME only allow when holding MAP item
llOwnerSay("@showminimap=n"); // RPG: Allow/prevent viewing the mini map : @showminimap=<y/n> -- FIXME only allow when holding SCANNER item
llOwnerSay("@showloc=n"); // RPG: Allow/prevent knowing the current location : @showloc=<y/n>
llOwnerSay("@shownames=n"); // RPG: Allow/prevent seeing the names of the people around : @shownames=<y/n>
llOwnerSay("@showhovertextall=n"); // RPG: Allow/prevent seeing all the hovertexts : @showhovertextall=<y/n>
llOwnerSay("@showhovertext:"+(string)parcelowner+"=y"); // RPG: Allow/prevent seeing one hovertext in particular : @showhovertext:<UUID>=<y/n> -- FIXME allow see region owner/staff
llOwnerSay("@showhovertexthud=n"); // RPG: Allow/prevent seeing the hovertexts on the HUD of the user : @showhovertexthud=<y/n> -- FIXME work around for BAM status?
llOwnerSay("@showhovertextworld=n"); // RPG: Allow/prevent seeing the hovertexts in-world : @showhovertextworld=<y/n>
llOwnerSay("@setgroup:Myriad RPG=force"); // RPG: Force the agent to change the active group : @setgroup:<group_name>=force // FIXME get current group - switch to whatever parcel group is
llOwnerSay("@setgroup=n"); // RPG: Allow/prevent activating a group : @setgroup=<y/n>
llOwnerSay("@setenv=n"); // RPG: Allow/prevent changing the environment settings : @setenv=<y/n>
// llOwnerSay("@setenv_preset:<presetname> =force"); // RPG: Force change an environment setting : @setenv_<setting>:<value>=force (*) -- FIXME set world, drug, incapacitated, dead, magic effects
OWNERSAY("Myriad Lite RLV IC Mode enabled");
//}
}
RLV_OOC() {
// FIXME region tool to enable OOC and in IC - location narrator?
//if ( RLV_AVAIL == TRUE ) {
list details = llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]);
key parcelowner = llList2String(details,0);
llOwnerSay("@fly=y"); // RPG: Allow/prevent flying @fly=<y/n>
llOwnerSay("@alwaysrun=y"); // RPG: Allow/prevent always running: @alwaysrun=<y/n>
llOwnerSay("@redirchat:44=rem"); // RPG: Redirect public chat to private channels: @redirchat:<channel>=<rem/add>
// llOwnerSay("@sendchannel:<channel>=y"); // RPG: Allow/prevent using any chat channel but certain channels : @sendchannel[:<channel>]=<y/n> -- FIXME only allow Myriad channels
// llOwnerSay("@sendchannel:<channe>=y"); // RPG: Allow/prevent using any chat channel but certain channels, secure way : @sendchannel_sec[:<channel>]=<y/n> -- FIXME only allow Myriad channels
llOwnerSay("@sendim=y"); // RPG: Allow/prevent sending instant messages : "@sendim=<y/n>"
llOwnerSay("@sendim_sec=y"); // RPG: Allow/prevent sending instant messages, secure way : "@sendim_sec=<y/n>"
//llOwnerSay("@sendimto:"+(string)parcelowner+"=y"); // RPG: Allow/prevent sending instant messages to someone in particular : "@sendimto:<UUID>=<y/n>" -- FIXME allow to region owner/staff
//llOwnerSay("@startimto:"+(string)parcelowner+"=y"); // RPG: Allow/prevent starting an IM session with someone in particular : "@startimto:<UUID>=<y/n>" -- FIXME allow to region owner/staff
llOwnerSay("@recvim=y"); // RPG: Allow/prevent receiving instant messages : "@recvim=<y/n>"
llOwnerSay("@recvim_sec=y"); // RPG: Allow/prevent receiving instant messages, secure way : "@recvim_sec=<y/n>"
//llOwnerSay("@recvimfrom:"+(string)parcelowner+"=y"); // RPG: Allow/prevent receiving instant messages from someone in particular : "@recvimfrom:<UUID>=<y/n>" - FIXME allow from region owner/staff
llOwnerSay("@tplm=y"); // RPG: Allow/prevent teleporting to a landmark : "@tplm=<y/n>"
llOwnerSay("@tploc=y"); // RPG: Allow/prevent teleporting to a location : "@tploc=<y/n>"
llOwnerSay("@tplure=y"); // RPG: Allow/prevent teleporting by a friend : "@tplure=<y/n>"
llOwnerSay("@tplure_sec=y"); // RPG: Allow/prevent teleporting by a friend, secure way : "@tplure_sec=<y/n>"
llOwnerSay("@sittp=y"); // RPG: Unlimit/limit sit-tp : "@sittp=<y/n>"
llOwnerSay("@standtp=y"); // RPG: Allow/prevent standing up at a different location than where we sat down : @standtp=<y/n>
llOwnerSay("@accepttp:"+(string)parcelowner+"=rem"); // RPG: Remove/add auto-accept teleport offers from a particular avatar : "@accepttp[:<UUID>]=<rem/add>" -- FIXME allow from region owner/staff
llOwnerSay("@showinv=y"); // RPG: Allow/prevent using inventory : @showinv=<y/n>
llOwnerSay("@viewnote=y"); // RPG: Allow/prevent reading notecards : @viewnote=<y/n>
llOwnerSay("@viewscript=y"); // RPG: Allow/prevent opening scripts : @viewscript=<y/n>
llOwnerSay("@viewtexture=y"); // RPG: Allow/prevent opening textures : @viewtexture=<y/n>
llOwnerSay("@edit=y"); // RPG: Allow/prevent editing objects : "@edit=<y/n>"
llOwnerSay("@rez=y"); // RPG: Allow/prevent rezzing inventory : "@rez=<y/n>" -- FIXME TEST IF THIS AFFECTS BULLETS
llOwnerSay("@fartouch=y"); // RPG: Allow/prevent touching objects located further than 1.5 meters away from the avatar : @fartouch=<y/n>
llOwnerSay("@showworldmap=y"); // RPG: Allow/prevent viewing the world map : @showworldmap=<y/n> -- FIXME only allow when holding MAP item
llOwnerSay("@showminimap=y"); // RPG: Allow/prevent viewing the mini map : @showminimap=<y/n> -- FIXME only allow when holding SCANNER item
llOwnerSay("@showloc=y"); // RPG: Allow/prevent knowing the current location : @showloc=<y/n>
llOwnerSay("@shownames=y"); // RPG: Allow/prevent seeing the names of the people around : @shownames=<y/n>
llOwnerSay("@showhovertextall=y"); // RPG: Allow/prevent seeing all the hovertexts : @showhovertextall=<y/n>
// llOwnerSay("@showhovertext:"+(string)parcelowner+"=y"); // RPG: Allow/prevent seeing one hovertext in particular : @showhovertext:<UUID>=<y/n> -- FIXME allow see region owner/staff
llOwnerSay("@showhovertexthud=y"); // RPG: Allow/prevent seeing the hovertexts on the HUD of the user : @showhovertexthud=<y/n> -- FIXME work around for BAM status?
llOwnerSay("@showhovertextworld=y"); // RPG: Allow/prevent seeing the hovertexts in-world : @showhovertextworld=<y/n>
//llOwnerSay("@setgroup:Myriad RPG=force"); // RPG: Force the agent to change the active group : @setgroup:<group_name>=force
llOwnerSay("@setgroup=y"); // RPG: Allow/prevent activating a group : @setgroup=<y/n>
llOwnerSay("@setenv=y"); // RPG: Allow/prevent changing the environment settings : @setenv=<y/n>
// llOwnerSay("@setenv_preset:<presetname> =force"); // RPG: Force change an environment setting : @setenv_<setting>:<value>=force (*) -- FIXME set world, drug, incapacitated, dead, magic effects
OWNERSAY("Myriad Lite RLV OOC Mode enabled");
//}
}
RLV_OPEN() {
RLV_CLOSE();
RLV_HAND = llListen(RLV_CHAN,"",NULL_KEY,"");
llSetTimerEvent(60.0);
}
//////////////////////////////////////////////////////////////////////////////
// RLV TPTO FORCE TELEPORT EXAMPLE
// Listens on channel 4 for local coordinates and a sim name
// and tells your viewer to teleport you there.
//
// By Marine Kelley 2008-08-26
// RLV version required : 1.12 and above
//
// HOW TO USE :
// * Create a script inside a box
// * Overwrite the contents of the script with this one
// * Wear the box
// * Say the destination coords Region/X/Y/Z on channel 4 :
// Example : /4 Help Island Public/128/128/50
//key kRequestHandle; // UUID of the dataserver request
//vector vLocalPos; // local position extracted from the
//Init () {
// kRequestHandle = NULL_KEY;
// llListen (4, "", llGetOwner (), "");
//}
//default {
// state_entry () {
// Init ();
// }
// on_rez(integer start_param) {
// Init ();
// }
// listen(integer channel, string name, key id, string message) {
// list tokens = llParseString2List (message, ["/"], []);
// integer L = llGetListLength (tokens);
// if (L==4) {
// // Extract local X, Y and Z
// vLocalPos.x = llList2Float (tokens, 1);
// vLocalPos.y = llList2Float (tokens, 2);
// vLocalPos.z = llList2Float (tokens, 3);
// Request info about the sim
// kRequestHandle=llRequestSimulatorData (llList2String (tokens, 0), DATA_SIM_POS);
// }
// }
// dataserver(key queryid, string data) {
// if (queryid == kRequestHandle) {
// Parse the dataserver response (it is a vector cast to a string)
// list tokens = llParseString2List (data, ["<", ",", ">"], []);
// string pos_str = "";
// vector global_pos;
// The coordinates given by the dataserver are the ones of the
// South-West corner of this sim
// => offset with the specified local coordinates
// global_pos.x = llList2Float (tokens, 0);
// global_pos.y = llList2Float (tokens, 1);
// global_pos.z = llList2Float (tokens, 2);
// global_pos += vLocalPos;
// Build the command
// pos_str = (string)((integer)global_pos.x)
// +"/"+(string)((integer)global_pos.y)
// +"/"+(string)((integer)global_pos.z);
// llOwnerSay ("Global position : "+(string)pos_str); // Debug purposes
// Fire !
// llOwnerSay ("@tpto:"+pos_str+"=force");
// }
// }
//}
//////////////////////////////////////////////////////////////////////////////
RLV_VERSION() {
RLV_OPEN();
llOwnerSay("@version="+(string)RLV_CHAN);
}
RLV_VERSIONNEW() {
RLV_OPEN();
llOwnerSay("@versionnew="+(string)RLV_CHAN);
}
RLV_VERSIONNUM() {
RLV_CMD="versionnum";
RLV_OPEN();
llOwnerSay("@versionnum="+(string)RLV_CHAN);
}
// RPEVENT
RPEVENT(string rpevent) {
llMessageLinked(LINK_THIS,MODULE_RLV,"RPEVENT|"+rpevent,llGetOwner());
}
SETUP() {
RLV_VERSIONNEW();
RLV_OOC();
OWNERSAY("RLV module active.");
}
SETUP_WINDLIGHT() {
if ( RLV_AVAIL == TRUE ) {
// check altitude
CURPOS = llGetPos();
GROUND_LEVEL = llFloor(llGround(<0,0,0>));
if ( CURPOS.z >= ( GROUND_LEVEL + SPACE_OFFSET ) ) {
OWNERSAY("RestrainedLight configuring Midnight for Space.");
llOwnerSay("@setenv_preset:midnight=force");
} else {
string setting = GET_RLV("RL_"+llGetRegionName());
if ( setting != "" ) {
llOwnerSay("@setenv_preset:"+setting+"=force");
OWNERSAY("RestrainedLight set to "+setting+" for region "+llGetRegionName());
} else {
llOwnerSay("@setenv_preset:Default=force");
OWNERSAY("RestrainedLight set to Default for region "+llGetRegionName());
}
}
} else {
OWNERSAY("Please enabled RestrainedLove Viewer features to activate RestrainedLight.");
}
}
default {
changed(integer changes) {
if ( ( RLV_AVAIL == TRUE ) && ( ( changes & CHANGED_REGION ) || (changes & CHANGED_TELEPORT ) ) ) {
SETUP_WINDLIGHT();
}
}
link_message(integer sender_num,integer num,string str,key id) {
if ( num == MODULE_RLV || num == LM_SENDTOATTACHMENT ) return; // ignore our own messages
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
// show debug only when not ignoring other commands
DEBUG("EVENT: link_message("+(string)sender_num+","+(string)num+","+str+","+(string)id+")");
PARSE(str,id);
}
listen(integer channel,string name,key id,string message) {
DEBUG("EVENT listen channel=["+(string)channel+"] name=["+name+"] id=["+(string)id+"] message=["+message+"]");
if ( channel != RLV_CHAN ) return; // woken up for message that is not for this module FIXME show error?
if ( RLV_CMD == "versionnum" ) {
if ( (integer)message > 2080000 ) {
RLV_AVAIL = TRUE;
}
RLV_CLOSE();
return;
}
}
state_entry() {
SETUP();
}
timer() {
RLV_CLOSE();
}
}