This commit is contained in:
Fred Beckhusen
2023-05-13 20:30:41 -05:00
79 changed files with 19288 additions and 7 deletions

View File

@@ -0,0 +1,27 @@
vector LANDING = <128,128,32>; // Edit this for where they land
key avatarkey;
default
{
state_entry()
{
llVolumeDetect(FALSE);
llVolumeDetect(TRUE);
}
collision_start(integer n)
{
llOwnerSay("Avatar Arriving:" + llDetectedName(0));
avatarkey = llDetectedKey(0);
osForceOtherSit(avatarkey, llGetKey());
}
changed(integer what) {
if (what & CHANGED_LINK) {
llSetRegionPos(llGetObjectDesc());
llUnSit(avatarkey);
llSetRegionPos(LANDING);
llResetScript();
}
}
}

View File

@@ -0,0 +1,71 @@
integer debug = TRUE; // set this top FALSE to shut the chat up.
integer idx = 0; // a counter to fiund the thing we need.
string prioranimation = ""; // where we keep thje last anim,ation so we can stop it.
// example list of animations to play
// 1,2,3 seconds in this case
// plays "soundfIle on the 1st and last animation.
list animations = ["idle_1", "soundFile1", 1.0,
"idle_2", "", 2.0,
"idle_3","soundFile3", 3.0
];
// The above list is the names or UUIDS of animations in the prim, optionally a sound file name or UUID, and the time to play them.
// List is a 3-stride list so to play no animation, and a sound for 10 seconds, use
// "","soundfile name", 10,
// for just an animation for 2 seconds, use this:
// "animationame","", 2.0
// for an animation for 20 secondsw with a wav file, use this:
// "animationame", "soundfilename", 20
// And there is no comma at the end of the list!!
default {
state_entry() { // all we do in this ewvent is start a timer. Never rest inside this event! It's an endless loop!
if (debug) llSay(0,"reset");
llSetTimerEvent(1);
}
on_rez(integer p){ // in case you rez the prim
llResetScript();
}
changed(integer what) {
if (what & CHANGED_REGION_START) { // in case the OAR was loaded
llResetScript();
}
if (what & CHANGED_INVENTORY) { // reset if you change any items in the prim inventory
llResetScript();
}
}
timer() {
// check for end of list, if so start over
if (idx >= llGetListLength(animations)) {
idx = 0;
}
// Start an animation after sttopping the prior
string animation = llList2String(animations,idx);
if (debug) {
llSay(0,"Playing " + animation);
}
llStopObjectAnimation(prioranimation);
llStartObjectAnimation(animation);
prioranimation = animation;
// Set Sound
string sound = llList2String(animations,idx+1);
if (debug) {
llSay(0,"Sound " + sound);
}
if (llStringLength(sound)> 0 ) {
llPlaySound(sound, 1.0);
}
// Set timer
float t = (float) llList2String(animations,idx+2);
llSetTimerEvent(t);
if (debug) llSay(0,"Timer Set to " + (string) t );
idx+= 3;
}
}

View File

@@ -0,0 +1,413 @@
// Default Program FrameWork
/*
Replace this Section with Program Specific Information
*/
// Created by Tech Guy of IO
// Configuration Directives
/* This Section Contains Configuration Variables that will contain data set by reading the notecard specified by ConfigFile Variable */
// Communication Channels
integer MenuComChannel; // Menu Communications Channel for All User Dialog Communications
integer ComChannel; // General Communication Channel for Inter-Device Communication
// System Variables
/* This Section contains variables that will be used throughout the program. */
// Admin ACL
list Admins; // List of Administrator Keys Read in from ConfigFile
// Dance Animation Names
list Dances;
// Num Dances Per Category
list NumDances;
// Num of Categories
integer NumCats;
// List of Category Names (Index Associated with {NumCats}
list CatNames;
// Couples Dances
list CDances;
// Dancers Keys
list Dancers;
// Maximum Dancers Supported
integer MaxDancers = 20;
// Number of Active Dancers (Not to Exceed Max Dancers)
integer NumDancers;
// Default Dance for someone who requests start
string DefaultDance;
// Communication Handles
integer MenuComHandle; // Menu Communications Handle
integer ComHandle; // General Communications Handle
// Config Card Reading Variables
integer cLine; // Holds Configuration Line Index for Loading Config Loop
key cQueryID; // Holds Current Configuration File Line during Loading Loop
integer DCounter;
string DanceCat;
// System Constants
/* This Section contains constants used throughout the program */
string BootMessage = "Booting..."; // Default/Initial Boot Message
string ConfigFile = ".config"; // Name of Configuration File
string EMPTY = "";
// Menu Constants
string MainMenuMessage = "Wholearth Dance Machine v1.0";
list MainMenuButtons = [ "<<", "Stop", ">>", "Dances", "Start", "Invite", "Sync", "Random" ];
list NavButtons = [ "Prev Menu", "Exit Menu" ];
list AdminButton = [ "Admin" ];
list AdminMenuButtons = [ "Dance", "Random", "Reset", "Sync" ];
string AdminMenuMessage = "Admin Menu\n\tDance -> Sets Default Dance for start request\n\tRandom -> Should dances auto cycle.\n\tReset -> Reset Scripts\n\tSync -> Sync's Current Default Dance";
string DefaultDancesMenuMessage = "Change the Default Dance...";
// Color Vectors
list colorsVectors = [<0.000, 0.455, 0.851>, <0.498, 0.859, 1.000>, <0.224, 0.800, 0.800>, <0.239, 0.600, 0.439>, <0.180, 0.800, 0.251>, <0.004, 1.000, 0.439>, <1.000, 0.522, 0.106>, <1.000, 0.255, 0.212>, <0.522, 0.078, 0.294>, <0.941, 0.071, 0.745>, <0.694, 0.051, 0.788>, <1.000, 1.000, 1.000>];
// List of Names for Colors
list colors = ["BLUE", "AQUA", "TEAL", "OLIVE", "GREEN", "LIME", "ORANGE", "RED", "MAROON", "FUCHSIA", "PURPLE", "WHITE"];
// System Switches
/* This Section contains variables representing switches (integer(binary) yes/no) or modes (string "modename" */
// Debug Mode Swtich
integer DebugMode = FALSE; // Is Debug Mode Enabled before Reading Obtaining Configuation Information
string AdminOpFlag;
// Imported Functions
/* This section contains any functions that were not written by Tech Guy */
// Home-Brew Functions
/* This section contains any functions that were written by Tech Guy */
// Debug Message Function
DebugMessage(string msg){
if(DebugMode){
llOwnerSay(msg);
}
}
// Send Any User a Message
SendMessage(string msg, key userid){
if(userid=="NULL_KEY" || userid==""){
//llSay(0, msg);
llRegionSay(0, msg);
}else if(msg!="" && userid!=NULL_KEY){
//llInstantMessage(userid, msg);
llRegionSayTo(userid, 0, msg);
}else{
DebugMessage("Error Sending User Message: "+msg);
}
}
// Main Initialization Logic, Executed Once Upon Script Start
Initialize(){
SendMessage(BootMessage, llGetOwner()); // State Booting Message
MenuComChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0); // Randomize Dialog Com Channel
MenuComHandle = llListen(MenuComChannel, EMPTY, EMPTY, EMPTY);
SendMessage("Configuring...", llGetOwner()); // Message Owner that we are starting the Configure Loop
cQueryID = llGetNotecardLine(ConfigFile, cLine); // Start the Read from Config Notecard
}
// System has started Function (Runs After Configuration is Loaded, as a result of EOF)
SystemStart(){
// Clean Up Config Variables
NumDances = NumDances + [DCounter];
//llOwnerSay((string)llGetListLength(Dances)+llDumpList2String(Dances, "||"));
//llOwnerSay((string)llGetListLength(CatNames)+llDumpList2String(CatNames, "||"));
//llOwnerSay((string)llGetListLength(NumDances)+llDumpList2String(NumDances, "||"));
DCounter = 0;
DanceCat = EMPTY;
SendMessage("System Started!", llGetOwner());
}
// Add Admin (Add provided Legacy Name to Admins List after extrapolating userKey)
AddAdmin(string LegacyName){
string FName = llList2String(llParseString2List(LegacyName, [" "], []), 0);
string LName = llList2String(llParseString2List(LegacyName, [" "], []), 1);
DebugMessage("First Name: "+FName+" Last Name: "+LName);
key UserKey = osAvatarName2Key(FName, LName);
if(UserKey!=NULL_KEY){
Admins = Admins + UserKey;
DebugMessage("Added Admin: "+LegacyName);
}else{
DebugMessage("Unable to Resolve: "+LegacyName);
}
}
// Configuration Directives Processor (Called Each Time a Line is Found in the config File)
LoadConfig(string data){
if(data!=""){ // If Line is not Empty
// if the line does not begin with a comment
if(llSubStringIndex(data, "#") != 0)
{
// find first equal sign
integer i = llSubStringIndex(data, "=");
// if line contains equal sign
if(i != -1){
// get name of name/value pair
string name = llGetSubString(data, 0, i - 1);
// get value of name/value pair
string value = llGetSubString(data, i + 1, -1);
// trim name
list temp = llParseString2List(name, [" "], []);
name = llDumpList2String(temp, " ");
// make name lowercase
name = llToLower(name);
// trim value
temp = llParseString2List(value, [" "], []);
value = llDumpList2String(temp, " ");
// Check Key/Value Pairs and Set Switches and Lists
if(name=="debugmode"){ // Check DeBug Mode
if(value=="TRUE" || value=="true"){
DebugMode = TRUE;
llOwnerSay("Debug Mode: Enabled!");
}else if(value=="FALSE" || value=="false"){
DebugMode = FALSE;
llOwnerSay("Debug Mode: Disabled!");
}
}else if(name=="menu"){
DanceCat = value;
CatNames = CatNames + [value];
NumCats++;
Dances = Dances + [value];
DebugMessage("Dance Category Found: "+llList2String(Dances, -1)+"\nTotal Categories: "+(string)NumCats);
if(DCounter>0){
NumDances = NumDances + [DCounter];
}
DCounter = 0;
}else if(name=="dance"){
Dances = Dances + [value];
DebugMessage("Dance "+value+" found! Placing into Category "+DanceCat);
DCounter++;
if(NumCats==1 && DCounter==1){
DefaultDance = value;
DebugMessage("Default Dance Set to: "+DefaultDance);
}
DebugMessage((string)DCounter+" Total Dances for "+DanceCat+".");
}else if(name=="admin"){
AddAdmin(value);
}
}else{ // line does not contain equal sign
SendMessage("Configuration could not be read on line " + (string)cLine, NULL_KEY);
}
}
}
}
// Check Security
integer CheckSecurity(key id){
if(llListFindList(Admins, [id])!=-1){
return TRUE;
}else{
return FALSE;
}
}
// Test of Requesting Users Key is found in Dancers List, Returns True or False
integer IsDancing(key id){
if(llListFindList(Dancers, [id])!=-1){
return TRUE;
}else{
return FALSE;
}
}
// Manipulate Dancer (Start, Stop, Next/Prev Dance,
Dancer(string CMD, key id, string Dance){
if(CMD=="Start"){
if(!IsDancing(id)){ // If the User is not in the dance list and is request to start.
Dancers = Dancers + [id];
DebugMessage("Added: "+llKey2Name(id)+" to the Dancers List!");
Relay("Assign", id, Dance); // Assign Requesting User the next available relay
}else{
DebugMessage("Requesting Relay Re-Init...");
Relay("Reload", id, Dance);
}
}else if(CMD=="Stop"){
if(IsDancing(id)){
Dancers = llDeleteSubList(Dancers, llListFindList(Dancers, [id]), llListFindList(Dancers, [id]));
if(llListFindList(Dancers, [id])==-1){
DebugMessage("Dancer Removed from List!");
}else{
DebugMessage("Failed to Remove Dancer from List!");
}
Relay("Stop", id, DefaultDance);
}
}else if(CMD==">>"){
if(IsDancing(id)){
DebugMessage("Advancing Dance for User: "+llKey2Name(id)+".");
Relay(CMD, id, Dance);
}
}else if(CMD=="<<"){
if(IsDancing(id)){
DebugMessage("Retrogressing Dance for User: "+llKey2Name(id)+".");
Relay(CMD, id, Dance);
}
}else if(CMD=="Sync"){
}else if(CMD=="Change"){ // Change to Selected Dance
if(IsDancing(id)){
DebugMessage("Changing Dance for User: "+llKey2Name(id)+" to dance: "+Dance);
Relay("Change", id, Dance);
}
}
}
// Relay Control
Relay(string CMD, key id, string Dance){
string RelayName = "Relay ";
if(CMD=="Assign"){
integer i;
for(i=1;i<=MaxDancers;i++){
integer ISON = llGetScriptState(RelayName+(string)i);
if(!ISON){ // Script is Already in Use
RelayName = RelayName + (string)i;
DebugMessage("Script Relay: "+RelayName);
llSetScriptState(RelayName, TRUE);
llResetOtherScript(RelayName);
DebugMessage("Sending Start Message to Relay: "+RelayName);
llMessageLinked(LINK_THIS, 0, "START||"+DefaultDance, id);
return;
}
}
}else if(CMD=="Reload"){
}else if(CMD=="Stop"){
DebugMessage("Sending Stop Message to Relay...");
llMessageLinked(LINK_THIS, 0, "STOP||", id);
}else if(CMD=="Change"){
DebugMessage("Sending Change Message to Relay...");
llMessageLinked(LINK_THIS, 0, "CHANGE||"+Dance, id);
}else if(CMD==">>" || CMD=="<<"){
DebugMessage("Sending Slot Adjustment Command...");
llMessageLinked(LINK_THIS, 0, CMD+"||"+Dance, id);
}
}
// Show Menu
ShowMenu(string Menu, key id){
string CurMenuMessage;
list CurMenuButtons;
if(Menu=="MainMenu"){
CurMenuMessage = MainMenuMessage;
CurMenuButtons = MainMenuButtons;
if(CheckSecurity(id)){
CurMenuButtons =CurMenuButtons + AdminButton;
}
}else if(Menu=="Dances"){
list Categories;
integer i;
integer CatIndex;
for(i=0;i<NumCats;i++){
Categories = Categories + [llList2String(Dances, CatIndex)];
CatIndex = (CatIndex + (llList2Integer(NumDances, i)+1));
}
if(AdminOpFlag=="ChangeDefaultDance"){
CurMenuMessage = DefaultDancesMenuMessage;
}else{
CurMenuMessage = MainMenuMessage;
}
CurMenuButtons = Categories;
}else if(Menu=="Admin"){
CurMenuMessage = AdminMenuMessage;
CurMenuButtons = AdminMenuButtons;
}else if(llListFindList(Dances, [Menu])!=-1){
integer CIndex = llListFindList(CatNames, [Menu]);
llOwnerSay("CIndex: "+(string)CIndex+" Num of Dances: "+llList2String(NumDances, CIndex));
integer i;
integer StartPoint = (llListFindList(Dances, [Menu])+1);
llOwnerSay("Start Point: "+(string)StartPoint);
for(i=0;i<llList2Integer(NumDances, CIndex);i++){
CurMenuButtons = CurMenuButtons + llList2String(Dances, StartPoint);
llOwnerSay(llList2String(CurMenuButtons, -1));
StartPoint++;
}
CurMenuMessage = DefaultDancesMenuMessage;
}
// Send Constructed Dialog to User
llDialog(id, CurMenuMessage, CurMenuButtons, MenuComChannel);
}
//Main Program Logic
/* This section contains the main program logic. (ie: Default State, and all event triggers) */
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
// DataServer Event Called for Each Line of Config NC. This Loop It was Calls LoadConfig()
dataserver(key query_id, string data){ // Config Notecard Read Function Needs to be Finished
if (query_id == cQueryID){
if (data != EOF){
LoadConfig(data); // Process Current Line
++cLine; // Increment Line Index
cQueryID = llGetNotecardLine(ConfigFile, cLine); // Attempt to Read Next Config Line (Re-Calls DataServer Event)
}else{ // IF EOF (End of Config loop, and on Blank File)
SystemStart();
}
}
}
listen(integer chan, string sender, key id, string msg){
DebugMessage("Listen Event Fired: "+msg);
if(msg=="Dances"){
ShowMenu("Dances", id);
}else if(msg=="Admin"){
if(CheckSecurity(id)){ // Verify their Id against Admins List again to avoid message spoofing from unauthed users
ShowMenu(msg, id); // Show Admin Menu
}else{
llRegionSayTo(id, 0, "Your not Smart Enough!");
}
}else if(msg=="Dance"){
AdminOpFlag = "ChangeDefaultDance";
if(CheckSecurity(id)){ // Verify their Id against Admins List again to avoid message spoofing from unauthed users
ShowMenu("Dances", id); // Show Admin Menu
}else{
llRegionSayTo(id, 0, "Your not Smart Enough!");
}
}else if(llListFindList(Dances, [msg])!=-1){ // If the Message is either a Dance or a Category
if(llGetInventoryKey(msg)==NULL_KEY){ // It was not a Dance, Must be a Category
ShowMenu(msg, id); // Show Menu comprised of Dances in Category specified by {msg}
}else{ // It was a Dance.
if(AdminOpFlag=="ChangeDefaultDance"){
DefaultDance = msg;
SendMessage("Default Dance is now: "+msg, id);
}else{
Dancer("Change", id, msg); // Change slected dance for calling user
}
}
}else if(msg=="Start" || msg=="Stop" || msg==">>" || msg=="<<" || msg=="Sync"){
DebugMessage(msg+" Message Received!");
Dancer(msg, id, DefaultDance);
}
}
touch_start(integer num){
if(num>1){
return;
}
key UserKey = llDetectedKey(0);
if(NumDancers<MaxDancers){
ShowMenu("MainMenu", UserKey);
}
}
changed(integer change){
if(change & CHANGED_INVENTORY){
BootMessage = "Inventory Changed Detected, Re-Initializing...";
llResetScript();
}
}
}

112
Dance Engine/Relay 1.lsl Normal file
View File

@@ -0,0 +1,112 @@
key ActiveDancer = NULL_KEY;
string ActiveDance;
string PrevDance;
integer Random = FALSE; // Do we Dance Cycle?
string TimerMode;
string EMPTY = "";
list Dances;
Dancer(string CMD){
if(CMD=="Start"){
osAvatarStopAnimation(ActiveDancer, "stand");
osAvatarPlayAnimation(ActiveDancer, ActiveDance);
}else if(CMD=="Stop"){
osAvatarStopAnimation(ActiveDancer, ActiveDance);
osAvatarPlayAnimation(ActiveDancer, "stand");
ActiveDancer = NULL_KEY;
llSetScriptState(llGetScriptName(), FALSE);
}else if(CMD=="Change"){
osAvatarStopAnimation(ActiveDancer, PrevDance);
osAvatarPlayAnimation(ActiveDancer, ActiveDance);
}
}
integer GetDances(){
integer i;
for(i=0;i<llGetInventoryNumber(INVENTORY_ANIMATION);i++){
Dances = Dances + [llGetInventoryName(INVENTORY_ANIMATION, i)];
}
integer DanceListLength = llGetListLength(Dances);
return DanceListLength;
}
default{
state_entry(){
llResetScript();
GetDances();
}
link_message(integer sendinglink, integer I, string msg, key id){
list InputData = llParseString2List(msg, ["||"], []);
string CMD = llList2String(InputData, 0);
key UserKey = id;
string PARAM = llList2String(InputData, 1);
if(ActiveDancer==NULL_KEY){
if(CMD=="START"){
ActiveDance = PARAM;
ActiveDancer = UserKey;
llRegionSayTo(id, 0, "Please Accept Animate Permissions...");
llRequestPermissions(UserKey, PERMISSION_TRIGGER_ANIMATION);
TimerMode = "Perms";
llSetTimerEvent(30);
}
}else if(ActiveDancer==UserKey){
if(CMD=="STOP"){
Random = FALSE;
llSetTimerEvent(0);
Dancer("Stop");
}else if(CMD=="CHANGE"){
Random = FALSE;
llSetTimerEvent(0);
PrevDance = ActiveDance;
ActiveDance = PARAM;
Dancer("Change");
}else if(CMD=="<<"){
if(llGetListLength(Dances)==0){
if(GetDances()>=2){
integer DanceIndex = llListFindList(Dances, [ActiveDance]);
PrevDance = ActiveDance;
if(DanceIndex==0){
ActiveDance = llList2String(Dances, -1);
}else{
ActiveDance = llList2String(Dances, (DanceIndex - 1));
}
Dancer("Change");
}
}
}else if(CMD==">>"){
if(llGetListLength(Dances)==0){
if(GetDances()>=2){
integer DanceIndex = llListFindList(Dances, [ActiveDance]);
PrevDance = ActiveDance;
if(DanceIndex==(llGetListLength(Dances) - 1)){
ActiveDance = llList2String(Dances, 0);
}else{
ActiveDance = llList2String(Dances, (DanceIndex + 1));
}
Dancer("Change");
}
}
}
}
}
run_time_permissions(integer perms){
if(perms & PERMISSION_TRIGGER_ANIMATION){
llSetTimerEvent(0);
TimerMode = EMPTY;
Dancer("Start");
}else{
llRequestPermissions(ActiveDancer, PERMISSION_TRIGGER_ANIMATION);
}
}
timer(){
if(TimerMode=="Perms"){
llMessageLinked(LINK_THIS, 0, "FAIL||"+llGetScriptName(), ActiveDancer);
llSleep(0.1);
llSetScriptState(llGetScriptName(), FALSE);
}
}
}

View File

@@ -0,0 +1,178 @@
// Rideable Elevator Engine v1.0
// Created by Tech Guy (Island Oasis) 2014
// CONFIGURATION AREA
list floorlist = [1, 23.71295, 30.63740, 38.13171, 45.60405, 53.14041, 60.63789, 68.13129, 75.63333, 83.11023, 90.61882, 98.16618, 105.64812, 113.15546, 120.65170, 128.13916, 135.65147 ]; // List of Floor Z-Vectors associated with floors
list seats = [25,26,27,28,29,30]; // Seat Link Numbers
key MainComputer = "a50c545c-2472-4e8c-a82d-6fbb7598c418";
integer currentfloor = 1; // Stores Current Floor Number (Starts with it being on Floor 1)
integer dest_floor; // Holds Destination Floor
vector currentPos; // Stored Current Position of Car
vector destPos; // Stores Destination Vector
integer MainListener; // Main Listener Handle
float sitTimer = 1.0; // Timer Event Loop Freqency
integer sitCounter; // Sit Counter Down Integer->String
string runstate = "ready"; // Stores Running State of Elevator (ready vs preparing vs moving)
float SpeedT = 5.0; // Travel Speed (Multipled by Travel Distance to get Key Framed Animation Time)
float travelTime; // Will Contain Travel Time for Requested Floor Call
string direction; // Hold Direction Indicator String
vector nextfloor; // Hold Vector of Next Floor
float DiM; // Travel Distance in Meters
integer JR = TRUE; // J
SetSitTargets(){ // Sets Set Targets on
integer ListLength = llGetListLength(seats);
integer i;
while (i < ListLength){
llLinkSitTarget(llList2Integer(seats,i),<0.0,0.0,1.0>, ZERO_ROTATION);
++i;
}
}
OpenDoors(){
llWhisper(420, currentfloor+"O");
llMessageLinked(LINK_SET, 0, "OFF", NULL_KEY);
llWhisper(420, "OFF");
}
default
{
state_entry()
{
llListenRemove(MainListener);
llSetMemoryLimit(0x4000);
SetSitTargets();
llOwnerSay("Ready...");
MainListener = llListen(604, "", "", "" );
}
on_rez(integer num)
{
llResetScript();
}
listen(integer number, string name, key id, string message)
{
if(message!=""){
if((integer)message<currentfloor){ // If Destination Floor is Lower than Current Floor
llOwnerSay("Going to Floor"+message);
dest_floor = (integer)message;
integer travel_distance = currentfloor - (integer)message; // Number of Floors to Travel
travelTime = travel_distance * SpeedT; // TravelTime
DiM = llList2Float(floorlist, currentfloor) - llList2Float(floorlist, (integer)message); // Determine Distance in Meters
DiM = DiM * -1;
destPos = llGetPos();
destPos.z = llList2Float(floorlist, dest_floor);
nextfloor = llGetPos();
nextfloor.z = llList2Float(floorlist, currentfloor-1);
llOwnerSay("Next Floor: "+(string)nextfloor.z);
state movedown;
}else if((integer)message>currentfloor){ // If Destination Floor is Higher than Current Floor
llOwnerSay("Going to Floor"+message);
dest_floor = (integer)message;
integer travel_distance = (integer)message - currentfloor; // Number of Floors to Travel
travelTime = travel_distance * SpeedT; // TravelTime
DiM = llList2Float(floorlist, (integer)message) - llList2Float(floorlist, currentfloor); // Travel Distance in Meters
destPos = llGetPos();
destPos.z = llList2Float(floorlist, dest_floor);
nextfloor = llGetPos();
nextfloor.z = llList2Float(floorlist, currentfloor+1);
llOwnerSay("Next Floor: "+(string)nextfloor.z);
state moveup;
}else{
OpenDoors();
}
}
}
}
state moveup{
state_entry(){
llListenRemove(MainListener);
llSetStatus(STATUS_ROTATE_X| STATUS_ROTATE_Y| STATUS_ROTATE_Z, FALSE); // Restrict Rotation
sitCounter = 3;
integer numSeconds = (integer)sitTimer * sitCounter;
llSay(0,"You have "+(string)numSeconds+" seconds to sit down or be left behind. Thank You.\n Going to Floor");
runstate = "preparing";
llSetTimerEvent(sitTimer);
}
timer(){
if(runstate=="preparing"){
if(sitCounter!=0){
llSay(0,sitCounter+" second remaining...");
sitCounter = sitCounter - 1;
}
if(sitCounter==0){
llSay(0,"Going to Floor "+(string)destPos.z);
llSetKeyframedMotion(
[<0.0,0.0,DiM>, travelTime],
[KFM_DATA, KFM_TRANSLATION, KFM_MODE, KFM_FORWARD]);
runstate = "moving";
llSetTimerEvent(0.25);
}
}
if(runstate=="moving"){
currentPos = llGetPos();
if(llRound(currentPos.z)==llRound(destPos.z)){
currentfloor = dest_floor;
OpenDoors();
state default;
}
if(llRound(currentPos.z)==llRound(nextfloor.z)){
currentfloor = currentfloor + 1;
nextfloor.z = llList2Float(floorlist, currentfloor+1);
llRegionSayTo(MainComputer, 421, (string)currentfloor);
}
}
}
}
state movedown{
state_entry(){
llListenRemove(MainListener);
llSetStatus(STATUS_ROTATE_X| STATUS_ROTATE_Y| STATUS_ROTATE_Z, FALSE); // Restrict Rotation
sitCounter = 3;
integer numSeconds = (integer)sitTimer * sitCounter;
llSay(0,"You have "+(string)numSeconds+" seconds to sit down or be left behind. Thank You.\n Going to Floor");
runstate = "preparing";
llSetTimerEvent(sitTimer);
}
timer(){
if(runstate=="preparing"){
if(sitCounter!=0){
llSay(0,sitCounter+" second remaining...");
sitCounter = sitCounter - 1;
}
if(sitCounter==0){
llSay(0,"Going to Floor "+(string)destPos.z);
llSetKeyframedMotion(
[<0.0,0.0,DiM>, travelTime],
[KFM_DATA, KFM_TRANSLATION, KFM_MODE, KFM_FORWARD]);
runstate = "moving";
llSetTimerEvent(1.0);
}
}
if(runstate=="moving"){
currentPos = llGetPos();
if(llRound(currentPos.z)==llRound(destPos.z)){
llSay(420, (currentfloor-1)+"O");
llMessageLinked(LINK_SET, 0, "OFF", NULL_KEY);
llSay(420, "OFF");
currentfloor = dest_floor;
state default;
}
if(llRound(currentPos.z)==llRound(nextfloor.z)){
currentfloor = currentfloor - 1;
nextfloor.z = llList2Float(floorlist, currentfloor-1);
llRegionSayTo(MainComputer, 421, (string)currentfloor);
}
}
}
}

View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,271 @@
//Hot Tube Engine V1.0
// Created by Tech Guy of IO
// Configuration
// Menus
list MainMenu = ["Lights", "Steam On", "Steam Off", "Jets On", "Jets Off", "Exit"]; // Main Menu Options
list LightsMenu = ["On/Off", "Color", "Main Menu", "Exit"];
string MenuFlag = "";
// Variables
integer ListenChannel; // Listen Channel Variable Initializer
integer ListenHandle; // Listen Handle
// Constants
string EMPTY = "";
vector FullSizeWater = <2.11000, 3.06800, 1.2>;
vector NoWater = <2.11000, 3.06800, 0.00073>;
float NumWaterLevels = 30;
list JetLink = [2, 4, 5, 6, 7, 8, 10];
key JetTarget = NULL_KEY;
// Color Vectors
list colorsVectors = [<0.000, 0.455, 0.851>, <0.498, 0.859, 1.000>, <0.224, 0.800, 0.800>, <0.239, 0.600, 0.439>, <0.180, 0.800, 0.251>, <0.004, 1.000, 0.439>, <1.000, 0.522, 0.106>, <1.000, 0.255, 0.212>, <0.522, 0.078, 0.294>, <0.941, 0.071, 0.745>, <0.694, 0.051, 0.788>, <1.000, 1.000, 1.000>];
// List of Names for Colors
list colors = ["BLUE", "AQUA", "TEAL", "OLIVE", "GREEN", "LIME", "ORANGE", "RED", "MAROON", "FUCHSIA", "PURPLE", "WHITE"];
//Initial Light Configuration Values + Some Holders for Temp Values
float Intensity = 1.0;
float Radius = 10.0;
float FallOff = 0.750;
vector DefaultColor = <0.502, 1.0, 1.0>;
float Glow = 0.06;
float Alpha = 0.7;
// PlaceHolders for Current Values of Same
float CurIntensity;
float CurRadius;
float CurFallOff;
vector CurColor;
float CurGlow;
// Switches
integer LightState = FALSE; // Initial State of Tub Lights
integer SteamState = FALSE; // Initial Steam State
integer JetState = FALSE; // Initial Jet State
// Functions
DoMenu(string MFLAG, key userid){
if(MFLAG==""){
llSetTimerEvent(30.0);
ListenHandle = llListen(ListenChannel, EMPTY, EMPTY, EMPTY);
llDialog(userid, "Please select option...", MainMenu, ListenChannel);
}else if(MFLAG=="Lights"){
llSetTimerEvent(30.0);
ListenHandle = llListen(ListenChannel, EMPTY, EMPTY, EMPTY);
llDialog(userid, "Please select option...", LightsMenu, ListenChannel);
}else if(MFLAG=="Color"){
llSetTimerEvent(30.0);
ListenHandle = llListen(ListenChannel, EMPTY, EMPTY, EMPTY);
llDialog(userid, "Please select lighting color...", colors, ListenChannel);
}
}
Steam(integer ISON){
if(ISON){
llLinkParticleSystem(LINK_ROOT, [
PSYS_PART_FLAGS,( 0
|PSYS_PART_INTERP_COLOR_MASK
|PSYS_PART_INTERP_SCALE_MASK ),
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE ,
PSYS_PART_START_ALPHA,0.501961,
PSYS_PART_END_ALPHA,0.0117647,
PSYS_PART_START_COLOR,CurColor,
PSYS_PART_END_COLOR,<1,1,1> ,
PSYS_PART_START_SCALE,<3,3,0>,
PSYS_PART_END_SCALE,<0.1875,0.1875,0>,
PSYS_PART_MAX_AGE,2.14844,
PSYS_SRC_MAX_AGE,0,
PSYS_SRC_ACCEL,<0,0,-0.203125>,
PSYS_SRC_BURST_PART_COUNT,2,
PSYS_SRC_BURST_RADIUS,0.199219,
PSYS_SRC_BURST_RATE,0.046875,
PSYS_SRC_BURST_SPEED_MIN,0.796875,
PSYS_SRC_BURST_SPEED_MAX,1,
PSYS_SRC_ANGLE_BEGIN,0,
PSYS_SRC_ANGLE_END,1.46875,
PSYS_SRC_OMEGA,<0,0,0>,
PSYS_SRC_TEXTURE, (key)"26321045-e218-49c8-9387-e7801c890e27",
PSYS_SRC_TARGET_KEY, (key)"00000000-0000-0000-0000-000000000000"
]);
}else{
llLinkParticleSystem(LINK_ROOT, []);
}
}
Jets(integer ISON){
integer i;
if(ISON){
for(i=0;i<=5;i++){
llLinkParticleSystem(llList2Integer(JetLink, i), [
PSYS_PART_FLAGS,( 0
|PSYS_PART_INTERP_COLOR_MASK
|PSYS_PART_INTERP_SCALE_MASK
|PSYS_PART_FOLLOW_SRC_MASK
|PSYS_PART_FOLLOW_VELOCITY_MASK
|PSYS_PART_TARGET_POS_MASK ),
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE ,
PSYS_PART_START_ALPHA,1,
PSYS_PART_END_ALPHA,0,
PSYS_PART_START_COLOR,CurColor ,
PSYS_PART_END_COLOR,<1,1,1> ,
PSYS_PART_START_SCALE,<0,0,0>,
PSYS_PART_END_SCALE,<0.28125,0.28125,0>,
PSYS_PART_MAX_AGE,3,
PSYS_SRC_MAX_AGE,0,
PSYS_SRC_ACCEL,<0,0,0.046875>,
PSYS_SRC_BURST_PART_COUNT,8,
PSYS_SRC_BURST_RADIUS,0,
PSYS_SRC_BURST_RATE,0.0585938,
PSYS_SRC_BURST_SPEED_MIN,0.5,
PSYS_SRC_BURST_SPEED_MAX,1,
PSYS_SRC_ANGLE_BEGIN,2.09375,
PSYS_SRC_ANGLE_END,0.4375,
PSYS_SRC_OMEGA,<8,1.59375,1>,
PSYS_SRC_TEXTURE, (key)"1c79c1db-7cc0-421f-a363-499725617068",
PSYS_SRC_TARGET_KEY, llList2Key(JetTarget, 0)
]);
}
}else{
for(i=0;i<=2;i++){
llLinkParticleSystem(llList2Integer(JetLink, i), []);
}
for(i=3;i<=5;i++){
llLinkParticleSystem(llList2Integer(JetLink, i), []);
}
}
}
ToggleLights(){
if(LightState){
llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
PRIM_POINT_LIGHT, FALSE, CurColor, CurIntensity, CurRadius, CurFallOff,
PRIM_COLOR, ALL_SIDES, DefaultColor, Alpha
]);
if(SteamState){
vector TempColor = CurColor;
CurColor = <1.0,1.0,1.0>;
Steam(FALSE);
Steam(TRUE);
CurColor = TempColor;
}
if(JetState){
vector TempColor = CurColor;
CurColor = <1.0,1.0,1.0>;
Jets(FALSE);
Jets(TRUE);
CurColor = TempColor;
}
}else{
llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_POINT_LIGHT, TRUE, CurColor, CurIntensity, CurRadius, CurFallOff,
PRIM_COLOR, ALL_SIDES, CurColor, Alpha
]);
if(SteamState){
Steam(FALSE);
Steam(TRUE);
}
if(JetState){
Jets(FALSE);
Jets(TRUE);
}
}
LightState = !LightState;
}
default{
state_entry(){
llListenRemove(ListenHandle);
ListenChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
// Set Light Config Defaults to Current Values Variables
CurIntensity = Intensity;;
CurRadius = Radius;
CurFallOff = FallOff;
CurColor = DefaultColor;
CurGlow = Glow;
JetTarget = llGetLinkKey(LINK_ROOT);
}
touch(integer num){
key id = llDetectedKey(0);
integer WhatTouched = llDetectedLinkNumber(0);
if(WhatTouched!=16){
return;
}else{
//llOwnerSay("Link Number: "+(string)WhatTouched);
//return;
DoMenu(EMPTY, id);
}
}
listen(integer channel, string num, key id, string msg){
llSetTimerEvent(0.0); // Clear Timer when listen event triggers, We will start timer again if we open another menu with DoMenu();
if(msg=="Lights"){ // Open Lights Sub-Menu
MenuFlag = "Lights";
DoMenu(MenuFlag, id);
}else if(msg=="Steam On"){
SteamState = TRUE;
if(!LightState){
vector TempColor = CurColor;
CurColor = <1.0,1.0,1.0>;
Steam(FALSE);
Steam(TRUE);
CurColor = TempColor;
}else{
Steam(TRUE);
}
}else if(msg=="Steam Off"){
SteamState = FALSE;
Steam(FALSE);
}else if(msg=="Jets On"){
JetState = TRUE;
if(!LightState){
vector TempColor = CurColor;
CurColor = <1.0,1.0,1.0>;
Jets(FALSE);
Jets(TRUE);
CurColor = TempColor;
}else{
Jets(TRUE);
}
}else if(msg=="Jets Off"){
JetState = FALSE;
Jets(FALSE);
}else if(msg=="On/Off"){
ToggleLights();
}else if(msg=="Color"){
MenuFlag = msg;
DoMenu(MenuFlag, id);
}else if(msg=="Main Menu"){
MenuFlag = "";
DoMenu(EMPTY, id);
}else if(llListFindList(colors, [msg])!=-1){
integer ColorIndex = llListFindList(colors, [msg]);
CurColor = llList2Vector(colorsVectors, ColorIndex);
if(LightState){
ToggleLights();
ToggleLights();
}
if(SteamState){
Steam(FALSE);
Steam(TRUE);
}
if(JetState){
Jets(FALSE);
Jets(TRUE);
}
}else{
llSetTimerEvent(0);
llListenRemove(ListenHandle);
}
}
timer(){
llSetTimerEvent(0);
llListenRemove(ListenHandle);
}
}

View File

@@ -0,0 +1,204 @@
// Jacuzzi Engine v1.0 by Tech Guy
// Configuration
// Menus
list MainMenu = ["Fill", "Empty", "Steam On", "Steam Off", "Jets On", "Jets Off", "Exit"]; // Main Menu Options
// Variables
integer ListenChannel; // Listen Channel Variable Initializer
integer ListenHandle; // Listen Handle
// Constants
string EMPTY = "";
vector FullSizeWater = <2.11000, 3.06800, 1.2>;
vector NoWater = <2.11000, 3.06800, 0.00073>;
float NumWaterLevels = 30;
list JetLink = [14, 15, 16, 11, 12, 13];
list JetTarget = ["9fdd5d24-7801-4f16-8c85-c9a7d8fff952", "8259c797-bd86-4157-b65d-a68781626864", "b67326c0-d279-4af5-b692-670532c130fe", "f553d16c-26e1-48dd-a553-205bb7d71296", "f8220e96-bbf7-4df2-9588-c8b374c6af9e", "203df0d7-8910-436f-a46a-0a50b854e3ae"];
// System States
integer JetState = FALSE;
integer WaterState = FALSE;
integer SteamState = FALSE;
// Functions
Water(integer ISON){
float StepSize = (FullSizeWater.z - NoWater.z) / NumWaterLevels; // Size to Change prim each Step
integer i;
if(ISON){
llSetLinkTextureAnim(2, TRUE | LOOP, ALL_SIDES, 8, 8, 0.0, 64.0, 24.5 );
llSetLinkAlpha(2, 1.0, ALL_SIDES);
for(i=0;i<=NumWaterLevels;i++){
vector Size = llList2Vector(llGetLinkPrimitiveParams(2, [PRIM_SIZE]), 0);
Size.z = Size.z + StepSize;
llSetLinkPrimitiveParams(2, [PRIM_SIZE, Size]);
}
SteamState = TRUE;
Steam(TRUE);
}else{
Steam(FALSE);
Jets(FALSE);
for(i=0;i<=NumWaterLevels;i++){
vector Size = llList2Vector(llGetLinkPrimitiveParams(2, [PRIM_SIZE]), 0);
Size.z = Size.z - StepSize;
llSetLinkPrimitiveParams(2, [PRIM_SIZE, Size]);
}
llSetLinkAlpha(2, 0.0, ALL_SIDES);
llSetLinkTextureAnim(2, FALSE | LOOP, ALL_SIDES, 8, 8, 0.0, 64.0, 24.5 );
}
}
Steam(integer ISON){
if(ISON){
llLinkParticleSystem(2, [
PSYS_PART_FLAGS,( 0
|PSYS_PART_INTERP_COLOR_MASK
|PSYS_PART_INTERP_SCALE_MASK ),
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE ,
PSYS_PART_START_ALPHA,0.501961,
PSYS_PART_END_ALPHA,0.0117647,
PSYS_PART_START_COLOR,<1,1,1> ,
PSYS_PART_END_COLOR,<1,1,1> ,
PSYS_PART_START_SCALE,<3,3,0>,
PSYS_PART_END_SCALE,<0.1875,0.1875,0>,
PSYS_PART_MAX_AGE,2.14844,
PSYS_SRC_MAX_AGE,0,
PSYS_SRC_ACCEL,<0,0,-0.203125>,
PSYS_SRC_BURST_PART_COUNT,2,
PSYS_SRC_BURST_RADIUS,0.199219,
PSYS_SRC_BURST_RATE,0.046875,
PSYS_SRC_BURST_SPEED_MIN,0.796875,
PSYS_SRC_BURST_SPEED_MAX,1,
PSYS_SRC_ANGLE_BEGIN,0,
PSYS_SRC_ANGLE_END,1.46875,
PSYS_SRC_OMEGA,<0,0,0>,
PSYS_SRC_TEXTURE, (key)"26321045-e218-49c8-9387-e7801c890e27",
PSYS_SRC_TARGET_KEY, (key)"00000000-0000-0000-0000-000000000000"
]);
}else{
llLinkParticleSystem(2, []);
}
}
Jets(integer ISON){
integer i;
if(ISON){
for(i=0;i<=2;i++){
llLinkParticleSystem(llList2Integer(JetLink, i), [
PSYS_PART_FLAGS,( 0
|PSYS_PART_INTERP_COLOR_MASK
|PSYS_PART_INTERP_SCALE_MASK
|PSYS_PART_FOLLOW_SRC_MASK
|PSYS_PART_FOLLOW_VELOCITY_MASK
|PSYS_PART_TARGET_POS_MASK ),
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE ,
PSYS_PART_START_ALPHA,1,
PSYS_PART_END_ALPHA,0,
PSYS_PART_START_COLOR,<0.501961,0.501961,1> ,
PSYS_PART_END_COLOR,<1,1,1> ,
PSYS_PART_START_SCALE,<0,0,0>,
PSYS_PART_END_SCALE,<0.28125,0.28125,0>,
PSYS_PART_MAX_AGE,3,
PSYS_SRC_MAX_AGE,0,
PSYS_SRC_ACCEL,<0,0,0.046875>,
PSYS_SRC_BURST_PART_COUNT,8,
PSYS_SRC_BURST_RADIUS,0,
PSYS_SRC_BURST_RATE,0.0585938,
PSYS_SRC_BURST_SPEED_MIN,0.5,
PSYS_SRC_BURST_SPEED_MAX,1,
PSYS_SRC_ANGLE_BEGIN,2.09375,
PSYS_SRC_ANGLE_END,0.4375,
PSYS_SRC_OMEGA,<8,1.59375,1>,
PSYS_SRC_TEXTURE, (key)"1c79c1db-7cc0-421f-a363-499725617068",
PSYS_SRC_TARGET_KEY, llList2Key(JetTarget, i)
]);
}
for(i=3;i<=5;i++){
llLinkParticleSystem(llList2Integer(JetLink, i), [
PSYS_PART_FLAGS,( 0
|PSYS_PART_INTERP_COLOR_MASK
|PSYS_PART_INTERP_SCALE_MASK
|PSYS_PART_FOLLOW_SRC_MASK
|PSYS_PART_FOLLOW_VELOCITY_MASK
|PSYS_PART_TARGET_POS_MASK ),
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE ,
PSYS_PART_START_ALPHA,1,
PSYS_PART_END_ALPHA,0,
PSYS_PART_START_COLOR,<0.501961,0.501961,1> ,
PSYS_PART_END_COLOR,<1,1,1> ,
PSYS_PART_START_SCALE,<0,0,0>,
PSYS_PART_END_SCALE,<0.28125,0.28125,0>,
PSYS_PART_MAX_AGE,3,
PSYS_SRC_MAX_AGE,0,
PSYS_SRC_ACCEL,<0,0,0.046875>,
PSYS_SRC_BURST_PART_COUNT,8,
PSYS_SRC_BURST_RADIUS,0,
PSYS_SRC_BURST_RATE,0.0585938,
PSYS_SRC_BURST_SPEED_MIN,0.5,
PSYS_SRC_BURST_SPEED_MAX,1,
PSYS_SRC_ANGLE_BEGIN,2.09375,
PSYS_SRC_ANGLE_END,0.4375,
PSYS_SRC_OMEGA,<8,1.59375,1>,
PSYS_SRC_TEXTURE, (key)"1c79c1db-7cc0-421f-a363-499725617068",
PSYS_SRC_TARGET_KEY, llList2Key(JetTarget, i)
]);
}
}else{
for(i=0;i<=2;i++){
llLinkParticleSystem(llList2Integer(JetLink, i), []);
}
for(i=3;i<=5;i++){
llLinkParticleSystem(llList2Integer(JetLink, i), []);
}
}
}
default{
state_entry(){
llListenRemove(ListenHandle);
ListenChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
}
touch(integer num){
key id = llDetectedKey(0);
llSetTimerEvent(30.0);
ListenHandle = llListen(ListenChannel, EMPTY, EMPTY, EMPTY);
llDialog(id, "Please select option...", MainMenu, ListenChannel);
}
listen(integer channel, string num, key id, string msg){
llSetTimerEvent(30.0);
if(msg=="Fill"){
WaterState = TRUE;
Water(TRUE);
}else if(msg=="Empty"){
WaterState = FALSE;
Water(FALSE);
}else if(msg=="Steam On"){
if(!WaterState){
llSay(0, "You must have water in the tub to turn the Steam On.");
return;
}
Steam(TRUE);
}else if(msg=="Steam Off"){
Steam(FALSE);
}else if(msg=="Jets On"){
if(!WaterState){
llSay(0, "You must have water in the tub to turn the Jets On.");
return;
}
Jets(TRUE);
}else if(msg=="Jets Off"){
Jets(FALSE);
}else{
llSetTimerEvent(0);
llListenRemove(ListenHandle);
}
}
timer(){
llSetTimerEvent(0);
llListenRemove(ListenHandle);
}
}

340
JacuzziTub/LICENSE.txt Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -20,6 +20,7 @@
//Configuration:
integer MeasureNonParcelPrims=FALSE;
//Variables, these are dynamically set, don't bother with them.
float timertime=0.5;
string region;
string sim;
vector color;
@@ -31,30 +32,58 @@ integer minutes;
integer seconds;
integer lastrestartedcalc;
list same_params =[PRIM_SLICE, <0.5, 1.0, 0.0>,PRIM_FULLBRIGHT,ALL_SIDES,TRUE,PRIM_TEXTURE,ALL_SIDES,TEXTURE_BLANK,ZERO_VECTOR,ZERO_VECTOR,0];
integer toggle=1;
default
{
state_entry()
{
llSetObjectName("Open Source Lag Meter v3");
llSetObjectName("Open Source Lag Meter v12.1");
llSetLinkPrimitiveParams(1,same_params+[PRIM_COLOR,ALL_SIDES,<0,0,0>,.4,PRIM_SIZE,<.5,.5,4>]);
llSetLinkPrimitiveParams(2,same_params+[PRIM_COLOR,ALL_SIDES,<0,1,0>,1.,PRIM_SIZE,<.4,.4,3.8>,PRIM_POS_LOCAL,<0,0,.04>]);
llSetLinkPrimitiveParams(2,same_params+[PRIM_COLOR,ALL_SIDES,<0,1,0>,1.,PRIM_SIZE,<.4,.4,3.8>,PRIM_POS_LOCAL,<0,0,.04>,PRIM_GLOW,ALL_SIDES,0.1]);
llSetText("Initalizing...",<1,1,0>, 1.0);
//First start, Set some stuff.
lastrestart = llGetUnixTime();
llSetTimerEvent(0.5); //One second is too much checking. Let's not be a resource hog.
llSetTimerEvent(timertime); //One second is too much checking. Let's not be a resource hog.
}
on_rez(integer start_param)
{
llSetPos(llGetPos()+<0,0,-2.>);
}
changed(integer change)
{
if(change & CHANGED_REGION_START)
lastrestart = llGetUnixTime();
}
touch_start(integer num_detected)
{
key avatarKey = llDetectedKey(0);
if (avatarKey==llGetOwner())
{
toggle=!toggle;
if(toggle==0)
{
llSetTimerEvent(0);
llSetLinkColor(2,<0.5,0.5,0.5>,ALL_SIDES);
llSetText("deactivated.\nTouch to activate.",<1,0.5,0>, 1.0);
}
else
{
llSetLinkColor(2,<0,1,0>,ALL_SIDES);
llSetTimerEvent(timertime);
}
}
}
timer(){
region = llGetRegionName();
avatars = llGetListLength(llGetAgentList(AGENT_LIST_REGION, []));
//Restart time
lastrestartedcalc = llGetUnixTime()-lastrestart;
lastrestartedcalc = llGetUnixTime()-(integer)llGetEnv("region_start_time");//-lastrestart;
days=0;
hours=0;
minutes=0;
@@ -83,13 +112,23 @@ default
color=<1,0,0>;
integer primsused=llGetParcelPrimCount(llGetPos(), PARCEL_COUNT_TOTAL, MeasureNonParcelPrims);
integer maxprims=llGetParcelMaxPrims(llGetPos(), MeasureNonParcelPrims);
string sim_version=llGetEnv("sim_version");
list lsim_version=llParseString2List(sim_version,[" "],[]);
string sim_version_clean=llList2String(lsim_version,0)+" "+llList2String(lsim_version,1);
llSetText(
"Region: "+region+
"\nAvatars: "+(string)avatars+
//"\nSimChan: "+llGetEnv("sim_channel")+
"\nSimHostn: "+llGetEnv("simulator_hostname")+
"\nSimVrsn: "+sim_version_clean+
"\nPhysics: "+osGetPhysicsEngineName()+
"\nScripts: " + osGetScriptEngineName()+
// "\nProdn: "+llGetEnv("region_product_name")+
"\nAvas: "+(string)avatars+"/"+llGetEnv("agent_limit")+
"\nPrims left: "+(string)(maxprims-primsused)+" ("+(string)primsused+"/"+(string)maxprims+")"+
"\nTemp on rez: "+(string)llGetParcelPrimCount(llGetPos(),PARCEL_COUNT_TEMP, FALSE)+
"\nDilation: "+llGetSubString((string)((1.-region_time_dilation)*100.), 0, 3)+"%"+
"\nFPS: "+llGetSubString((string)llGetRegionFPS(), 0, 5)+
"\nLast restart:\n"+(string)days+" Days, "+(string)hours+" Hours, "+(string)minutes+" Minutes, and "+(string)seconds+" Seconds ago.",
"\nLast restart:\n"+(string)days+" days, "+(string)hours+" hrs, "+(string)minutes+" min, and "+(string)seconds+" sec ago.",
//"\nLast restart:\n"+(string)days+":"+(string)hours+":"+(string)minutes+":"+(string)seconds,
color, 1.0);
//llSetLinkPrimitiveParamsFast(2,[PRIM_SLICE,<0,(region_time_dilation),0>,PRIM_COLOR,ALL_SIDES,color,1]);

View File

@@ -0,0 +1,93 @@
string int2hex(integer x)
{
string hex="0123456789ABCDEF";
return llGetSubString(hex, (x >> 4), (x >> 4)) +
llGetSubString(hex, x & 0xF, x & 0xF);
}
default
{
state_entry()
{
llOwnerSay("Script running");
}
touch_end(integer touched)
{
if (llDetectedKey(0) == llGetOwner())
{
llOwnerSay("Starting...");
float mapX = 0.0;
float mapY = 0.0;
float mapZ = 0.0;
integer x = 0;
integer y = 0;
integer z = 0;
integer offsetX = 0;
integer offsetY = 0;
string colorX = "";
string colorY = "";
string colorZ = "";
string draw = osSetPenSize("", 1);
vector pos = llGetPos();
for (; y < 64; y++)
{
draw = osMovePen(draw, 0, y);
offsetX = 0;
if (y == 63) offsetY = 1;
for (x = 0; x < 64; x++)
{
if (x == 63) offsetX = 1;
mapX = ((float)x + offsetX) / 2.0 - 16.0;
mapY = ((float)y + offsetY) / 2.0 - 16.0;
mapZ = llGround(<mapX, mapY, 0.0>);
if (mapZ > (pos.z + 16.0)) z = 255;
else if (mapZ < (pos.z - 16.0)) z = 0;
else { z = llRound((mapZ - (pos.z - 16.0)) * 8.0); }
if (x == 63) colorX = "FF";
else colorX = int2hex(x * 4);
if (y == 63) colorY = "FF";
else colorY = int2hex(y * 4);
if (z == 256) colorZ = "FF";
else colorZ = int2hex(z);
draw = osSetPenColor(draw, "FF" + colorX + colorY + colorZ);
draw = osDrawLine(draw, x, y, x + 1, y);
}
}
osSetDynamicTextureDataBlendFace("", "vector", draw, "width:64,height:64", FALSE, 2, 0, 255, 1);
llSetPrimitiveParams([PRIM_SIZE, <32.0, 32.0, 32.0>,
PRIM_TYPE, PRIM_TYPE_SCULPT,
llGetTexture(1),
PRIM_SCULPT_TYPE_PLANE | PRIM_SCULPT_FLAG_INVERT]);
state done;
}
}
}
state done
{
state_entry()
{
llSetClickAction(CLICK_ACTION_NONE);
llOwnerSay("Done.");
//llRemoveInventory(llGetScriptName());
}
}

340
Lucky Chair/LICENSE.txt Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,106 @@
key Sitter = NULL_KEY;
list Prizes;
string TimerMode;
integer TimerRoundCount;
integer TimerCountDown = 10;
list Players;
string SittingAnim = "Sit 1";
// Init Function
Init(){
integer NumPrizes = llGetInventoryNumber(INVENTORY_OBJECT);
integer i;
for(i=0;i<NumPrizes;i++){
Prizes = Prizes + [llGetInventoryName(INVENTORY_OBJECT, i)];
llOwnerSay("Prize: "+llList2String(Prizes, -1)+" Added!");
}
TimerRoundCount = TimerCountDown;
if(llGetListLength(Prizes)>0){
llLinkSitTarget(1, <0,0,0.1>, ZERO_ROTATION);
llOwnerSay("System Ready!");
}
}
PickWinner(){
float Num = llFrand(10.0);
if((integer)Num > 5){
integer NumPrizes = llGetListLength(Prizes);
string Prize = llList2String(Prizes, (integer)llFrand((NumPrizes - 1)));
llShout(0, "We have a WINNER! Prize Won: "+Prize);
llRegionSayTo(Sitter, 0, "You are a WINNER! You have won the "+Prize);
llGiveInventory(Sitter, Prize);
Players = Players + [Sitter];
llUnSit(Sitter);
Sitter = NULL_KEY;
}else{
Players = Players + [Sitter];
llRegionSayTo(Sitter, 0, "Better Luck Next Time!");
llUnSit(Sitter);
Sitter = NULL_KEY;
}
}
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
Init();
}
changed(integer change){
if(change & CHANGED_INVENTORY){
llResetScript();
}
if(change & CHANGED_LINK){
key sitterKey=llAvatarOnLinkSitTarget(1);
if (Sitter==NULL_KEY && sitterKey!=NULL_KEY) // someone sitting down
{
Sitter=sitterKey;
llRegionSayTo(Sitter, 0, "Please Accept Animation Permissions to start the Lucky Chair!");
TimerMode = "Sitting";
llSetTimerEvent(15.0);
llRequestPermissions(Sitter,PERMISSION_TRIGGER_ANIMATION);
}else if (Sitter!=NULL_KEY && sitterKey==NULL_KEY){
Sitter = NULL_KEY;
llSetTimerEvent(0);
}else if (Sitter!=NULL_KEY && sitterKey!=Sitter) // someone sitting but object already occupied by someone else
{
llUnSit(sitterKey);
llRegionSayTo(sitterKey,0,"Sorry, someone else is already sitting here, Please wait...");
}
return;
}
}
run_time_permissions(integer perms){
if(perms & PERMISSION_TRIGGER_ANIMATION){
TimerMode = "CountDown";
llStopAnimation("stand");
llStartAnimation(SittingAnim);
llShout(0, "We have a player for the lucky chair!\n Counting Down...");
llSetTimerEvent(1.0);
}
}
timer(){
if(TimerMode=="Sitting"){
llStopAnimation(SittingAnim);
llStartAnimation("stand");
llUnSit(Sitter);
llSleep(1.0);
llResetScript();
}else if(TimerMode=="CountDown"){
if(TimerRoundCount==0){
TimerRoundCount = TimerCountDown;
llSetTimerEvent(0);
PickWinner();
}else{
llShout(0, "Picking a Winner in "+(string)TimerRoundCount+" seconds...");
TimerRoundCount--;
}
}
}
}

52
Metors/DayChecker1_00.lsl Normal file
View File

@@ -0,0 +1,52 @@
//DayChecker 1.0
// Simple script for testing day/night time and give a shout if daytime changes
// GLOBALS
integer Debug = FALSE ;
integer time_check = 20 ; // periode om nacht te checken
integer Gchannel = 10001 ; // General channel for daycheck
default // default daytime state
{
state_entry()
{
llRegionSay(Gchannel, "Day");
llSetTimerEvent(time_check); // Checks default every 120 secs = 2 minutes
}
timer() // If timer reached ...
{
vector sun = llGetSunDirection(); // Gets Sun Direction as a vector
if (sun.z < 0) state nighttime; // If its night goes to state nighttime
llOwnerSay("It's daytime " + (string)sun.z); // Says to Owner its daytime
}
touch_start(integer total_number) // If touched ...
{
key lAvatarKey = llDetectedKey(0) ;
string lAvatarName = llKey2Name(llDetectedKey(0)) ;
state nighttime;
}
}
state nighttime // nighttime state
{
state_entry()
{
llRegionSay(Gchannel, "Night");
llSetTimerEvent(time_check); // Checks default every 120 secs = 2 minutes
}
timer() // If timer reached ....
{
vector sun = llGetSunDirection(); // Gets Sun Direction as a vector
if (sun.z > 0) state default; // If its day, change back to daytime state
llOwnerSay("It's nighttime " + (string)sun.z); // Says to Owner its daytime
}
touch_start(integer total_number) // If touched ...
{
llWhisper(0,"Nighttime"); // Says to Owner its nighttime
state default;
}
}

BIN
Metors/Meteors.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

74
Metors/Meteors.lsl Normal file
View File

@@ -0,0 +1,74 @@
// Name:meteors.lsl
// Author:JPvdGiessen IT Consultancy
integer Debug = FALSE ;
integer Gchannel =10001; // Channel for DayChecker
vector color = <1,1,1>; // Use to change the color of the light
float intensity = 1.000; // Use to change the intensity of the light, from 0 to 1
float radius = 1.000; // Use to change the radius of the light, from 0 to 20
float falloff = 0.150; // Use to set the falloff of the light, from 0 to 2
particlesOn()
{
integer flags = 0;
flags = flags | PSYS_PART_EMISSIVE_MASK | PSYS_PART_INTERP_COLOR_MASK;
// flags = flags | PSYS_PART_FOLLOW_SRC_MASK;
flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK;
llParticleSystem([ PSYS_PART_MAX_AGE, 50.5,
PSYS_PART_FLAGS, flags,
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,
PSYS_PART_END_COLOR, <1.0, 1.0, 0.8>,
PSYS_PART_START_SCALE, <0.3,0.3,0.3>,
PSYS_PART_END_SCALE, <0.5,0.5,0.5>,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE,
PSYS_SRC_BURST_RATE, 1,
PSYS_SRC_ACCEL, <0,1.0,0>,
PSYS_SRC_BURST_PART_COUNT, 5,
PSYS_SRC_BURST_SPEED_MIN, 0.05,
PSYS_SRC_BURST_SPEED_MAX, 25.0,
PSYS_SRC_INNERANGLE, 0.5,
PSYS_SRC_OUTERANGLE, 0.0,
PSYS_SRC_OMEGA, <0,0,0>,
PSYS_PART_START_ALPHA, 1.0,
PSYS_PART_END_ALPHA, 0.25,
PSYS_SRC_BURST_RADIUS, 4.5
]);
}
particlesOff()
{
llParticleSystem([]);
}
default
{
state_entry()
{
llSay(0, "Script running");
llListen (Gchannel, "", "", "");
}
listen(integer channel, string name, key id, string message)
{
if ( message == "Night")
{
particlesOn() ;
llSetPrimitiveParams( [ PRIM_GLOW, ALL_SIDES, 0.3 ] ) ;
llSetPrimitiveParams([PRIM_POINT_LIGHT,TRUE,
<1.0,0.7,1.0>, // light color vector range: 0.0-1.0 *3
intensity, // intensity (0.0-1.0)
radius, // radius (.1-10.0)
falloff ]); // falloff (.01-1.0)
llSetAlpha(1.0, ALL_SIDES);
} else if ( message == "Day") {
particlesOff() ;
llSetPrimitiveParams([PRIM_FULLBRIGHT,ALL_SIDES,FALSE]);
llSetPrimitiveParams([PRIM_POINT_LIGHT, FALSE, // if this is false, light is off,
<0.0,1.0,0.0>,1.0, 10.0, 0.5]); // rest of params don't matter
llSetPrimitiveParams( [ PRIM_GLOW, ALL_SIDES, 0 ] ) ;
llSetAlpha(0.0, ALL_SIDES);
}
}
}

11
Metors/readme.txt Normal file
View File

@@ -0,0 +1,11 @@
Name: Meteors, Particle Script
Author: J.P. van de Giessen (J.P. van de Giessen IT Consultancy, www.giessenict.nl)
Mail: tersus@solcon.nl
Creation Date: 9 jul 2012
Release: 1.01
Description: Create a prime (like a sphere), place the Meteor.lsl script in it and put the sphere on a height of about 60 meters. Create a second prim and
place the DayChecker script in it. Both prims must be in the same region. At night you will see the meteors, or if you can't wait, touch the DayChecker prim.
If you use it in your own environment, please sent an image to me.
License: This object is created by J.P. van de Giessen IT Consultancy (www.giessenict.nl) and is published under the following copyrights:
Creative Commons Naamsvermelding-NietCommercieel-GelijkDelen 3.0 Nederland license (http://creativecommons.org/licenses/by-nc-sa/3.0/nl/).

View File

@@ -0,0 +1,240 @@
//Multi File Sound Player For Music Or Sounds Works Without Needing File Name changing If Named Right
//Script auto determin order of list of sound files in alphbetical order
float INTERVAL = 10.00;
integer LISTEN_CHAN = 2000;
integer SEND_CHAN = 2001;
float VOLUME = 1.0;
integer g_iSound;
integer tottrack;
integer g_iListenCtrl = -1;
integer g_iPlaying;
integer g_iLinked;
integer g_iStop;
integer g_iPod;
string g_sLink;
// DEBUG
integer g_iWasLinked;
integer g_iFinished;
Initialize()
{
// reset listeners
if ( g_iListenCtrl != -1 )
{
llListenRemove(g_iListenCtrl);
}
g_iListenCtrl = llListen(LISTEN_CHAN,"","","");
g_iPlaying = 0;
g_iLinked = 0;
}
PlaySong()
{
integer i;
g_iPlaying = 1;
llSetSoundQueueing(TRUE);
tottrack = llGetInventoryNumber(INVENTORY_SOUND);
llPlaySound(llGetInventoryName(INVENTORY_SOUND, 0),VOLUME);
llPreloadSound(llGetInventoryName(INVENTORY_SOUND, 1));
llSetTimerEvent(5.0); // wait 5 seconds before queueing the second file
g_iSound = 1;
// for ( i = 1; i < tottrack; i++ )
// {
// llPreloadSound(llGetInventoryName(INVENTORY_SOUND, i));
// }
}
StopSong()
{
g_iPlaying = 0;
llStopSound();
llSetTimerEvent(0.0);
}
integer CheckLink()
{
string sLink;
sLink = llGetLinkName(1);
g_sLink = sLink;
if ( llGetSubString(sLink,0,6) == "Jukebox" )
{
return TRUE;
}
return FALSE;
}
default
{
state_entry()
{
Initialize();
}
on_rez(integer start_param)
{
Initialize();
if ( start_param )
{
g_iPod = start_param - 1;
if ( g_iPod )
{
llRequestPermissions(llGetOwner(),PERMISSION_ATTACH);
} else {
// Tell the controller what the CD key is so it can lin
}
}
}
changed(integer change)
{
if ( change == CHANGED_LINK )
{
if ( llGetLinkNumber() == 0 )
{
StopSong();
llDie();
} else {
if ( g_iStop )
{
llMessageLinked(1,llGetLinkNumber(),"UNLINK","");
} else {
llMessageLinked(1,llGetLinkNumber(),"LINKID","");
g_iWasLinked = 1;
}
}
}
}
attach(key id)
{
if ( id == NULL_KEY )
{
llDie();
} else {
PlaySong();
}
}
run_time_permissions(integer perm)
{
if ( perm == PERMISSION_ATTACH )
{
llAttachToAvatar(ATTACH_LSHOULDER);
llSetTexture("clear",ALL_SIDES);
}
}
touch_start(integer total_number)
{
integer i;
for ( i = 0; i < total_number; i++ )
{
if ( llDetectedKey(i) == llGetOwner() )
{
if ( g_iPlaying )
{
g_iPlaying = 0;
llStopSound();
llSetTimerEvent(0.0);
} else {
PlaySong();
}
}
}
}
listen(integer channel, string name, key id, string message)
{
if ( message == "RESET" )
{
if ( llGetLinkNumber() == 0 )
{
llDie();
} else {
llMessageLinked(1,llGetLinkNumber(),"UNLINK","");
}
}
if ( message == "STOP" )
{
if ( g_iPod )
{
StopSong();
llDetachFromAvatar();
}
}
}
link_message(integer sender_num, integer num, string str, key id)
{
if ( str == "PLAY" )
{
if ( !g_iPlaying )
{
PlaySong();
}
return;
}
if ( str == "STOP" )
{
g_iStop = 1;
StopSong();
llMessageLinked(1,llGetLinkNumber(),"UNLINK","");
}
if ( str == "VOLUME" )
{
VOLUME = (float)num / 10.0;
llAdjustSoundVolume(VOLUME);
}
}
timer()
{
if ( g_iPlaying )
{
if ( g_iSound == 1 )
{
llSetTimerEvent(INTERVAL);
}
llPlaySound(llGetInventoryName(INVENTORY_SOUND, g_iSound),VOLUME);
if ( g_iSound < (tottrack - 1) )
{
llPreloadSound(llGetInventoryName(INVENTORY_SOUND, g_iSound+1));
}
g_iSound++;
if ( g_iSound >= tottrack )
{
llSetTimerEvent(INTERVAL + 5.0);
g_iPlaying = 0;
}
} else {
if ( llGetLinkNumber() != 0 )
{
llSetTimerEvent(0.0);
if ( g_iPod )
{
llDetachFromAvatar();
} else {
llMessageLinked(1,0,"FINISH","");
g_iFinished = 1;
}
}
}
}
}

View File

@@ -0,0 +1,525 @@
// ********** SIMPLE DIALOG MODULE ********** //
// By Nargus Asturias
// Version 1.80
//
// Support only one dialog at a time. DO NOT request multiple dialog at once!
// Use of provided functions are recommented. Instruction here are for hardcore programmers only!
//
// Request: Send MessageLinked to the script. There are 3 dialog modes:
// lnkDialog : Normal dialog with message and buttons
// lnkDialogNumericAdjust : A dialog with buttons can be used to adjust numeric value
// lnkDialogNotify : Just a simple notification dialog. No return value and no buttons.
//
// Send MessageLinked with code lnkDialogReshow to force active dialog to reappear.
// Send MessageLinked with code lnkDialogCancel to force cancel active dialog
//
// If a lnkDialog is requested with more than 12 buttons, multi-pages dialog is used to show the buttons.
//
// [ For lnkDialog ]
// MessageLinked Format:
// String part: List dumped into string, each entry seperated by '||'
// Field 1: Dialog message (512 bytes maximum)
// Field 2: Time-out data (integer)
// Field 3-4: Button#1 and return value pair
// Field 5-6: Button#2 and return value pair
// And go on...
// Key part: Key of AV who attend this dialog
//
// Response: MessageLinked to the prim that requested dialog (but no where else)
// num == lnkDialogResponse: AV click on a button. The buttons value returned as a string
// num == lnkDialogTimeOut: Dialog timeout.
//
// [ For lnkDialogNumericAdjust ]
// MessageLinked Format:
// String part: List dumped into string, each entry seperated by '||'
// Field 1: Dialog message (512 bytes maximum)
// Put {VALUE} where you want the current value to be displayed)
// Field 2: Time-out data (integer)
// Field 3: Most significant value (ie. 100, for +/-100)
// Field 4: String-casted numeric value to be adjusted
// Field 5: 2nd most significant value (ie. 10, for +/-10)
// Field 6: Use '1' to enable "+/-" button, '0' otherwise.
// Field 7: 3nd significant value (ie. 1, for +/-1)
// Field 8: Use '1' for integer, or '0' for float
// Field 9: Least significant value (ie. 0.1, for +/-0.1)
// Field 10: Reserved. Not used.
// Key part: Key of AV who attend this dialog
//
// Response: MessageLinked to the prim that requested dialog (but no where else)
// num == lnkDialogResponse: OK or Cancel button is clicked. The final value returned as string.
// num == lnkDialogTimeOut: Dialog timeout.
//
// ******************************************* //
// Constants
integer lnkDialog = 14001;
integer lnkDialogNumericAdjust = 14005;
integer lnkDialogNotify = 14004;
integer lnkDialogReshow = 14011;
integer lnkDialogCancel = 14012;
integer lnkDialogResponse = 14002; // A button is hit, or OK is hit for lnkDialogNumericAdjust
integer lnkDialogCanceled = 14006; // Cancel is hit for lnkDialogNumericAdjust
integer lnkDialogTimeOut = 14003; // No button is hit, or Ignore is hit
integer lnkMenuClear = 15001;
integer lnkMenuAdd = 15002;
integer lnkMenuShow = 15003;
integer lnkMenuNotFound = 15010;
string seperator = "||";
// Menus variables
list menuNames = []; // List of names of all menus
list menus = []; // List of packed menus command, in order of menuNames
integer lastMenuIndex = 0; // Latest called menu's index
// Dialog variables
integer dialogChannel; // Channel number used to spawn this dialog
string message; // Message to be shown with the dialog
integer timerOut; // Dialog time-out
key keyId; // Key of user who attending this dialog
integer requestedNum; // Link-number of the requested prim
list buttons; // List of dialog buttons
list returns; // List of results from dialog buttons
float numericValue;
integer useInteger;
// Other variables
integer buttonsCount;
integer startItemNo;
integer listenId;
string redirectState;
integer responseInt = -1;
string responseStr;
key responseKey;
list order_buttons(list buttons)
{
return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4)
+ llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
}
// ********** String Functions **********
string replaceString(string pattern, string replace, string source){
integer index = llSubStringIndex(source, pattern);
if(index < 0) return source;
source = llDeleteSubString(source, index, (index + llStringLength(pattern) - 1));
return llInsertString(source, index, replace);
}
// ********** Dialog Functions **********
// Function: createDialog
// Create dialog with given message and buttons, direct to user with give id
integer createDialog(key id, string message, list buttons){
integer channel = -((integer)llFrand(8388608))*(255) - (integer)llFrand(8388608) - 11;
llListenRemove(listenId);
listenId = llListen(channel, "", keyId, "");
llDialog(keyId, message, order_buttons(buttons), channel);
return channel;
}
// Function: createMultiDialog
// Create dialog with multiple pages. Each page has Back, Next, and a Close button. Otherwise same functionality as createDialog() function.
integer createMultiDialog(key id, string message, list buttons, integer _startItemNo){
integer channel = -llRound(llFrand( llFabs(llSin(llGetGMTclock())) * 1000000 )) - 11;
if(_startItemNo < 0) _startItemNo = 0;
if(_startItemNo >= buttonsCount - 1) _startItemNo -= 9;
startItemNo = _startItemNo;
integer vButtonsCount = buttonsCount - 2;
// Generate list of buttons to be shown
string closeButton = llList2String(buttons, buttonsCount - 1);
integer stopItemNo = startItemNo + 8;
if(stopItemNo >= buttonsCount - 1) stopItemNo = vButtonsCount;
list thisButtons = llList2List(buttons, startItemNo, stopItemNo);
// Generate dialog navigation buttons
integer i = stopItemNo - startItemNo + 1;
i = i % 3;
if(i > 0)
{
while(i < 3)
{
thisButtons += [" "];
i++;
}
}
if(startItemNo > 0)
thisButtons += ["<< BACK"];
else thisButtons += [" "];
thisButtons += [closeButton];
if(stopItemNo < vButtonsCount)
thisButtons += ["NEXT >>"];
else thisButtons += [" "];
// Append page number to the message
integer pageNumber = (integer)(stopItemNo / 9) + 1;
integer pagesCount = llCeil(vButtonsCount / 9.0);
string vMessage = "PAGE: " + (string)pageNumber + " of " + (string)pagesCount + "\n" +
message;
// Display dialog
llListenRemove(listenId);
listenId = llListen(channel, "", keyId, "");
llDialog(keyId, vMessage, order_buttons(thisButtons), channel);
return channel;
}
// Function: generateNumericAdjustButtons
// Generate numeric adjustment dialog which adjustment values are in given list.
// If useNegative is TRUE, "+/-" button will be available.
list generateNumericAdjustButtons(list adjustValues, integer useNegative){
list dialogControlButtons;
list positiveButtons;
list negativeButtons;
list additionButtons;
dialogControlButtons = ["OK", "Cancel"];
// Config adjustment buttons
integer count = llGetListLength(adjustValues);
integer index;
for(index = 0; (index < count) && (index < 3); index++){
string sValue = llList2String(adjustValues, index);
if((float)sValue != 0){
positiveButtons += ["+" + sValue];
negativeButtons += ["-" + sValue];
}
}
// Check positive/negative button
if(useNegative)
additionButtons = ["+/-"];
else additionButtons = [];
// If there is fourth adjustment button
if(count > 3){
if(llGetListLength(additionButtons) == 0) additionButtons = [" "];
string sValue = llList2String(adjustValues, index);
additionButtons += ["+" + sValue, "-" + sValue];
}else if(additionButtons != []) additionButtons += [" ", " "];
// Return list dialog buttons
return additionButtons + negativeButtons + positiveButtons + dialogControlButtons;
}
setResponse(integer int, string str, key id){
responseInt = int;
responseStr = str;
responseKey = id;
}
checkDialogRequest(integer sender_num, integer num, string str, key id){
if((num == lnkDialogNotify) || (num == lnkDialogNumericAdjust) || (num == lnkDialog)){
list data = llParseStringKeepNulls(str, [seperator], []);
message = llList2String(data, 0);
timerOut = llList2Integer(data, 1);
keyId = id;
requestedNum = sender_num;
buttons = [];
returns = [];
if(message == "") message = " ";
if(timerOut > 7200) timerOut = 7200;
integer i;
integer count;
count = llGetListLength(data);
for(i=2; i<count; i += 0){
buttons += [llList2String(data, i++)];
returns += [llList2String(data, i++)];
}
buttonsCount = llGetListLength(buttons);
if(num == lnkDialogNotify){
dialogChannel = -((integer)llFrand(8388608))*(255) - (integer)llFrand(8388608) - 11;
llDialog(keyId, message, order_buttons(buttons), dialogChannel);
return;
}else if(num == lnkDialogNumericAdjust)
redirectState = "NumericAdjustDialog";
else if(num == lnkDialog){
if(buttonsCount > 12)
redirectState = "MultiDialog";
else redirectState = "Dialog";
}
if(TRUE) state StartDialog;
}else checkMenuRequest(sender_num, num, str, id);
}
// ********** Menu Functions **********
clearMenusList(){
menuNames = [];
menus = [];
lastMenuIndex = 0;
}
addMenu(string name, string message, list buttons, list returns){
// Reduced menu request time by packing request commands
string packed_message = message + seperator + "0";
integer i;
integer count = llGetListLength(buttons);
for(i=0; i<count; i++) packed_message += seperator + llList2String(buttons, i) + seperator + llList2String(returns, i);
// Add menu to the menus list
integer index = llListFindList(menuNames, [name]);
if(index >= 0)
menus = llListReplaceList(menus, [packed_message], index, index);
else{
menuNames += [name];
menus += [packed_message];
}
}
integer showMenu(string name, key id){
if(llGetListLength(menuNames) <= 0) return FALSE;
integer index;
if(name != ""){
index = llListFindList(menuNames, [name]);
if(index < 0) return FALSE;
}else index = lastMenuIndex;
lastMenuIndex = index;
// Load menu command and execute
string packed_message = llList2String(menus, index);
llMessageLinked(LINK_THIS, lnkDialog, packed_message, id);
return TRUE;
}
checkMenuRequest(integer sender_num, integer num, string str, key id){
// Menu response commands
if(num == lnkDialogResponse){
if(llGetSubString(str, 0, 4) == "MENU_"){
str = llDeleteSubString(str, 0, 4);
showMenu(str, id);
}
}
// Menu management commands
else if(num == lnkMenuClear)
clearMenusList();
else if(num == lnkMenuAdd){
list data = llParseString2List(str, [seperator], []);
string message = llList2String(data, 0);
list buttons = [];
list returns = [];
integer i;
integer count = llGetListLength(data);
for(i=2; i<count; i += 0){
buttons += [llList2String(data, i++)];
returns += [llList2String(data, i++)];
}
addMenu((string)id, message, buttons, returns);
}else if(num == lnkMenuShow){
if(!showMenu(str, id)) llMessageLinked(sender_num, lnkMenuNotFound, str, NULL_KEY);
}
}
// ********** States **********
default{
state_entry(){
if(responseInt > 0) llMessageLinked(requestedNum, responseInt, responseStr, responseKey);
}
link_message(integer sender_num, integer num, string str, key id){
checkDialogRequest(sender_num, num, str, id);
}
}
state StartDialog{
state_entry(){
if(redirectState == "Dialog") state Dialog;
else if(redirectState == "MultiDialog") state MultiDialog;
else if(redirectState == "NumericAdjustDialog") state NumericAdjustDialog;
else state default;
}
}
state Dialog{
state_entry(){
responseInt = -1;
dialogChannel = createDialog(keyId, message, buttons);
llSetTimerEvent(timerOut);
}
state_exit(){
llSetTimerEvent(0);
}
on_rez(integer start_param){
state default;
}
timer(){
setResponse(lnkDialogTimeOut, "", keyId);
state default;
}
link_message(integer sender_num, integer num, string str, key id){
if(num == lnkDialogReshow){
dialogChannel = createDialog(keyId, message, buttons);
llSetTimerEvent(timerOut);
}else if(num == lnkDialogCancel) state default;
else checkDialogRequest(sender_num, num, str, id);
}
listen(integer channel, string name, key id, string msg){
if((channel != dialogChannel) || (id != keyId)) return;
integer index = llListFindList(buttons, [msg]);
setResponse(lnkDialogResponse, llList2String(returns, index), keyId);
state default;
}
}
state MultiDialog {
state_entry(){
responseInt = -1;
startItemNo = 0;
dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo);
llSetTimerEvent(timerOut);
}
state_exit(){
llSetTimerEvent(0);
}
on_rez(integer start_param){
state default;
}
timer(){
setResponse(lnkDialogTimeOut, "", keyId);
state default;
}
link_message(integer sender_num, integer num, string str, key id){
if(num == lnkDialogReshow){
dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo);
llSetTimerEvent(timerOut);
}else if(num == lnkDialogCancel) state default;
else checkDialogRequest(sender_num, num, str, id);
}
listen(integer channel, string name, key id, string msg){
if((channel != dialogChannel) || (id != keyId)) return;
// Dialog control buttons
if(msg == "<< BACK"){
dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo - 9);
llSetTimerEvent(timerOut);
}else if(msg == "NEXT >>"){
dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo + 9);
llSetTimerEvent(timerOut);
}else if(msg == " "){
dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo);
llSetTimerEvent(timerOut);
// Response buttons
}else{
integer index = llListFindList(buttons, [msg]);
setResponse(lnkDialogResponse, llList2String(returns, index), keyId);
state default;
}
}
}
state NumericAdjustDialog {
state_entry(){
responseInt = -1;
numericValue = llList2Float(returns, 0);
useInteger = llList2Integer(returns, 2);
buttons = generateNumericAdjustButtons(buttons, llList2Integer(returns, 1));
string vMessage;
if(useInteger)
vMessage = replaceString("{VALUE}", (string)((integer)numericValue), message);
else vMessage = replaceString("{VALUE}", (string)numericValue, message);
dialogChannel = createDialog(keyId, vMessage, buttons);
llSetTimerEvent(timerOut);
}
state_exit(){
llSetTimerEvent(0);
}
on_rez(integer start_param){
state default;
}
timer(){
setResponse(lnkDialogTimeOut, "", keyId);
state default;
}
link_message(integer sender_num, integer num, string str, key id){
if(num == lnkDialogReshow){
dialogChannel = createDialog(keyId, message, buttons);
llSetTimerEvent(timerOut);
}else if(num == lnkDialogCancel) state default;
else checkDialogRequest(sender_num, num, str, id);
}
listen(integer channel, string name, key id, string msg){
if((channel != dialogChannel) || (id != keyId)) return;
// Dialog control button is hit
if(msg == "OK"){
setResponse(lnkDialogResponse, (string)numericValue, keyId);
state default;
}else if(msg == "Cancel"){
setResponse(lnkDialogCanceled, (string)numericValue, keyId);
llMessageLinked(requestedNum, lnkDialogCanceled, (string)numericValue, keyId);
state default;
// Value adjustment button is hit
}else if(msg == "+/-")
numericValue = -numericValue;
else if(llSubStringIndex(msg, "+") == 0)
numericValue += (float)llDeleteSubString(msg, 0, 0);
else if(llSubStringIndex(msg, "-") == 0)
numericValue -= (float)llDeleteSubString(msg, 0, 0);
// Spawn another dialog if no OK nor Cancel is hit
string vMessage;
if(useInteger)
vMessage = replaceString("{VALUE}", (string)((integer)numericValue), message);
else vMessage = replaceString("{VALUE}", (string)numericValue, message);
dialogChannel = createDialog(keyId, vMessage, buttons);
llSetTimerEvent(timerOut);
}
}

View File

@@ -0,0 +1,28 @@
Telepad Instructions
This Networked Telepad system allows you to
create teleport points throughout a region.
Its almost too easy to use.
1) Simply Rez a pad where you want a TP Point.
2) Edit the description (*not* the name) of
the object to the name of the place
(House, Pool, Skybox, etc...)
3) Click on the telepad, and choose "Reset"
from the dialog box. Only the owner can do this.
(this adds the telepad to the network)
**Important** if you move a telepad, or delete one,
you must use "Reset" to be sure all telepads receive
the changes. (Reset just the one you moved, not all of them)
To use it, touch it, choose the destination, then right
click it and choose Teleport.
** advanced configuration options **
If the description starts with a minus (for example -Beach)
then the telepad will serve as a direct telepad to that location.
To change the channel number for the network. Changet the number proceeding the colon in the
teleport pads description.
For example Beach:-99999

View File

@@ -0,0 +1,351 @@
//
// Telepad Instructions
//
// This Networked Telepad system allows you to
// create teleport points throughout a region.
// Its almost too easy to use.
//
// 1) Simply Rez a pad where you want a TP Point.
// 2) Edit the description (*not* the name) of
// the object to the name of the place
// (House, Pool, Skybox, etc...)
// 3) Click on the telepad, and choose "Reset"
// from the dialog box. Only the owner can do this.
// (this adds the telepad to the network)
//
// InWorldz and OpenSim 0.6.9 (osgrid and others) Caviat! (fixed in 0.7.1)
// Don't rotate the prim! Be sure it is set to Rotation 0,0,0
// There is a little bug that prevents the teleporter from dropping
// you off in the right place. However, when the bug is fixed, this script
// should work even with rotations, or child rotaions, unless rotations will
// be working differently than the other place. Also, if it is inside a child
// prim, it is likely to have rotation issues as well.
//
// **Important** if you move a telepad, or delete one,
// you must use "Reset" to be sure all telepads receive
// the changes. (Reset just the one you moved, not all of them)
//
// To use it, touch it, choose the destination, then right
// click it and choose Teleport.
//
// ** advanced **
// If the description starts with a minus (for example -Beach)
// then the telepad will serve as a direct telepad to that // // location.
//
// To use a special channel number for the network other
// than the default.. add colon channel number to the description.
// For example Beach:-99999
//
integer network_channel = -23423432; // default
integer dialog_channel = 0;
integer same_owner = TRUE;
integer directMode = FALSE;
float timeout = 15.0;
string myname;
list pads;
string destination;
integer collecting = FALSE;
//== dialog control stuff
// ********** DIALOG FUNCTIONS **********
// Dialog constants
integer lnkDialog = 14001;
integer lnkDialogNotify = 14004;
integer lnkDialogResponse = 14002;
integer lnkDialogTimeOut = 14003;
integer lnkDialogReshow = 14011;
integer lnkDialogCancel = 14012;
integer lnkMenuClear = 15001;
integer lnkMenuAdd = 15002;
integer lnkMenuShow = 15003;
string seperator = "||";
integer dialogTimeOut = 0;
string packDialogMessage(string message, list buttons, list returns){
string packed_message = message + seperator + (string)dialogTimeOut;
integer i;
integer count = llGetListLength(buttons);
for(i=0; i<count; i++){
string button = llList2String(buttons, i);
if(llStringLength(button) > 24) button = llGetSubString(button, 0, 23);
packed_message += seperator + button + seperator + llList2String(returns, i);
}
return packed_message;
}
dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);}
dialogCancel(){
llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY);
llSleep(1);
}
dialog(key id, string message, list buttons, list returns){
llMessageLinked(LINK_THIS, lnkDialog, packDialogMessage(message, buttons, returns), id);
}
dialogNotify(key id, string message){
list rows;
llMessageLinked(LINK_THIS, lnkDialogNotify,
message + seperator + (string)dialogTimeOut + seperator,
id);
}
// ********** END DIALOG FUNCTIONS **********
dotext()
{
string tex = "Telepad\n";
if (directMode)
{
tex += "Direct Teleport to "+myname;
llSetSitText("Teleport");
}
else
{
if (destination != "")
{
tex += "Click to go to "+destination +
"\n.\nRight-Click->Touch\nfor another Destination\n";
llSetSitText("Teleport");
}
else
{
tex += "Click to choose Destination\n";
llSetSitText(".");
}
}
llSetText(tex,<1.0,1.0,1.0>,1.0);
}
pinger()
{
if (directMode) return;
llRegionSay(network_channel,llDumpList2String(
[ myname, llGetPos(), llGetRot() ], ":"));
}
setupMenus()
{
llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
list b1;
list b2;
integer n;
integer i;
pads = llListSort(pads,3,TRUE);
n = llGetListLength(pads);
for (i = 0; i < n; i += 3)
{
b1 += [ llList2String(pads,i) ];
b2 += [ "pad," + llList2String(pads,i) ];
}
//llOwnerSay(llDumpList2String(b1,":"));
llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
"[ Networked Telepad ]\n" +
" Choose Destination",
b1 + [ " " ],
b2 + [ " " ]
), "MainMenu");
llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
"[ Networked Telepad ]\n" +
" Choose Destination",
b1 + [ "Reset" ],
b2 + [ "RESET" ]
), "OwnerMenu");
}
default
{
state_entry()
{
//llSetRot(ZERO_ROTATION);
llSetClickAction(CLICK_ACTION_TOUCH);
dotext();
string mydesc = llGetObjectDesc();
list d = llParseString2List(mydesc,[ ":" ],[]);
myname = llList2String(d,0);
if (llGetSubString(myname,0,0) == "-")
{
directMode = TRUE;
myname = llGetSubString(myname,1,-1);
dotext();
}
string altchan = llList2String(d,1);
integer n = (integer)altchan;
if (n != 0)
{
if (n > 0) n = - n;
network_channel = n;
}
if ((float)llList2String(d,2) > 0)
{
timeout = (float)llList2String(d,2);
}
if (myname == "")
{
llOwnerSay("Please name this telepad by putting a name in the objects description");
return;
}
llListen(network_channel,"",NULL_KEY,"");
llRegionSay(network_channel,"ping");
collecting = TRUE;
llSleep(0.2 + llFrand(0.3));
llSetTimerEvent(2.0);
pinger();
}
on_rez(integer num)
{
llResetScript();
}
listen(integer chan, string name, key id, string message)
{
if (same_owner)
{
key ok = llGetOwnerKey(id);
if (ok != llGetOwner()) return;
}
if (message == "ping")
{
pads = [];
llSetTimerEvent(2.0);
collecting = TRUE;
pinger();
return;
}
list v = llParseString2List(message,[ ":" ],[]);
if (llGetListLength(v) != 3) return;
string n = llList2String(v,0);
if (directMode && n != myname) return;
vector vec = (vector)llList2String(v,1);
rotation rot = (rotation)llList2String(v,2);
integer i = llListFindList(pads, [ n ]);
if (i > -1)
{
pads = llListReplaceList(pads, [ n, vec, rot ], i, i+2);
}
else
{
pads += [ n, vec, rot ];
}
if (directMode)
{
vec = ( vec - llGetPos() ) / llGetRot();
rot = rot / llGetRot();
vec.z += 1.5;
llSitTarget(vec,rot);
llSetClickAction(CLICK_ACTION_SIT);
}
else
{
collecting = TRUE;
llSetTimerEvent(2.0);
}
}
touch_start(integer num)
{
if (collecting) return;
key toucher = llDetectedKey(0);
if (toucher == llGetOwner())
{
llMessageLinked(LINK_THIS, lnkMenuShow, "OwnerMenu", llDetectedKey(0));
}
else
{
llMessageLinked(LINK_THIS, lnkMenuShow, "MainMenu", llDetectedKey(0));
}
}
timer()
{
if (collecting)
{
llSetTimerEvent(0.0);
setupMenus();
collecting = FALSE;
return;
}
llSitTarget(ZERO_VECTOR,ZERO_ROTATION);
llSetClickAction(CLICK_ACTION_TOUCH);
destination = "";
dotext();
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
llSleep(0.1);
if (llAvatarOnSitTarget() != NULL_KEY)
{
llUnSit(llAvatarOnSitTarget());
if (!directMode) llSetTimerEvent(timeout);
}
}
}
link_message(integer sender, integer num, string message, key id)
{
if(num == lnkDialogResponse)
{
integer p = llSubStringIndex(message,",");
integer s;
string cmd;
string rest;
if (p > -1)
{
cmd = llToLower(llGetSubString(message,0,p-1));
rest = llGetSubString(message,p+1,-1);
}
else
{
cmd = llToLower(message);
}
if (id == llGetOwner() && message == "RESET") llResetScript();
if (cmd == "pad")
{
integer ii = llListFindList(pads, [ rest ]);
if (ii > -1)
{
destination = rest;
vector vv = llList2Vector(pads,ii+1);
rotation rr = llList2Rot(pads,ii+2);
vv = (vv - llGetPos()) / llGetRot();
rr = rr / llGetRot();
vv.z += 1.5;
llSitTarget(vv,rr);
llSetClickAction(CLICK_ACTION_SIT);
if (!directMode) llSetTimerEvent(timeout);
dotext();
}
}
}
}
}

View File

@@ -0,0 +1,622 @@
// Variables
//Dialog Channel
integer DHandleChannel;
integer ChatHandle;
// Textures
list Textures = []; // Holds list of Texture keys
integer NumTextures; // Total Number of Backgrounds
key CurrentTexture = NULL_KEY; // Will Hold key of Current Background
list TextureGrid = [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]; // Link Numbers of Texture Grid
list EmitterGrid = [25,26,27,28,29,30]; // Link Numbers of Emitter Texture Grid
string NoTextureID = "940333d1-4838-46f2-9331-58de6e726fa6";
integer lastStartNumber;
//Poses
list Poses = []; // Hold List of Pose Names
integer NumPoses; // Hold Total Number of Poses
integer CurrentPoseIndex = 0;
key SeatedUserID;
// Lights Variables
list ColorVectors = [<0.000, 0.455, 0.851>, <0.498, 0.859, 1.000>, <0.224, 0.800, 0.800>, <0.239, 0.600, 0.439>, <0.180, 0.800, 0.251>, <0.004, 1.000, 0.439>, <1.000, 0.863, 0.000>, <1.000, 0.522, 0.106>, <1.000, 0.255, 0.212>, <0.522, 0.078, 0.294>, <0.941, 0.071, 0.745>, <0.694, 0.051, 0.788>, <1.000, 1.000, 1.000>];
list Colors = ["BLUE", "AQUA", "TEAL", "OLIVE", "GREEN", "LIME", "YELLOW", "ORANGE", "RED", "MAROON", "FUCHSIA", "PURPLE", "WHITE"];
list ColorsMenuStaticOptions = ["Custom", "Main Menu", "Next Page", "Prev Page"];
list Lights = [33,34,48,49];
list LightsMenu = ["Light On", "Light Off", "Intensity", "Color", "Radius", "FallOff", "Exit Menu", "Reset Lights"];
string CurrentSubMenu = "";
string CurrentColor = "";
vector CustomColorVector;
integer CurrentMenuPage = 0;
list IntensityMenu = ["+0.001","-0.001","+0.01","-0.01","+0.1","-0.1","Main Menu"];
list RadiusMenu = ["+0.5","-0.5","+1.0","-1.0","+5.0","-5.0","Main Menu"];
list FallOffMenu = ["+0.100","-0.100","+0.250","-0.250","Main Menu"];
integer LightsOn = FALSE;
float Intensity = 1.0;
float Radius = 10.0;
float FallOff = 0.0;
//Sit Target Variables
vector SitTarget;
// Security
list UserKeys = []; // Hold Authorized User Keys
key notecardQueryId; // Holds NoteCard Query ID
integer notecardLine; // Hold Id of Notecard Line Being Queried
list SecurityMenu = ["Owner", "Anyone", "Auth List", "Add User", "Remove User", "List Users", "Exit Menu"];
// Constants
string AuthCardName = ".users"; // Name of Notecard that Hold Names of Authorized Users (One Per line)
vector DefaultPostion = <-3.631882,-0.110687,-0.220459>;
rotation DefaultRotation = ZERO_ROTATION;
// Switches
string AuthMode = "List"; // Hold Type of Auth Mode (Owner,List,Open)
integer FireOn = FALSE;
string TimerSwitch = "";
integer CustomColor = FALSE;
integer Debug = FALSE;
//Functions
DebugMsg(string message){
if(Debug){
llOwnerSay(message);
}
}
UpdateSitLinkTarget(string direction){
list Positions = llGetLinkPrimitiveParams(51, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL]);
vector LocPos = llList2Vector(Positions, 0);
rotation LocRot = llList2Rot(Positions, 1);
if(direction=="Left"){
LocPos.y = LocPos.y - 0.1;
llSetLinkPrimitiveParamsFast(51, [PRIM_POS_LOCAL, LocPos]);
}else if(direction=="Right"){
LocPos.y = LocPos.y + 0.1;
llSetLinkPrimitiveParamsFast(51, [PRIM_POS_LOCAL, LocPos]);
}else if(direction=="Forward"){
LocPos.x = LocPos.x + 0.1;
llSetLinkPrimitiveParamsFast(51, [PRIM_POS_LOCAL, LocPos]);
}else if(direction=="Backward"){
LocPos.x = LocPos.x - 0.1;
llSetLinkPrimitiveParamsFast(51, [PRIM_POS_LOCAL, LocPos]);
}else if(direction=="Up"){
LocPos.z = LocPos.z + 0.1;
llSetLinkPrimitiveParamsFast(51, [PRIM_POS_LOCAL, LocPos]);
}else if(direction=="Down"){
LocPos.z = LocPos.z - 0.1;
llSetLinkPrimitiveParamsFast(51, [PRIM_POS_LOCAL, LocPos]);
}else if(direction=="Reset"){
llSetLinkPrimitiveParamsFast(51, [PRIM_POS_LOCAL, DefaultPostion, PRIM_ROT_LOCAL, DefaultRotation]);
}else if(direction=="RR"){
vector RotationVector = llRot2Euler(LocRot);
RotationVector.z = RotationVector.z + (-0.5 / PI);
rotation NewRot = llEuler2Rot(RotationVector);
llSetLinkPrimitiveParamsFast(51, [PRIM_ROT_LOCAL, NewRot]);
}else if(direction=="RL"){
vector RotationVector = llRot2Euler(LocRot);
RotationVector.z = RotationVector.z - (-0.5 / PI);
rotation NewRot = llEuler2Rot(RotationVector);
llSetLinkPrimitiveParamsFast(51, [PRIM_ROT_LOCAL, NewRot]);
}
}
ShowSecurityDialog(string DialogType, key userid, string addremove){
if(!ChatHandle){
ChatHandle = llListen(DHandleChannel, "", NULL_KEY, "");
}
if(DialogType=="Normal"){
llDialog(userid, "Security\n\n\t Access Modes:\n\t\tOwner Only\n\t\tAnyone\n\t\tAuthorized List\n\n\tModify List:\n\t\tAdd User\n\t\tRemove User", SecurityMenu, DHandleChannel);
}else if(DialogType=="CustomInput"){
llTextBox(userid, "Please enter the full Username of the person you with to "+addremove+" the authorized users list.", DHandleChannel);
}
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}
Security(){
llOwnerSay("Attempting to Load Authorized User Config...");
if(llGetInventoryKey(AuthCardName) == NULL_KEY){
llOwnerSay("No .users config file found!");
}else{
notecardQueryId = llGetNotecardLine(AuthCardName, notecardLine);
}
}
ChangeAuthList(string action, string username, key callinguser){
integer spaceIndex = llSubStringIndex(username, " ");
string firstName = llGetSubString(username, 0, spaceIndex - 1);
string lastName = llGetSubString(username, spaceIndex + 1, -1);
key userkey = osAvatarName2Key(firstName, lastName);
if(action=="Add"){
UserKeys = UserKeys + userkey;
llOwnerSay("Added User: "+firstName+" "+lastName+" to Authorized Users List");
}else if(action=="Remove"){
integer placeinlist = llListFindList(UserKeys, [userkey]);
if (placeinlist != -1){
UserKeys = llDeleteSubList(UserKeys, placeinlist, placeinlist);
llRegionSayTo(callinguser, 0, firstName+" "+lastName+" Removed, Loading Auth List...");
ListAuthedUsers(callinguser);
}else{
llRegionSayTo(callinguser, 0, "That user was not found in the list! Showing List...");
ListAuthedUsers(callinguser);
}
}
}
ListAuthedUsers(key id){
llRegionSayTo(id, 0, "Authorized User List:");
integer i;
for(i=0;i<=(llGetListLength(UserKeys) - 1);i++){
llRegionSayTo(id, 0, llKey2Name(llList2Key(UserKeys, i)));
}
}
UpdateLights(string status){
integer i;
string Message;
if(CustomColor){
Message = status+","+(string)CustomColorVector+","+(string)Intensity+","+(string)Radius+","+(string)FallOff;
}else{
Message = status+","+llList2String(ColorVectors, llListFindList(Colors, [CurrentColor]))+","+(string)Intensity+","+(string)Radius+","+(string)FallOff;
}
for(i=0;i<=3;i++){
llMessageLinked(llList2Integer(Lights, i), 0, Message, "");
}
}
integer CheckSecurity(key TouchedMe){
if(AuthMode=="Open"){
return TRUE;
}else if(AuthMode=="Owner"){
if(TouchedMe==llGetOwner()){
return TRUE;
}else{
llSay(0, "You are not allow to use this! Please contact Owner.");
return FALSE;
}
}else if(AuthMode=="List"){
if(llListFindList(UserKeys, [TouchedMe])!=-1){
return TRUE;
}else{
llSay(0, "You are not authorized. Please contact Owner");
return FALSE;
}
}else{
llOwnerSay("Securiy Error");
return FALSE;
}
}
LoadTextures(){
NumTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
if(NumTextures<=0){
llOwnerSay("No Backgrounds Found!");
llMessageLinked(LINK_SET, 0, "NOBG", "");
return;
}
integer i;
for(i=0;i<NumTextures;i++){
//llOwnerSay("Found Texture: "+llGetInventoryName(INVENTORY_TEXTURE, i));
Textures = Textures + llGetInventoryKey(llGetInventoryName(INVENTORY_TEXTURE, i));
}
llOwnerSay("Total # Backgrounds: "+llGetListLength(Textures));
}
LoadPoses(){
NumPoses = llGetInventoryNumber(INVENTORY_ANIMATION);
if(NumPoses<=0){
llOwnerSay("No Poses Found!");
llMessageLinked(LINK_SET, 0, "NOPOSE", "");
return;
}
integer i;
for(i=0;i<NumPoses;i++){
Poses = Poses + [llGetInventoryName(INVENTORY_ANIMATION, i)];
}
llOwnerSay("Total # Poses: "+llGetListLength(Poses));
}
integer Initialize(){
llOwnerSay("Starting Photo Studio...");
DHandleChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
LoadTextures();
Security();
SetLinkSitTarget();
LoadPoses();
return TRUE;
}
SetLinkSitTarget(){
llSetSitText("Pose");
llLinkSitTarget(51, <0.0,0.0,1.2>, ZERO_ROTATION);
}
// Texture Grid Functions
UpdateGrid(integer startnum){
integer i;
integer NumOnGrid = llGetListLength(TextureGrid) - 1;
string TextureID;
for(i=0;i<=NumOnGrid;i++){
TextureID = llList2String(Textures, startnum);
startnum++;
integer CurrentLinkID = llList2Integer(TextureGrid, i);
if(TextureID!=""){
llSetLinkPrimitiveParamsFast(CurrentLinkID, [
PRIM_TEXTURE, 0, TextureID, <1.0, 1.0, 0.0>, ZERO_VECTOR,0.0,
PRIM_FULLBRIGHT, 0, TRUE]);
lastStartNumber = startnum;
}else{
startnum = 0;
lastStartNumber = 0;
}
}
}
ChangePose(string Direction){
if(Direction=="Next"){
llStopAnimation(llList2String(Poses, CurrentPoseIndex));
CurrentPoseIndex++;
if(llList2String(Poses, CurrentPoseIndex)==""){
CurrentPoseIndex = 0;
}
llStartAnimation(llList2String(Poses, CurrentPoseIndex));
}else if(Direction=="Prev"){
llStopAnimation(llList2String(Poses, CurrentPoseIndex));
CurrentPoseIndex--;
if(llList2String(Poses, CurrentPoseIndex)==""){
CurrentPoseIndex = llGetListLength(Poses) - 1;
}
llStartAnimation(llList2String(Poses, CurrentPoseIndex));
}
llSay(0, "New Pose: "+llList2String(Poses, CurrentPoseIndex));
}
default
{
on_rez(integer start_params){
llResetScript();
}
state_entry()
{
if(Initialize()){
llOwnerSay("Initialization Complete");
UpdateGrid(0);
}
}
changed(integer change){
if(change & CHANGED_INVENTORY){
TimerSwitch = "Inventory";
llSetTimerEvent(5.0);
}
if(change & CHANGED_LINK){
SeatedUserID = llAvatarOnLinkSitTarget(51);
if(SeatedUserID!=NULL_KEY){ // Someone is Sitting
llRequestPermissions(SeatedUserID, PERMISSION_TRIGGER_ANIMATION);
}else{ // Someone Just Stood Up
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION){
llStopAnimation(llList2String(Poses, CurrentPoseIndex));
}
}
}
}
run_time_permissions(integer perms){
llStopAnimation("sit");
llSay(0, "Starting Pose: "+llList2String(Poses, CurrentPoseIndex));
llStartAnimation(llList2String(Poses, CurrentPoseIndex));
}
touch(integer num){
key WhoTouched = llDetectedKey(0);
integer WhatTouched = llDetectedLinkNumber(0);
integer authok = CheckSecurity(WhoTouched);
if(!authok){
return;
}
if(llDetectedLinkNumber(0)==LINK_ROOT){
vector TouchedPos = llDetectedTouchST(0); // Get Click Position
if(TouchedPos.x >= 0.14 && TouchedPos.x <= 0.185 && TouchedPos.y <= 0.248 && TouchedPos.y >= 0.103){ // Left Texture Change Button
UpdateGrid((lastStartNumber + 21));
}else if(TouchedPos.x >= 0.21 && TouchedPos.x <= 0.26 && TouchedPos.y <= 0.248 && TouchedPos.y >= 0.103){ // Right Texture Change Button
UpdateGrid((lastStartNumber - 21));
}else if(TouchedPos.x >= 0.669 && TouchedPos.x <= 0.733 && TouchedPos.y <= 0.68 && TouchedPos.y >= 0.57){ // Fire On/Off Button
if(FireOn){
llSetLinkAlpha(47, 1.0, 1);
llRegionSayTo(WhoTouched, 0, "Fire Off");
}else{
llSetLinkAlpha(47, 0.0, 1);
llRegionSayTo(WhoTouched, 0, "Fire On");
}
FireOn = !FireOn;
}else if(TouchedPos.x >= 0.669 && TouchedPos.x <= 0.733 && TouchedPos.y <= 0.539 && TouchedPos.y >= 0.421){ // Lights Menu Button
ChatHandle = llListen(DHandleChannel, "", NULL_KEY, "");
llDialog(WhoTouched, "Lighting Controls", LightsMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(TouchedPos.x >= 0.379 && TouchedPos.x <= 0.457 && TouchedPos.y <= 0.187 && TouchedPos.y >= 0.045){ // Pose Scroll Left
ChangePose("Next");
}else if(TouchedPos.x >= 0.661 && TouchedPos.x <= 0.734 && TouchedPos.y <= 0.194 && TouchedPos.y >= 0.056){ // Pose Scroll Right
ChangePose("Prev");
}else if(TouchedPos.x >= 0.686 && TouchedPos.x <= 0.728 && TouchedPos.y <= 0.938 && TouchedPos.y >= 0.780){ // Pose Scroll Right
ShowSecurityDialog("Normal", WhoTouched, "");
}
}else if(llListFindList(TextureGrid, WhatTouched)!=-1){ // If Prim Touched was a Texture Grid Prim
list Texture = llGetLinkPrimitiveParams(WhatTouched, [PRIM_TEXTURE, 0]);
//Lower
llSetLinkPrimitiveParamsFast(50, [
PRIM_TEXTURE, 0, llList2String(Texture, 0), <1.000000,0.351709,0.000000>, <0.000000,-0.324137,0.000000>, 1.570796,
PRIM_FULLBRIGHT, 0, TRUE]);
//Curve
llSetLinkPrimitiveParamsFast(32, [
PRIM_TEXTURE, 2, llList2String(Texture, 0), <-1.000000,0.681924,0.000000>, <0.000000,0.124485,0.000000>, 1.570796,
PRIM_FULLBRIGHT, 0, TRUE]);
//Upper
llSetLinkPrimitiveParamsFast(46, [
PRIM_TEXTURE, 2, llList2String(Texture, 0), <1.000000,0.494858,0.000000>, <0.000000,0.252571,0.000000>, 0.0,
PRIM_FULLBRIGHT, 0, TRUE]);
}else if(llListFindList(EmitterGrid, WhatTouched)!=-1){ // If Prim Touched was a Emitter Grid Prim
list ToEmit = llGetLinkPrimitiveParams(WhatTouched, [PRIM_TEXTURE, 0]);
llRegionSayTo(WhoTouched, 0, "Emitters Toggled");
llMessageLinked(LINK_SET, 0, llList2String(ToEmit, 0), NULL_KEY);
}else if(llDetectedLinkNumber(0)==2){ // If Prim Touched was the Pose Circle Menu
vector TouchedPos = llDetectedTouchST(0); // Get Click Position
if(TouchedPos.x >= 0.348 && TouchedPos.x <= 0.651 && TouchedPos.y <= 0.206 && TouchedPos.y >= 0.022){ // Move Avatar Left
UpdateSitLinkTarget("Left");
}else if(TouchedPos.x >= 0.348 && TouchedPos.x <= 0.651 && TouchedPos.y <= 0.957 && TouchedPos.y >= 0.766){ // Move Avatar Right
UpdateSitLinkTarget("Right");
}else if(TouchedPos.x >= 0.033 && TouchedPos.x <= 0.228 && TouchedPos.y <= 0.639 && TouchedPos.y >= 0.336){ // Move Avatar Up
UpdateSitLinkTarget("Up");
}else if(TouchedPos.x >= 0.777 && TouchedPos.x <= 0.996 && TouchedPos.y <= 0.642 && TouchedPos.y >= 0.336){ // Move Avatar Down
UpdateSitLinkTarget("Down");
}else if(TouchedPos.x >= 0.581 && TouchedPos.x <= 0.716 && TouchedPos.y <= 0.530 && TouchedPos.y >= 0.258){ // Move Avatar Forward
UpdateSitLinkTarget("Forward");
}else if(TouchedPos.x >= 0.270 && TouchedPos.x <= 0.416 && TouchedPos.y <= 0.696 && TouchedPos.y >= 0.429){ // Move Avatar Backward
UpdateSitLinkTarget("Backward");
}else if(TouchedPos.x >= 0.680 && TouchedPos.x <= 0.861 && TouchedPos.y <= 0.849 && TouchedPos.y >= 0.687){ // Move Avatar Rotate Right
UpdateSitLinkTarget("RR");
}else if(TouchedPos.x >= 0.144 && TouchedPos.x <= 0.318 && TouchedPos.y <= 0.303 && TouchedPos.y >= 0.144){ // Move Avatar Rotate Left
UpdateSitLinkTarget("RL");
}else if(TouchedPos.x >= 0.573 && TouchedPos.x <= 0.729 && TouchedPos.y <= 0.701 && TouchedPos.y >= 0.537){ // Reset Avatar Position
llRegionSayTo(WhoTouched, 0, "Resetting Avatar Position and Rotation...");
UpdateSitLinkTarget("Reset");
}
}else{ // Some Other Prim was Touched Speak It's ID
//llOwnerSay((string)llDetectedLinkNumber(0));
}
}
listen(integer chan, string sender, key id, string msg){
if(msg=="Anyone"){
AuthMode = "Open";
llRegionSayTo(id, 0, "Security mode set to: Anyone");
}else if(msg=="Auth List"){
AuthMode = "List";
llRegionSayTo(id, 0, "Security mode set to: Authorized Users List");
}else if(msg=="Owner"){
AuthMode = "Owner";
llRegionSayTo(id, 0, "Security mode set to: Owner Only");
}
if(msg=="Reset Lights"){
Intensity = 1.0;
Radius = 10.0;
FallOff = 0.0;
CustomColor = FALSE;
CurrentColor = "<1.0,1.0,1.0>";
llRegionSayTo(id, 0, "Resetting Lights...");
UpdateLights("TRUE");
}else if(msg=="Light Off"){ // Turn Lights On
llRegionSayTo(id, 0, "Turning Lights Off...");
UpdateLights("FALSE");
}else if(msg=="Light On"){ // Turn Lights Off
llRegionSayTo(id, 0, "Turning Lights On...");
UpdateLights("TRUE");
}else if(msg=="Exit Menu"){ // Exit Menu
CurrentSubMenu = "";
llListenRemove(ChatHandle);
}else if(msg=="Color"){ // Change Color
CurrentSubMenu = msg;
llRegionSayTo(id, 0, "Change Color of Lights");
integer StartIndex = (CurrentMenuPage * 7);
list DialogMenu = llList2List(Colors, StartIndex, (StartIndex + 7)) + ColorsMenuStaticOptions;
llDialog(id, "Colors", DialogMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(msg=="Intensity"){ // Change Intensity
CurrentSubMenu = msg;
llRegionSayTo(id, 0, "Change Light Intensity");
llDialog(id, "Intensity", IntensityMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(msg=="Radius"){ // Change Effective Radius
CurrentSubMenu = msg;
llRegionSayTo(id, 0, "Change Light Radius");
llDialog(id, "Radius", RadiusMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(msg=="FallOff"){ // Change Effective Radius
CurrentSubMenu = msg;
llRegionSayTo(id, 0, "Change Light Fall Off");
llDialog(id, "FallOff", FallOffMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(msg=="Add User"){ // Prompt User for Persons Name to add to Authorized User List
CurrentSubMenu = msg;
ShowSecurityDialog("CustomInput", id, "Add to");
}else if(msg=="Remove User"){ // Prompt User for Persons Name to remove from Authorized User List
CurrentSubMenu = msg;
ShowSecurityDialog("CustomInput", id, "Remove from");
}else if(msg=="List Users"){ // Prompt User for Persons Name to remove from Authorized User List
CurrentSubMenu = "";
llSetTimerEvent(0);
llRegionSayTo(id, 0, "Listing Authorized Users...");
ListAuthedUsers(id);
}else if(CurrentSubMenu == "Color"){ // If we are processing a response from the Colors Sub Menu
if(msg=="Next Page"){
CurrentMenuPage++;
integer StartIndex = (CurrentMenuPage * 7);
list DialogMenu = llList2List(Colors, StartIndex, (StartIndex + 7)) + ColorsMenuStaticOptions;
llDialog(id, "Colors", DialogMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(msg == "Prev Page"){
CurrentMenuPage--;
integer StartIndex = (CurrentMenuPage * 7);
list DialogMenu = llList2List(Colors, StartIndex, (StartIndex - 7)) + ColorsMenuStaticOptions;
llDialog(id, "Colors", DialogMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(msg == "Custom"){
CurrentSubMenu = "CustomColorVector";
llTextBox(id, "Please Enter a Valid Color Vector\nIn the format of: <128,128,128>\n\n Note: Submit Empty Value to return Menu", DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(msg == "Main Menu"){
CurrentSubMenu = msg;
CurrentMenuPage = 0;
llDialog(id, "Lighting Controls", LightsMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(llListFindList(Colors, [msg])!=-1){
CustomColor = FALSE;
string ColorVector = llList2String(ColorVectors, llListFindList(Colors, [msg]));
CurrentColor = msg;
UpdateLights("TRUE");
llListenRemove(ChatHandle);
}
}else if(CurrentSubMenu=="CustomColorVector"){
if(msg==""){
CurrentSubMenu = "Color";
integer StartIndex = (CurrentMenuPage * 7);
list DialogMenu = llList2List(Colors, StartIndex, (StartIndex + 7)) + ColorsMenuStaticOptions;
llOwnerSay((string)llGetListLength(DialogMenu));
llDialog(id, "Colors", DialogMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else{
vector NewColor = msg;
if(NewColor.x <= 255 && NewColor.x >=0 && NewColor.y <= 255 && NewColor.y >= 0 && NewColor.z <= 255 && NewColor.z >= 0){ // Valid Input Vector
CustomColor = TRUE;
CustomColorVector = NewColor;
UpdateLights("TRUE");
}else{ // InValid Input Vector
CustomColor = FALSE;
llRegionSayTo(id, 0, "Invalid Input Vector. Please Try Again");
CurrentSubMenu = "CustomColorVector";
llTextBox(id, "Please Enter a Valid Color Vector\nIn the format of: <128,128,128>\n\n Note: Submit Empty Value to return Menu", DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}
}
}else if(CurrentSubMenu=="Intensity"){
if(msg=="Main Menu"){
CurrentSubMenu = msg;
CurrentMenuPage = 0;
llDialog(id, "Lighting Controls", LightsMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(llListFindList(IntensityMenu, [msg]) != -1){
string mathOP = llGetSubString(msg, 0, 0);
string AdjAmount = llGetSubString(msg, 1, -1);
if(mathOP=="-"){
Intensity = Intensity - (float)AdjAmount;
}else if(mathOP=="+"){
Intensity = Intensity + (float)AdjAmount;
}
UpdateLights("TRUE");
llDialog(id, "Intensity", IntensityMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(0);
llSetTimerEvent(30.0);
}
}else if(CurrentSubMenu=="Radius"){
if(msg=="Main Menu"){
CurrentSubMenu = msg;
CurrentMenuPage = 0;
llDialog(id, "Lighting Controls", LightsMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(llListFindList(RadiusMenu, [msg]) != -1){
string mathOP = llGetSubString(msg, 0, 0);
string AdjAmount = llGetSubString(msg, 1, -1);
if(mathOP=="-"){
Radius = Radius - (float)AdjAmount;
}else if(mathOP=="+"){
Radius = Radius + (float)AdjAmount;
}
UpdateLights("TRUE");
llDialog(id, "Radius", RadiusMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(0);
llSetTimerEvent(30.0);
}
}else if(CurrentSubMenu=="FallOff"){
if(msg=="Main Menu"){
CurrentSubMenu = msg;
CurrentMenuPage = 0;
llDialog(id, "Lights Menu", LightsMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(30.0);
}else if(llListFindList(FallOffMenu, [msg]) != -1){
string mathOP = llGetSubString(msg, 0, 0);
string AdjAmount = llGetSubString(msg, 1, -1);
if(mathOP=="-"){
FallOff = FallOff + (float)AdjAmount;
}else if(mathOP=="+"){
FallOff = FallOff - (float)AdjAmount;
}
UpdateLights("TRUE");
llDialog(id, "FallOff", FallOffMenu, DHandleChannel);
TimerSwitch = "DialogTimeOut";
llSetTimerEvent(0);
llSetTimerEvent(30.0);
}
}else if(CurrentSubMenu=="Remove User"){ // Receiving Name of User to Remove from Security Tab
ChangeAuthList("Remove", msg, id);
}else if(CurrentSubMenu=="Add User"){ // Receiving Name of User to Add to Security Tab
ChangeAuthList("Add", msg, id);
}
}
timer(){
if(TimerSwitch=="Inventory"){
llOwnerSay("Inventory Change Detected... Reloading...");
llResetScript();
}else if(TimerSwitch=="DialogTimeOut"){
llSay(0, "No Respose received to Dialog, Closing Listener...");
llListenRemove(ChatHandle);
TimerSwitch = "";
llSetTimerEvent(0);
}
}
dataserver(key query_id, string data)
{
if (query_id == notecardQueryId)
{
if (data == EOF)
llOwnerSay("Done reading notecard, read " + (string) notecardLine + " notecard lines.");
else
{
// bump line number for reporting purposes and in preparation for reading next line
++notecardLine;
integer spaceIndex = llSubStringIndex(data, " ");
string firstName = llGetSubString(data, 0, spaceIndex - 1);
string lastName = llGetSubString(data, spaceIndex + 1, -1);
UserKeys = UserKeys + osAvatarName2Key(firstName, lastName);
llOwnerSay("Added User: "+firstName+" "+lastName);
notecardQueryId = llGetNotecardLine(AuthCardName, notecardLine);
}
}
}
}

View File

@@ -0,0 +1,91 @@
// Keknehv's Particle Script v1.2
// 1.0 -- 5/30/05
// 1.1 -- 6/17/05
// 1.2 -- 9/22/05 (Forgot PSYS_SRC_MAX_AGE)
// This script may be used in anything you choose, including and not limited to commercial products.
// Just copy the MakeParticles() function; it will function without any other variables in a different script
// ( You can, of course, rename MakeParticles() to something else, such as StartFlames() )
// This script is basically an llParticleSystem() call with comments and formatting. Change any of the values
// that are listed second to change that portion. Also, it is equipped with a touch-activated off button,
// for when your particles go haywire and cause everyone to start yelling at you.
// Contact Keknehv Psaltery if you have questions or comments.
MakeParticles() //This is the function that actually starts the particle system.
{
llParticleSystem([ //KPSv1.0
PSYS_PART_FLAGS , 0 //Comment out any of the following masks to deactivate them
| PSYS_PART_BOUNCE_MASK //Bounce on object's z-axis
| PSYS_PART_WIND_MASK //Particles are moved by wind
| PSYS_PART_INTERP_COLOR_MASK //Colors fade from start to end
| PSYS_PART_INTERP_SCALE_MASK //Scale fades from beginning to end
| PSYS_PART_FOLLOW_SRC_MASK //Particles follow the emitter
| PSYS_PART_FOLLOW_VELOCITY_MASK //Particles are created at the velocity of the emitter
//| PSYS_PART_TARGET_POS_MASK //Particles follow the target
| PSYS_PART_EMISSIVE_MASK //Particles are self-lit (glow)
//| PSYS_PART_TARGET_LINEAR_MASK //Undocumented--Sends particles in straight line?
,
//PSYS_SRC_TARGET_KEY , NULL_KEY, //Key of the target for the particles to head towards
//This one is particularly finicky, so be careful.
//Choose one of these as a pattern:
//PSYS_SRC_PATTERN_DROP Particles start at emitter with no velocity
//PSYS_SRC_PATTERN_EXPLODE //Particles explode from the emitter
//PSYS_SRC_PATTERN_ANGLE Particles are emitted in a 2-D angle
//PSYS_SRC_PATTERN_ANGLE_CONE Particles are emitted in a 3-D cone
//PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY Particles are emitted everywhere except for a 3-D cone
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE
,PSYS_SRC_TEXTURE, "Bling" //UUID of the desired particle texture, or inventory name
,PSYS_SRC_MAX_AGE, 0.0 //Time, in seconds, for particles to be emitted. 0 = forever
,PSYS_PART_MAX_AGE, 3.0 //Lifetime, in seconds, that a particle lasts
,PSYS_SRC_BURST_RATE, 0.5 //How long, in seconds, between each emission
,PSYS_SRC_BURST_PART_COUNT, 2 //Number of particles per emission
,PSYS_SRC_BURST_RADIUS, 5.0 //Radius of emission
,PSYS_SRC_BURST_SPEED_MIN, 1.0 //Minimum speed of an emitted particle
,PSYS_SRC_BURST_SPEED_MAX, 2.0 //Maximum speed of an emitted particle
,PSYS_SRC_ACCEL, <0.0,0.0,-0.8> //Acceleration of particles each second
,PSYS_PART_START_COLOR, <1.0,0.0,1.0> //Starting RGB color
,PSYS_PART_END_COLOR, <1.0,1.0,1.0> //Ending RGB color, if INTERP_COLOR_MASK is on
,PSYS_PART_START_ALPHA, 1.0 //Starting transparency, 1 is opaque, 0 is transparent.
,PSYS_PART_END_ALPHA, 1.0 //Ending transparency
,PSYS_PART_START_SCALE, <0.05,0.05,0.0> //Starting particle size
,PSYS_PART_END_SCALE, <0.1,0.1,0.0> //Ending particle size, if INTERP_SCALE_MASK is on
,PSYS_SRC_ANGLE_BEGIN, PI //Inner angle for ANGLE patterns
,PSYS_SRC_ANGLE_END, PI //Outer angle for ANGLE patterns
,PSYS_SRC_OMEGA, <0.0,0.0,0.0> //Rotation of ANGLE patterns, similar to llTargetOmega()
]);
}
default
{
state_entry()
{
MakeParticles(); //Start making particles
}
touch_start( integer num ) //Turn particles off when touched
{
state off; //Switch to the off state
}
}
state off
{
state_entry()
{
llParticleSystem([]); //Stop making particles
}
touch_start( integer num ) //Turn particles back on when touched
{
state default;
}
on_rez(integer num_param)
{
llResetScript();
}
}

View File

@@ -0,0 +1,565 @@
// Default Program FrameWork
/*
Replace this Section with Program Specific Information
*/
// Created by Tech Guy of IO
// Configuration Directives
/* This Section Contains Configuration Variables that will contain data set by reading the notecard specified by ConfigFile Variable */
// Communication Channels
integer MenuComChannel; // Menu Communications Channel for All User Dialog Communications
integer ComChannel; // General Communication Channel for Inter-Device Communication
// System Variables
/* This Section contains variables that will be used throughout the program. */
// Admin ACL
list Admins = []; // List of Administrator Keys Read in from ConfigFile
// Communication Handles
integer MenuComHandle; // Menu Communications Handle
integer ComHandle; // General Communications Handle
// Config Card Reading Variables
integer cLine; // Holds Configuration Line Index for Loading Config Loop
key cQueryID; // Holds Current Configuration File Line during Loading Loop
// System Constants
/* This Section contains constants used throughout the program */
string BootMessage = "Booting..."; // Default/Initial Boot Message
string ConfigFile = ".config"; // Name of Configuration File
string EMPTY = "";
string SecurityKey;
list Wings;
integer Floors;
string CurrentWing;
list Units;
integer CurUnitID;
integer CurPayPrice;
list CurUnitData;
integer CurrentYear = 2015;
// Color Vectors
list colorsVectors = [<0.000, 0.455, 0.851>, <0.498, 0.859, 1.000>, <0.224, 0.800, 0.800>, <0.239, 0.600, 0.439>, <0.180, 0.800, 0.251>, <0.004, 1.000, 0.439>, <1.000, 0.522, 0.106>, <1.000, 0.255, 0.212>, <0.522, 0.078, 0.294>, <0.941, 0.071, 0.745>, <0.694, 0.051, 0.788>, <1.000, 1.000, 1.000>];
// List of Names for Colors
list colors = ["BLUE", "AQUA", "TEAL", "OLIVE", "GREEN", "LIME", "ORANGE", "RED", "MAROON", "FUCHSIA", "PURPLE", "WHITE"];
// XyText Cell Com Numbers
integer CA1 = 281000;
integer CA2 = 282000;
integer CA3 = 283000;
integer CA4 = 284000;
integer CB1 = 285000;
integer CB2 = 286000;
integer CB3 = 287000;
integer CB4 = 288000;
integer CC1 = 289000;
integer CC2 = 290000;
integer CC3 = 291000;
integer CC4 = 292000;
// Display Prim and Face IDs
integer DisplayPrim = 14;
integer DisplayFace = 4;
// System Switches
/* This Section contains variables representing switches (integer(binary) yes/no) or modes (string "modename" */
// Debug Mode Swtich
integer DebugMode = FALSE; // Is Debug Mode Enabled before Reading Obtaining Configuation Information
// Imported Functions
/* This section contains any functions that were not written by Tech Guy */
list uUnix2StampLst( integer vIntDat ){
if (vIntDat / 2145916800){
vIntDat = 2145916800 * (1 | vIntDat >> 31);
}
integer vIntYrs = 1970 + ((((vIntDat %= 126230400) >> 31) + vIntDat / 126230400) << 2);
vIntDat -= 126230400 * (vIntDat >> 31);
integer vIntDys = vIntDat / 86400;
list vLstRtn = [vIntDat % 86400 / 3600, vIntDat % 3600 / 60, vIntDat % 60];
if (789 == vIntDys){
vIntYrs += 2;
vIntDat = 2;
vIntDys = 29;
}else{
vIntYrs += (vIntDys -= (vIntDys > 789)) / 365;
vIntDys %= 365;
vIntDys += vIntDat = 1;
integer vIntTmp;
while (vIntDys > (vIntTmp = (30 | (vIntDat & 1) ^ (vIntDat > 7)) - ((vIntDat == 2) << 1))){
++vIntDat;
vIntDys -= vIntTmp;
}
}
return [vIntYrs, vIntDat, vIntDys] + vLstRtn;
}
/*//-- Anti-License Text --//*/
/*// Contributed Freely to the Public Domain without limitation. //*/
/*// 2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/
/*//--
// Home-Brew Functions
/* This section contains any functions that were written by Tech Guy */
// Debug Message Function
DebugMessage(string msg){
if(DebugMode){
llOwnerSay(msg);
}
}
// Send Any User a Message
SendMessage(string msg, key userid){
if(userid=="NULL_KEY" || userid==""){
//llSay(0, msg);
llRegionSay(0, msg);
}else if(msg!="" && userid!=NULL_KEY){
//llInstantMessage(userid, msg);
llRegionSayTo(userid, 0, msg);
}else{
DebugMessage("Error Sending User Message: "+msg);
}
}
// Convert Input (S)ColorName to (V)Color
vector Color2Vector(string ColorName){
integer VectorIndex = llListFindList(colors, [llToUpper(ColorName)]);
vector Color;
if(VectorIndex==-1){
Color = ZERO_VECTOR;
}else{
Color = llList2Vector(colorsVectors, VectorIndex);
}
return Color;
}
// Main Initialization Logic, Executed Once Upon Script Start
Initialize(){
SendMessage(BootMessage, llGetOwner()); // State Booting Message
MenuComChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0); // Randomize Dialog Com Channel
SendMessage("Configuring...", llGetOwner()); // Message Owner that we are starting the Configure Loop
cQueryID = llGetNotecardLine(ConfigFile, cLine); // Start the Read from Config Notecard
}
// System has started Function (Runs After Configuration is Loaded, as a result of EOF)
SystemStart(){
SendMessage("System Started!", llGetOwner());
CurUnitID = 0;
//llSetTimerEvent(300.0);
UpdateUnitInfo("", (string)CurUnitID, NULL_KEY);
llSetTimerEvent(10.0);
}
// Add Admin (Add provided Legacy Name to Admins List after extrapolating userKey)
AddAdmin(string LegacyName){
string FName = llList2String(llParseString2List(LegacyName, [" "], []), 0);
string LName = llList2String(llParseString2List(LegacyName, [" "], []), 1);
DebugMessage("First Name: "+FName+" Last Name: "+LName);
key UserKey = osAvatarName2Key(FName, LName);
if(UserKey!=NULL_KEY){
Admins = Admins + UserKey;
DebugMessage("Added Admin: "+LegacyName);
}else{
DebugMessage("Unable to Resolve: "+LegacyName);
}
}
// Update Stats
UpdateUnitInfo(string UnitName, string UnitIndex, key WhoTouched){
list UnitData;
integer CurUnitIndex;
if(UnitName!=""){
CurUnitIndex = llListFindList(Units, [UnitName]);
}else if(UnitIndex!=""){
CurUnitIndex = ((integer)UnitIndex * 10);
if(CurUnitIndex==1){
CurUnitIndex--;
}
//llOwnerSay("Inex: "+(string)CurUnitIndex);
}
UnitData = llList2List(Units, CurUnitIndex, (CurUnitIndex + 9));
CurUnitData = UnitData;
// Set Price to make board payable if unit is available
if(llList2String(UnitData, 5)=="FALSE" || (llList2String(UnitData, 5)=="TRUE" && llList2Key(UnitData, 6) == WhoTouched)){
//llOwnerSay("Path1");
CurPayPrice = llList2Integer(UnitData, 1);
if(CurPayPrice>0){
llSetPayPrice(CurPayPrice, [ CurPayPrice, (CurPayPrice * 2), (CurPayPrice * 3), (CurPayPrice * 4)]);
}
llMessageLinked(LINK_SET, 0, "green", "");
}else if(llList2String(UnitData, 5)=="TRUE"){
//llOwnerSay(llList2String(UnitData, 5));
llSetPayPrice(PAY_HIDE, [ PAY_HIDE, PAY_HIDE, PAY_HIDE, PAY_HIDE ]);
llMessageLinked(LINK_SET, 0, "red", "");
}
//llOwnerSay(llDumpList2String(UnitData, "||"));
// Update Display Text
string DisplayUnitName;
if(llStringLength(llList2String(UnitData, 0))==2){
DisplayUnitName = llList2String(UnitData, 0)+" ";
}else{
DisplayUnitName = llList2String(UnitData, 0)+" ";
}
string DisplayString;
if(llStringLength(llList2String(UnitData, 8))==3){
DisplayString = "Unit: "+DisplayUnitName+" Prims: "+llList2String(UnitData, 8)+" Price: "+llList2String(UnitData, 1)+"wk ";
}else{
DisplayString = "Unit: "+DisplayUnitName+" Prims: "+llList2String(UnitData, 8)+"Price: "+llList2String(UnitData, 1)+"wk ";
}
if(llList2String(UnitData, 5)=="FALSE"){
DisplayString = DisplayString + "Available ";
}else{
DisplayString = DisplayString + "UnAvailable";
}
DisplayString = DisplayString + "Expires: ";
integer InputExpireTimeStamp = llList2Integer(UnitData, 7);
if(InputExpireTimeStamp==0){
DisplayString = DisplayString + "12 Weeks 6 Days";
}else{
list TimeList = uUnix2StampLst(InputExpireTimeStamp);
DisplayString = DisplayString + " " + (string)(llList2Integer(TimeList, 0) + (CurrentYear - llList2Integer(TimeList, 0))) + "/" + llList2String(TimeList, 1) + "/" + llList2String(TimeList, 2);
//llOwnerSay(DisplayString);
}
//llOwnerSay("T"+(string)llStringLength(DisplayString));
//llOwnerSay(DisplayString);
llMessageLinked(LINK_SET, CA1, llGetSubString(DisplayString, 0, 5), "''''");
llMessageLinked(LINK_SET, CA2, llGetSubString(DisplayString, 6, 11), "''''");
llMessageLinked(LINK_SET, CA3, llGetSubString(DisplayString, 12, 17), "''''");
llMessageLinked(LINK_SET, CA4, llGetSubString(DisplayString, 18, 23), "''''");
llMessageLinked(LINK_SET, CB1, llGetSubString(DisplayString, 24, 29), "''''");
llMessageLinked(LINK_SET, CB2, llGetSubString(DisplayString, 30, 35), "''''");
llMessageLinked(LINK_SET, CB3, llGetSubString(DisplayString, 36, 41), "''''");
llMessageLinked(LINK_SET, CB4, llGetSubString(DisplayString, 42, 47), "''''");
llMessageLinked(LINK_SET, CC1, llGetSubString(DisplayString, 48, 53), "''''");
llMessageLinked(LINK_SET, CC2, llGetSubString(DisplayString, 54, 60), "''''");
llMessageLinked(LINK_SET, CC3, llGetSubString(DisplayString, 61, 66), "''''");
llMessageLinked(LINK_SET, CC4, llGetSubString(DisplayString, 67, -1), "''''");
// Update Main Texture Display and Buffer Display
llSetLinkPrimitiveParamsFast(DisplayPrim, [PRIM_TEXTURE, DisplayFace, llList2String(UnitData, 9), <1.0,1.0,1.0>, ZERO_VECTOR, 0.0]);
}
// Configuration Directives Processor (Called Each Time a Line is Found in the config File)
LoadConfig(string data){
if(data!=""){ // If Line is not Empty
// if the line does not begin with a comment
if(llSubStringIndex(data, "#") != 0)
{
// find first equal sign
integer i = llSubStringIndex(data, "=");
// if line contains equal sign
if(i != -1){
// get name of name/value pair
string name = llGetSubString(data, 0, i - 1);
// get value of name/value pair
string value = llGetSubString(data, i + 1, -1);
// trim name
list temp = llParseString2List(name, [" "], []);
name = llDumpList2String(temp, " ");
// make name lowercase
name = llToLower(name);
// trim value
temp = llParseString2List(value, [" "], []);
value = llDumpList2String(temp, " ");
// Check Key/Value Pairs and Set Switches and Lists
if(name=="debugmode"){ // Check DeBug Mode
if(value=="TRUE" || value=="true"){
DebugMode = TRUE;
llOwnerSay("Debug Mode: Enabled!");
}else if(value=="FALSE" || value=="false"){
DebugMode = FALSE;
llOwnerSay("Debug Mode: Disabled!");
}
}else if(name=="comchannel"){
ComChannel = (integer)value;
DebugMessage("Com Channel: "+(string)ComChannel);
}else if(name=="securitykey"){
SecurityKey = value;
DebugMessage("Security Key: "+SecurityKey);
}else if(name=="admin"){
AddAdmin(value);
}else if(name=="wings"){
Wings = llCSV2List(value);
CurrentWing = llList2String(Wings, 0);
DebugMessage("Wings: "+llDumpList2String(Wings, " & "));
}else if(name=="floors"){
Floors = (integer)value;
DebugMessage("Total Number of Floors Per Wing: "+(string)Floors);
}
}else{ // line does not contain equal sign
SendMessage("Configuration could not be read on line " + (string)cLine, NULL_KEY);
}
}
}
}
// Get Unit Configuration Information from the Server
GetServerConfig(){
if(ComHandle<=0){ // Need to Open Com Handle
DebugMessage("Opening Com Channel "+(string)ComChannel+"...");
ComHandle = llListen(ComChannel, EMPTY, EMPTY, EMPTY);
}
integer count = 0;
string GetConfigCmd;
DebugMessage("Calling Server...");
for(count=0;count<=Floors;count++){
GetConfigCmd = "GETCONFIG||"+count+llToUpper(CurrentWing);
llRegionSay(ComChannel, GetConfigCmd);
if(count==Floors){
integer NumWings = llGetListLength(Wings);
integer NextWingIndex = (llListFindList(Wings, [CurrentWing]) + 1);
if(NextWingIndex>=NumWings){
count = Floors;
}else{
count = 0;
CurrentWing = llList2String(Wings, NextWingIndex);
}
}
}
}
// Validate the Servers Security Key
integer CheckServerSecurity(string InKey){
if(InKey==SecurityKey){
return TRUE;
}else{
return FALSE;
}
}
// Next / Prev Unit Display Changer
ChangeUnit(string Direction, key WhoTouched){
if(Direction=="Next"){
CurUnitID++;
if(CurUnitID>=(Floors * llGetListLength(Wings))){
CurUnitID = 0;
}
}else if(Direction=="Prev"){
if(CurUnitID==0){
CurUnitID = (Floors * llGetListLength(Wings));
CurUnitID--;
}else{
CurUnitID--;
}
}
//llOwnerSay("CurUnitID: "+(string)CurUnitID);
UpdateUnitInfo("", (string)CurUnitID, WhoTouched);
}
AnnounceUnitStateChange(list InputData){
string SendString = llDumpList2String(InputData, "||");
llRegionSay(-86000, SendString);
}
// Check for Expired Units
CheckExpires(){
integer count;
integer Start;
integer End;
list CurrentUnit;
string CurrentWing = "a";
integer CurrentTime;
for(count=1;count<=Floors;count++){
Start = llListFindList(Units, (string)count+llToUpper(CurrentWing));
End = (Start + 9);
CurrentUnit = llList2List(Units, Start, End);
CurrentTime = llGetUnixTime();
integer UnitExpiry = llList2Integer(CurrentUnit, 7);
if(CurrentTime>UnitExpiry && UnitExpiry>0){
if(llList2String(CurrentUnit, 0)=="1A" || llList2String(CurrentUnit, 0)=="1B"){
// Do Nothing
}else{
// Notify Server of Rented Unit
list SendList = [ "AVAIL" ] + CurrentUnit;
string SendString = llDumpList2String(SendList, "||");
DebugMessage("Updating Server...");
llRegionSay(ComChannel, SendString);
// Announce Change to Front Door Panels (And Anything Else we later want to listen)
AnnounceUnitStateChange(SendList);
//llOwnerSay("Expired "+llList2String(CurrentUnit, 0));
}
}
// llOwnerSay(llDumpList2String(CurrentUnit, "||"));
if(count==Floors){
integer NumWings = llGetListLength(Wings);
integer NextWingIndex = (llListFindList(Wings, [CurrentWing]) + 1);
if(NextWingIndex>=NumWings){
count = Floors;
}else{
count = 1;
CurrentWing = llList2String(Wings, NextWingIndex);
}
}
}
}
//Main Program Logic
/* This section contains the main program logic. (ie: Default State, and all event triggers) */
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
touch_start(integer num){
vector WhereTouched = llDetectedTouchST(0);
key WhoTouched = llDetectedKey(0);
//llOwnerSay("X Vector: "+(string)WhereTouched.x+" Y Vector: "+(string)WhereTouched.y);
if(WhereTouched.x>=0.0597 && WhereTouched.x<=0.3779 && WhereTouched.y>=0.5845 && WhereTouched.y<=0.6212){
ChangeUnit("Prev", WhoTouched);
}else if(WhereTouched.x>=0.6308 && WhereTouched.x<=0.9434 && WhereTouched.y>=0.5867 && WhereTouched.y<=0.6213){
ChangeUnit("Next", WhoTouched);
}
}
listen(integer channel, string sender, key id, string msg){
if(channel==ComChannel){ // Message comes from Server
list InputData = llParseString2List(msg, ["||"], []);
if(!CheckServerSecurity(llList2String(InputData, 0))){
DebugMessage("Server Security Code Invalid!\n Closing Com Handle...");
//llListenRemove(ComHandle);
//state borked;
}
string CMD = llList2String(InputData, 1);
if(CMD=="UNIT"){ // Receiving Configuration for Unit
integer UnitPropCount = llGetListLength(Units);
Units = Units + llList2List(InputData, 2, -1);
// llOwnerSay("Unit Configured:\n"+llDumpList2String(llList2List(Units, UnitPropCount, (UnitPropCount + 8)), ","));
AnnounceUnitStateChange(llList2List(InputData, 1, -1));
//llOwnerSay((string)llGetListLength(Units));
if((llGetListLength(Units) / 8)==(Floors * llGetListLength(Wings))){
llOwnerSay("Please accept debit permissions...");
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
}
}else if(channel==MenuComChannel){ // Message comes from Board Dialog Menu
}
}
run_time_permissions(integer perms){
if(perms & PERMISSION_DEBIT){
llOwnerSay("Permissions Granted! System Configured!");
SystemStart();
}
}
// DataServer Event Called for Each Line of Config NC. This Loop It was Calls LoadConfig()
dataserver(key query_id, string data){ // Config Notecard Read Function Needs to be Finished
if (query_id == cQueryID){
if (data != EOF){
LoadConfig(data); // Process Current Line
++cLine; // Increment Line Index
cQueryID = llGetNotecardLine(ConfigFile, cLine); // Attempt to Read Next Config Line (Re-Calls DataServer Event)
}else{ // IF EOF (End of Config loop, and on Blank File)
GetServerConfig();
}
}
}
changed(integer change){
if(change & CHANGED_INVENTORY){
BootMessage = "Inventory Changed Detected, Re-Initializing...";
llResetScript();
}
}
money(key Payor, integer AmountPaid){
//llOwnerSay((string)CurPayPrice+" "+(string)CurUnitID);
integer OneWeek = CurPayPrice;
integer TwoWeek = (CurPayPrice * 2);
integer ThreeWeek = (CurPayPrice * 3);
integer FourWeek = (CurPayPrice * 4);
integer Expiry;
if(AmountPaid != OneWeek && AmountPaid != TwoWeek && AmountPaid != ThreeWeek && AmountPaid != FourWeek){ // Incorrent Amount Paid
llRegionSayTo(Payor, 0, "You paid an invalid amount! Returning your money...");
llGiveMoney(Payor, AmountPaid);
return;
}else if(AmountPaid==OneWeek){
Expiry = (llGetUnixTime() + 604800);
}else if(AmountPaid==TwoWeek){
Expiry = (llGetUnixTime() + (604800 * 2));
}else if(AmountPaid==ThreeWeek){
Expiry = (llGetUnixTime() + (604800 * 3));
}else if(AmountPaid==FourWeek){
Expiry = (llGetUnixTime() + (604800 * 4));
}
llRegionSayTo(Payor, 0, "Thank you for Renting Unit: "+llList2String(CurUnitData, 0));
list ExpiryList = uUnix2StampLst(Expiry);
integer ExpYear = llList2Integer(ExpiryList, 0) + (CurrentYear - llList2Integer(ExpiryList, 0));
list Public = [ExpYear] + llList2List(ExpiryList, 1, 2);
llOwnerSay("Pre New Expire: "+llDumpList2String(CurUnitData, "||"));
list NewUnitData = llList2List(CurUnitData, 0, 4) + ["TRUE"] + [(string)Payor] + [Expiry] + llList2List(CurUnitData, 8, -1);
llOwnerSay("New Unit Data: "+llDumpList2String(NewUnitData, "||"));
llMessageLinked(LINK_SET, 0, "red", "");
integer UnitIndex = llListFindList(Units, [llList2String(NewUnitData, 0)]);
if(UnitIndex==-1){
llOwnerSay("Error Unit Not Found in List!");
state borked;
}else{
list OldUnitData = llList2List(Units, UnitIndex, (UnitIndex + 9));
llOwnerSay("Old Unit Data: "+llDumpList2String(OldUnitData, "||"));
if(llList2String(OldUnitData, 6)==Payor){
integer OldExpiry = llList2Integer(NewUnitData, 7);
if(AmountPaid==OneWeek){
Expiry = (OldExpiry + 604800);
}else if(AmountPaid==TwoWeek){
Expiry = (OldExpiry + (604800 * 2));
}else if(AmountPaid==ThreeWeek){
Expiry = (OldExpiry + (604800 * 3));
}else if(AmountPaid==FourWeek){
Expiry = (OldExpiry + (604800 * 4));
}
}
}
NewUnitData = [] + llList2List(CurUnitData, 0, 4) + ["TRUE"] + [(string)Payor] + [Expiry] + llList2List(CurUnitData, 8, -1);
llOwnerSay("New Unit Data Final: "+llDumpList2String(NewUnitData, "||"));
list Start;
list End;
if(UnitIndex==0){
Start = [];
}else{
Start = llList2List(Units, 0, (UnitIndex - 1));
}
End = llList2List(Units, (UnitIndex + 10), -1);
list NewUnits = Start + NewUnitData + End;
Units = [] + NewUnits;
// Notify Server of Rented Unit
list SendList = [ "RENTED" ] + NewUnitData;
string SendString = llDumpList2String(SendList, "||");
DebugMessage("Updating Server...");
llRegionSay(ComChannel, SendString);
// Announce Change to Front Door Panels (And Anything Else we later want to listen)
AnnounceUnitStateChange(SendList);
// Update Display Text
//llOwnerSay(llList2String(NewUnitData, 0));
UpdateUnitInfo(llList2String(NewUnitData, 0), "", Payor);
}
timer(){
CheckExpires();
}
}
state borked {
state_entry(){
llInstantMessage(llGetOwner(), llGetObjectName()+" failure!");
}
}

View File

@@ -0,0 +1,767 @@
// Game Server Relay Engine v1.0
// Created by Tech Guy
//Very Keynes - 2008 - 2009
//
// Version: OpenSimulator Server 0.6.1.7935 (interface version 2)
//
// 2009-01-06, 19:30 GMT
//
//------------------Begin VK-DBMS-VM----------------------------\\
//--------------------Introduction------------------------------\\
//
// Very Keynes - DBMS - Virtual Machine
//
// Implements a core set of registers and root functions
// to create and manage multi-table database structures as
// an LSL list. Although intended to under pin higher level
// database management tools such as VK-SQL it is usable as
// a small footprint database facility for system level
// applications.
//
//
// Naming Conventions and Code Style
//
// This Code is intended to be included as a header to user generated
// code. As such it's naming convention was selected so that it would
// minimise the possibility of duplicate names in the user code portion
// of the application. Exposed Functions and Variables are prefixed db.
//
// A full User Guide and Tutorial is availible at this URL:
//
// http://docs.google.com/Doc?id=d79kx35_26df2pbbd8
//
//
// Table Control Registers
//
integer th_; // Table Handle / Index Pointer
integer tc_; // Columns in Active Table
integer tr_; // Rows in Active Table
integer ts_; // Active Table Start Address
//
list _d_ = []; // Database File
list _i_ = [0]; // Index File
//
// Exposed Variables
//
integer dbIndex; // Active Row Table Pointer
list dbRow; // User Scratch List
string dbError; // System Error String
//
// Temporary / Working Variables
//
integer t_i;
string t_s;
float t_f;
list t_l;
//
// System Functions
//
string dbCreate(string tab, list col)
{
if(dbOpen(tab))
{
dbError = tab + " already exists";
return "";
}
tc_ = llGetListLength(col);
_i_ += [tab, tc_, 0, 0, 0];
th_= 0;
dbOpen(tab);
dbInsert(col);
return tab;
}
integer dbCol(string col)
{
return llListFindList(dbGet(0), [_trm(col)]);
}
integer dbDelete(integer ptr)
{
if(ptr > 0 && ptr < tr_)
{
t_i = ts_ + tc_ * ptr;
_d_ = llDeleteSubList(_d_, t_i, t_i + tc_ - 1);
--tr_;
return tr_ - 1;
}
else
{
dbError = (string)ptr + " is outside the Table Bounds";
return FALSE;
}
}
integer dbDrop(string tab)
{
t_i = llListFindList(_i_, [tab]);
if(-1 != t_i)
{
dbOpen(tab);
_d_ = llDeleteSubList(_d_, ts_, ts_ + tc_ * tr_ - 1);
_i_ = llDeleteSubList(_i_, th_, th_ + 4);
th_= 0;
return TRUE;
}
else
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
}
integer dbExists(list cnd)
{
for(dbIndex = tr_ - 1 ; dbIndex > 0 ; --dbIndex)
{
if(dbTest(cnd)) return dbIndex;
}
return FALSE;
}
list dbGet(integer ptr)
{
if(ptr < tr_ && ptr >= 0)
{
t_i = ts_ + tc_ * ptr;
return llList2List(_d_, t_i, t_i + tc_ - 1);
}
else
{
dbError = (string) ptr + " is outside the Table Bounds";
return [];
}
}
integer _idx(integer hdl)
{
return (integer)llListStatistics(6, llList2ListStrided(_i_, 0, hdl, 5));
}
integer dbInsert(list val)
{
if(llGetListLength(val) == tc_)
{
dbIndex = tr_++;
_d_ = llListInsertList(_d_, val, ts_ + tc_ * dbIndex);
return dbIndex;
}
else
{
dbError = "Insert Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbOpen(string tab)
{
if(th_)
{
_i_ = llListReplaceList(_i_, [tr_, dbIndex, tc_ * tr_], th_ + 2, th_ + 4);
}
t_i = llListFindList(_i_, [tab]);
if(-1 == t_i) //if tab does not exist abort
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
else if(th_ != t_i)
{
th_ = t_i++;
ts_ = _idx(th_);
tc_ = llList2Integer(_i_, t_i++);
tr_ = llList2Integer(_i_, t_i++);
dbIndex = llList2Integer(_i_, t_i);
}
return tr_ - 1;
}
integer dbPut(list val)
{
if(llGetListLength(val) == tc_)
{
t_i = ts_ + tc_ * dbIndex;
_d_ = llListReplaceList(_d_, val, t_i, t_i + tc_ - 1);
return dbIndex;
}
else
{
dbError = "Update Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbTest(list cnd)
{
if(llGetListEntryType(cnd,2) >= 3)
{
t_s = llList2String(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
if ("==" == llList2String(cnd, 1)){t_i = t_s == _trm(llList2String(cnd, 2));}
else if("!=" == llList2String(cnd, 1)){t_i = t_s != _trm(llList2String(cnd, 2));}
else if("~=" == llList2String(cnd, 1))
{t_i = !(llSubStringIndex(llToLower(t_s), llToLower(_trm(llList2String(cnd, 2)))));}
}
else
{
t_f = llList2Float(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
t_s = llList2String(cnd, 1);
if ("==" == t_s){t_i = t_f == llList2Float(cnd, 2);}
else if("!=" == t_s){t_i = t_f != llList2Float(cnd, 2);}
else if("<=" == t_s){t_i = t_f <= llList2Float(cnd, 2);}
else if(">=" == t_s){t_i = t_f >= llList2Float(cnd, 2);}
else if("<" == t_s){t_i = t_f < llList2Float(cnd, 2);}
else if(">" == t_s){t_i = t_f > llList2Float(cnd, 2);}
}
if(t_i) return dbIndex;
else return FALSE;
}
string _trm(string val)
{
return llStringTrim(val, STRING_TRIM);
}
dbTruncate(string tab)
{
dbIndex = dbOpen(tab);
while(dbIndex > 0) dbDelete(dbIndex--);
}
dbSort(integer dir)
{
t_i = ts_ + tc_;
_d_ = llListReplaceList(_d_, llListSort(llList2List(_d_, t_i, t_i + tc_ * tr_ - 2), tc_, dir), t_i, t_i + tc_ * tr_ - 2);
}
float dbFn(string fn, string col)
{
t_i = ts_ + tc_;
t_l = llList2List(_d_, t_i, t_i + tc_ * tr_ - 2);
if(dbCol(col) != 0) t_l = llDeleteSubList(t_l, 0, dbCol(col) - 1);
return llListStatistics(llSubStringIndex("ramimaavmedesusqcoge", llGetSubString(llToLower(fn),0,1)) / 2,
llList2ListStrided(t_l, 0, -1, tc_));
}
//
//--------------------------- End VK-DBMS-VM ---------------------------\\
//
// Configuration
// Constants
integer ComChannel = -63473670; // Secret Negative Channel for Server Communication
integer UnitComChannel; // Channel Used to Communicate with Furniture inside Unit
list KEYS = [ "5b8c8de4-e142-4905-a28f-d4d00607d3e9", "b9dbc6a4-2ac3-4313-9a7f-7bd1e11edf78", "dbfa0843-7f7f-4ced-83f6-33223ae57639" ];
list Admins = [];
string EMPTY = "";
key SecurityKey = "3d7b1a28-f547-4d10-8924-7a2b771739f4";
float LightHoldLength = 0.1;
string SecureRequest = "TheKeyIs(Mq=h/c2)";
string cName = ".config"; // Name of Configuration NoteCard
// Off-World Data Communication Constants
key HTTPRequestHandle; // Handle for HTTP Request
string URLBase = "http://api.orbitsystems.ca/api.php";
list HTTPRequestParams = [
HTTP_METHOD, "POST",
HTTP_MIMETYPE, "application/x-www-form-urlencoded",
HTTP_BODY_MAXLENGTH, 16384,
HTTP_CUSTOM_HEADER, "CUSKEY", "TheKeyIs(Mq=h/c2)"
];
// Indicator Light Config
float GlowOn = 0.10;
float GlowOff = 0.0;
list ONColorVectors = [<0.0,1.0,0.0>,<1.0,0.5,0.0>,<1.0,0.0,0.0>];
list ColorNames = ["Green", "Orange", "Red"];
list OFFColorVectors = [<0.0,0.5,0.0>,<0.5,0.25,0.0>,<0.5,0.0,0.0>];
integer PWRLIGHT = 2;
integer CFGLIGHT = 3;
integer INLIGHT = 4;
integer OUTLIGHT = 5;
// Variables
integer ComHandle; // Hold Handle to Control Server Com Channel
integer cLine; // Holds Configuration Line Index for Loading Config Loop
key cQueryID; // Holds Current Configuration File Line during Loading Loop
string GameName = "";
string DBName = "Units";
integer DBEntries = 0;
// Switches
integer DebugMode = TRUE; // Are we running in with Debug Messages ON?
// Flags
string OpFlag = "";
// User Database Configuration Directives
string UserUploadTimer;
// Functions
// Debug Message
DebugMessage(string message){
if(DebugMode){
llOwnerSay(message);
}
}
Initialize(){
llListenRemove(ComHandle);
llListen(ComChannel, EMPTY, EMPTY, EMPTY);
// UNITID, PRICE, DISCOUNT, MINRENT, MAXRENT, RENTED, RENTERKEY, EXPIRE
string CreatedDB = dbCreate(DBName, ["unitid", "price", "discount", "minrent", "maxrent", "rented", "renterkey", "expire", "prims", "texture"]);
if(CreatedDB==DBName && DebugMode){
llOwnerSay("Database "+DBName+" Created...");
}
DebugMessage("Configuring...");
cQueryID = llGetNotecardLine(cName, cLine);
}
SystemStart(){
llOwnerSay("System Online!");
}
LightToggle(integer LinkID, integer ISON, string Color){
if(ISON){
vector ColorVector = llList2Vector(ONColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOn,
PRIM_FULLBRIGHT, ALL_SIDES, TRUE
]);
}else{
vector ColorVector = llList2Vector(OFFColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOff,
PRIM_FULLBRIGHT, ALL_SIDES, FALSE
]);
}
}
// Add Admin (Add provided Legacy Name to Admins List after extrapolating userKey)
AddAdmin(string LegacyName){
string FName = llList2String(llParseString2List(LegacyName, [" "], []), 0);
string LName = llList2String(llParseString2List(LegacyName, [" "], []), 1);
//DebugMessage("First Name: "+FName+" Last Name: "+LName);
key UserKey = osAvatarName2Key(FName, LName);
if(UserKey!=NULL_KEY){
Admins = Admins + UserKey;
DebugMessage("Added Admin: "+LegacyName);
}else{
DebugMessage("Unable to Resolve: "+LegacyName);
}
}
// Check Security
integer CheckSecurity(key id){
if(llListFindList(Admins, [id])!=-1){
return TRUE;
}else{
return FALSE;
}
}
LoadConfig(string data){
LightToggle(CFGLIGHT, TRUE, "Orange");
if(data!=""){ // If Line is not Empty
// if the line does not begin with a comment
if(llSubStringIndex(data, "#") != 0)
{
// find first equal sign
integer i = llSubStringIndex(data, "=");
// if line contains equal sign
if(i != -1){
// get name of name/value pair
string name = llGetSubString(data, 0, i - 1);
// get value of name/value pair
string value = llGetSubString(data, i + 1, -1);
// trim name
list temp = llParseString2List(name, [" "], []);
name = llDumpList2String(temp, " ");
// make name lowercase
name = llToLower(name);
// trim value
temp = llParseString2List(value, [" "], []);
value = llDumpList2String(temp, " ");
// Check Key/Value Pairs and Set Switches and Lists
if(name=="debugmode"){
if(value=="TRUE" || value=="true"){
DebugMode = TRUE;
DebugMessage("Debug Mode: Enabled!");
}else if(value=="FALSE" || value=="false"){
DebugMode = FALSE;
llOwnerSay("Debug Mode: Disabled!");
}
}else if(name=="comchannel"){
ComChannel = (integer)value;
if(ComHandle>0){
DebugMessage("Closing Old Com Channel...");
llListenRemove(ComHandle);
ComHandle = 0;
}
DebugMessage("Opening Com Channel ("+(string)ComChannel+")...");
ComHandle = llListen(ComChannel, EMPTY, EMPTY, EMPTY);
if(ComHandle>0){
DebugMessage("Com Channel Open!");
}
}else if(name=="securitykey"){
SecurityKey = (key)value;
if(SecurityKey!=NULL_KEY){
DebugMessage("Inter Device Communications Key: "+(string)SecurityKey);
}else{
DebugMessage("Inter Device Communications Key NOT FOUND!");
}
}else if(name=="unit"){
list InputData = llParseString2List(value, ["||"], []);
string UnitID = llList2String(InputData, 0);
integer Price = llList2Integer(InputData, 1);
float Discount = llList2Float(InputData, 2);
integer MinRent = llList2Integer(InputData, 3);
integer MaxRent = llList2Integer(InputData, 4);
integer Prims = llList2Integer(InputData, 5);
key Texture = llList2Key(InputData, 6);
DebugMessage("\nNew Unit Details: \nUnit ID: "+UnitID+"\nPrice: "+(string)Price+" /wk\nDiscount: "+(integer)Discount+" %\nMin Rental Time: "+(string)MinRent+" Week(s)\nMax Rental Time: "+(string)MaxRent+" Week(s)"+"\nMax Prims: "+(string)Prims+"\nImg Texture Key: "+(string)Texture);
// UNITID, PRICE, DISCOUNT, MINRENT, MAXRENT, RENTED, RENTERKEY, EXPIRE, PRIMS, Texture
DBEntries = dbInsert([UnitID, Price, Discount, MinRent, MaxRent, "FALSE", NULL_KEY, 0, Prims, Texture]);
//DebugMessage("DBEntries: "+(string)DBEntries);
}else if(name=="admin"){
AddAdmin(value);
}else if(name=="unitcomchannel"){
UnitComChannel = (integer)value;
DebugMessage("Unit Com Channel: "+(string)UnitComChannel);
}
LightToggle(CFGLIGHT, FALSE, "Orange");
}else{ // line does not contain equal sign
llOwnerSay("Configuration could not be read on line " + (string)cLine);
}
}
}
}
// Register Server with Off-World Database System (Also Sync)
RegisterServer(string cmd, list UnitData){
if(cmd=="CheckReg"){
DebugMessage("Registering Server...");
OpFlag = cmd;
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("CheckReg")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", "Rental"];
HTTPRequestHandle = llHTTPRequest(URL, SendParams, ""); // Send Request to Server to Check and/or Register this Server
}else if(cmd=="Sync"){
DebugMessage("Syncing...");
OpFlag = cmd;
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64(OpFlag)+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", "Rental"];
string DumpString = GetData();
//llOwnerSay(DumpString);
string EncodedDumpString = llStringToBase64(DumpString);
string MessageBody = "data="+EncodedDumpString;
integer MessageBodyLength = llStringLength(MessageBody);
HTTPRequestHandle = llHTTPRequest(URL, SendParams, MessageBody); // Send Request to Server to Check and/or Register this Server
}else if(cmd=="Update"){
OpFlag = cmd;
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64(OpFlag)+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", "Rental"];
string DumpString = llDumpList2String(UnitData, "||");
//llOwnerSay(DumpString);
string EncodedDumpString = llStringToBase64(DumpString);
string MessageBody = "data="+EncodedDumpString;
integer MessageBodyLength = llStringLength(MessageBody);
HTTPRequestHandle = llHTTPRequest(URL, SendParams, MessageBody); // Send Request to Server to Check and/or Register this Server
}
}
// Get All Entires out of Database and Return them as String Formatted as such:
// {UnitID}||{Price}||{Discount}||{MinRent}||{MaxRent}||{Rented}||{RenterKey}||{Expire}||{Prims}||{Texture},
string GetData(){
dbIndex = 1;
string ReturnString = "";
for(dbIndex=1;dbIndex<=DBEntries;dbIndex++){
list CurrentLine = dbGet(dbIndex);
if(llList2String(CurrentLine, 0)==""){ return ReturnString; }
// UNITID, PRICE, DISCOUNT, MINRENT, MAXRENT, RENTED, RENTERKEY, EXPIRE, PRIMS
string UnitID = llList2String(CurrentLine, 0);
string Price = llList2String(CurrentLine, 1);
string Discount = (string)llList2Integer(CurrentLine, 2);
string MinRent = llList2String(CurrentLine, 3);
string MaxRent = llList2String(CurrentLine, 4);
string Rented = llList2String(CurrentLine, 5);
string RenterKey = llList2String(CurrentLine, 6);
string Expire = llList2String(CurrentLine, 7);
string Prims = llList2String(CurrentLine, 8);
string Texture = llList2String(CurrentLine, 9) + ",";
list TempList = [ UnitID, Price, Discount, MinRent, MaxRent, Rented, RenterKey, Expire, Prims, Texture];
string CompiledString = llDumpList2String(TempList, "||");
ReturnString = ReturnString + CompiledString;
}
return ReturnString;
}
// Prep Unit After Rental
PrepUnit(string UnitID, key Renter){
//llRegionSayTo(Renter, 0, "Setting up your Unit...");
list SendList = [ SecurityKey, "NR", UnitID, Renter ];
string SendString = llStringToBase64(llDumpList2String(SendList, "||"));
DebugMessage(SendString);
llRegionSay(ComChannel, SendString);
}
// Main Program
default{
on_rez(integer params){
//llGiveInventory(llGetOwner(), llGetInventoryName(INVENTORY_NOTECARD, 1));
llResetScript();
}
state_entry(){
LightToggle(PWRLIGHT, TRUE, "Red");
llSleep(LightHoldLength);
LightToggle(CFGLIGHT, TRUE, "Orange");
llSleep(LightHoldLength);
LightToggle(CFGLIGHT, FALSE, "Orange");
LightToggle(INLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(OUTLIGHT, FALSE, "Green");
Initialize();
}
dataserver(key query_id, string data){ // Config Notecard Read Function Needs to be Finished
if (query_id == cQueryID){
if (data != EOF){
LoadConfig(data); // Process Current Line
++cLine; // Incrment Line Index
cQueryID = llGetNotecardLine(cName, cLine); // Attempt to Read Next Config Line (Re-Calls DataServer Event)
}else{ // IF EOF (End of Config loop, and on Blank File)
LightToggle(CFGLIGHT, TRUE, "Orange");
// Check if Server is Registered with Website
RegisterServer("CheckReg", []);
}
}
}
changed(integer c){
if(c & CHANGED_INVENTORY){
llResetScript();
}
}
listen(integer chan, string cmd, key id, string data){
if(DebugMode){
llOwnerSay("Listen Event Fired!\r"+data);
}
LightToggle(INLIGHT, TRUE, "Green");
list InputData = llParseString2List(data, ["||"], []);
string CMD = llList2String(InputData, 0);
if(CMD=="GETCONFIG"){
string UnitID = llList2String(InputData, 1);
DebugMessage("Configuration Data Requested for Unit: "+UnitID);
integer IDLength = llStringLength(UnitID);
string Wing = EMPTY;
string Unit = EMPTY;
integer DBIndex;
if(IDLength==2){
Wing = llGetSubString(UnitID, 1, 1);
Unit = llGetSubString(UnitID, 0, 0);
}else if(IDLength==3){
Wing = llGetSubString(UnitID, 2, 2);
Unit = llGetSubString(UnitID, 0, 1);
}
if(llToLower(Wing)=="a"){
DBIndex = (integer)Unit;
}else if(llToLower(Wing)=="b"){
DBIndex = ((integer)Unit + (DBEntries / 2));
}else{
llOwnerSay("ERROR");
}
list UnitData = dbGet(DBIndex);
string UnitIDb = llList2String(UnitData, 0);
if(UnitID!=UnitIDb){
DebugMessage("UnitID: "+UnitID+" UnitIDb: "+UnitIDb);
return;
}
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
string Price = llList2String(UnitData, 1);
string Discount = (string)llList2Integer(UnitData, 2);
string MinRent = llList2String(UnitData, 3);
string MaxRent = llList2String(UnitData, 4);
string Rented = llList2String(UnitData, 5);
string RenterKey = llList2String(UnitData, 6);
string Expire = llList2String(UnitData, 7);
string Prims = llList2String(UnitData, 8);
string Texture = llList2String(UnitData, 9);
list Output = [ SecurityKey, "UNIT", UnitID, Price, Discount, MinRent, MaxRent, Rented, RenterKey, Expire, Prims, Texture];
string OutputString = llDumpList2String(Output, "||");
DebugMessage("Sending Config Data: "+OutputString);
llRegionSayTo(id, ComChannel, OutputString);
LightToggle(OUTLIGHT, FALSE, "Green");
}else if(CMD=="RENTED" || CMD=="AVAIL"){
list NewUnitData = llList2List(InputData, 1, -1);
string UnitID = llList2String(NewUnitData, 0);
integer IDLength = llStringLength(UnitID);
string Wing = EMPTY;
string Unit = EMPTY;
integer DBIndex;
if(IDLength==2){
Wing = llGetSubString(UnitID, 1, 1);
Unit = llGetSubString(UnitID, 0, 0);
}else if(IDLength==3){
Wing = llGetSubString(UnitID, 2, 2);
Unit = llGetSubString(UnitID, 0, 1);
}
if(llToLower(Wing)=="a"){
DBIndex = (integer)Unit;
}else if(llToLower(Wing)=="b"){
DBIndex = ((integer)Unit + (DBEntries / 2));
}else{
llOwnerSay("ERROR");
}
dbIndex = DBIndex;
// UNITID, PRICE, DISCOUNT, MINRENT, MAXRENT, RENTED, RENTERKEY, EXPIRE, PRIMS, Texture
integer NewIndex = dbPut([llList2String(NewUnitData, 0), llList2String(NewUnitData, 1), llList2String(NewUnitData, 2), llList2String(NewUnitData, 3), llList2String(NewUnitData, 4), llList2String(NewUnitData, 5), llList2String(NewUnitData, 6), llList2String(NewUnitData, 7), llList2String(NewUnitData, 8), llList2String(NewUnitData, 9)]);
list UpData = dbGet(DBIndex);
DebugMessage("Updating Remote Server...");
RegisterServer("Update", UpData);
}
}
touch_start(integer num){
if(num>1){
return;
}
if(!CheckSecurity(llDetectedKey(0))){
llRegionSayTo(llDetectedKey(0), 0, "You are not authorized!");
return;
}
DebugMode = !DebugMode;
if(DebugMode){
DebugMessage("Debug Mode Enabled!");
DebugMessage("Dumping Database...");
integer i;
for(i=1;i<=DBEntries;i++){
list UnitData = dbGet(i);
DebugMessage("DB Entry #: "+(string)i+"\nUnit ID: "+llList2String(UnitData, 0)+"\nPrice: "+llList2String(UnitData, 1)+" /wk\nDiscount: "+(string)llList2Integer(UnitData, 2)+" %\nMin Rent: "+llList2String(UnitData, 3)+"Week(s)\nMax Rent: "+llList2String(UnitData, 4)+"Weeks(s)\nRented: "+llList2String(UnitData, 5)+"\nRenter: "+llKey2Name(llList2Key(UnitData, 6))+"\nExpiry: "+llList2String(UnitData, 7)+"\nMax Prims: "+llList2String(UnitData, 8)+"\nTexture Key: "+llList2String(UnitData, 9));
}
}else{
llOwnerSay("Debug Mode Disabled!");
}
}
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id != HTTPRequestHandle) return;// exit if unknown
if(OpFlag=="CheckReg"){
vector COLOR_BLUE = <0.0, 0.0, 1.0>;
float OPAQUE = 1.0;
list OutputData = llCSV2List(body); // Parse Response into List
string InputKey = llBase64ToString(llList2String(OutputData, 1));
string InputCMD = llBase64ToString(llList2String(OutputData, 0));
if(InputKey!=SecurityKey){
llOwnerSay("Invalid Security Key Received from RL Server!\r"+body);
}else{
if(InputCMD=="ALRDYREGOK"){ // Server Already Registered
if(DebugMode){
llOwnerSay("Server Already Registered!");
}
}else if(InputCMD=="REGOK"){ // Server Successfully Registered
if(DebugMode){
llOwnerSay("Server Successfully Registered!");
}
}else if(InputCMD=="REGERR"){ // Error Registering Server with Off-World Database
llOwnerSay("Error Registering Server with Database!");
}else if(InputCMD=="CHECKERR"){ // Error Checking Database for Server Registration
llOwnerSay("Error Checking Database for Server Registration");
}else{
llOwnerSay("Response from server not reconignized!");
}
}
LightToggle(CFGLIGHT, FALSE, "Orange");
RegisterServer("Sync", []);
}else if(OpFlag=="Sync"){
list InputData = llParseString2List(body, [":"], []);
string ResponseCode = llList2String(InputData, 0);
if(ResponseCode=="UPDATE"){ // In-Ward Sync
list OffWorldData = llCSV2List(llList2String(InputData, 1));
if(dbDrop(DBName)){
string CreatedDB = dbCreate(DBName, ["unitid", "price", "discount", "minrent", "maxrent", "rented", "renterkey", "expire", "prims", "texture"]);
if(CreatedDB==DBName && DebugMode){
llOwnerSay("Database "+DBName+" Cleared...");
}
integer i;
for(i=0;i<DBEntries;i++){
list ThisUnit = llParseString2List(llList2String(OffWorldData, i), ["||"], []);
// UNITID, PRICE, DISCOUNT, MINRENT, MAXRENT, RENTED, RENTERKEY, EXPIRE
string UnitID = llList2String(ThisUnit, 0);
integer Price = llList2Integer(ThisUnit, 1);
float Discount = llList2Float(ThisUnit, 2);
integer MinRent = llList2Integer(ThisUnit, 3);
integer MaxRent = llList2Integer(ThisUnit, 4);
string Rented = llList2String(ThisUnit, 5);
key RenterKey = llList2Key(ThisUnit, 6);
integer Expiry = llList2Integer(ThisUnit, 7);
integer Prims = llList2Integer(ThisUnit, 8);
key Texture = llList2Key(ThisUnit, 9);
integer NewEntry = dbInsert([UnitID, Price, Discount, MinRent, MaxRent, Rented, RenterKey, Expiry, Prims, Texture]);
if(NewEntry!=(i+1)){
DebugMessage("ERROR: New Entry #: "+(string)NewEntry+" Index #: "+(string)i);
state borked;
}
}
DebugMessage("Databases Sync'd!");
SystemStart();
}
}else if(ResponseCode=="SYNCERROR"){ // Sync Error
string ErrorString = llList2String(InputData, 1);
DebugMessage("Sync Error!\nMessage:\n"+ErrorString);
state borked;
}else if(ResponseCode=="OK"){ // Sync OK (New Database Setup)
DebugMessage("New Database Setup!");
SystemStart();
}
}else if(OpFlag=="Update"){
list Response = llParseString2List(body, ["||"], []);
if(llToUpper(llList2String(Response, 0))=="OK"){
string UnitID = llList2String(Response, 1);
key Renter = llList2Key(Response, 2);
PrepUnit(UnitID, Renter);
}
}
}
}
state borked{
state_entry(){
llOwnerSay("Error Has Occured! Please re-run with Diagnostics Mode On for full details!");
}
}

View File

@@ -0,0 +1,101 @@
integer Rented;
string UnitID;
list TexNames;
list TexKeys;
integer ComChannel = -86000;
integer MenuComChannel = -87000;
integer ComHandle;
integer MenuComHandle;
string EMPTY = "";
integer GetLoaded(){
integer NumTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
integer i;
for(i=0;i<NumTextures;i++){
TexNames = TexNames + llGetInventoryName(INVENTORY_TEXTURE, i);
TexKeys = TexKeys + llGetInventoryKey(llList2String(TexNames, -1));
integer NumKeys = (llGetListLength(TexKeys)-1);
if(NumKeys==i){
//llOwnerSay("Loaded Texture: "+llList2String(TexNames, -1));
}
}
integer FinalListLength = llGetListLength(TexNames);
if(FinalListLength==NumTextures){
return TRUE;
}else{
return FALSE;
}
}
SetState(string NewState){
string TextureName;
if(NewState=="Rented"){
TextureName = "Unit"+UnitID+"Ocu";
llSetTexture(TextureName, 2);
}else if(NewState=="NotRented"){
TextureName = "Unit"+UnitID+"Avail";
llSetTexture(TextureName, 2);
}
}
default{
state_entry(){
integer Loaded = GetLoaded();
if(Loaded){
UnitID = llGetObjectDesc();
if(UnitID!="" && llStringLength(UnitID)<=3){
MenuComHandle = llListen(MenuComChannel, EMPTY, EMPTY, EMPTY);
llDialog(llGetOwner(), UnitID+"\n\n\tIs this the correct Unit ID for this Sign?", ["Yes", "No"], MenuComChannel);
}else{
llOwnerSay("Unable to Configure, Please Enter UnitID into Desc, Max 3 Chars\n Auto Rebooting in 5 minutes...");
llSetTimerEvent(300.0);
}
}else{
llOwnerSay("We Need the Textures for the units.\n Auto Rebooting in 5 minutes...");
llSetTimerEvent(300.0);
}
}
listen(integer channel, string name, key id, string msg){
if(channel==MenuComChannel){
if(id==llGetOwner()){
if(llToLower(msg)=="yes"){
if(ComHandle>0){
return;
}
llOwnerSay("Opening Com Channel("+(string)ComChannel+")...");
ComHandle = llListen(ComChannel, EMPTY, EMPTY, EMPTY);
if(ComHandle>0){
llOwnerSay("Com Channel Open!");
}
}else if(llToLower(msg)=="no"){
llOwnerSay("Please set correct Unit ID in Description Field!\nResetting in 5 minutes...");
llSetTimerEvent(300.0);
}
}else{
}
}else if(channel==ComChannel){
//llOwnerSay("msg: "+msg);
list InputData = llParseString2List(msg, ["||"], []);
string UnitName = llList2String(InputData, 1);
string Rented = llList2String(InputData, 6);
if(UnitName==UnitID){
if(Rented=="TRUE"){
SetState("Rented");
}else if(Rented=="FALSE"){
SetState("NotRented");
}
}
}
}
timer(){
llSetTimerEvent(0.0);
llOwnerSay("Resetting...");
llResetScript();
}
}

View File

@@ -0,0 +1,50 @@
# Vendor v1.8 Configuration File
#
# Created by Tech Guy 2014
#DO NOT CHANGE THIS LINE
luna=1251
# YOUR CONFIGURATION IS BELOW THIS LINE
# Mark as True if all item will be the same price.
singleprice=true
# The Single Price of All Items
price=199
# Set to True if you wish to use HoverText over your vendor board
hovertext=true
# The Text for the Hover Text Field if previous option is set to true. If set false this option can be ignored. Set this Option to 'dynamic' to read text from product names
hovertextstring=dynamic
# Hover Text Color
# Colors to choose from:
# "NAVY", "BLUE", "AQUA", "TEAL", "OLIVE", "GREEN, LIME", "YELLOW", "ORANGE", "RED", "MAROON", "FUCHSIA", "PURPLE", "WHITE", "SILVER", "GRAY", "BLACK"
hovertextcolor=white
#Hover Text Price Label E.g: "Buy Now" or "Price" This Label preceeds the Price in P$ in the HoverText
hoverpricelabel=Buy Now
#Loop Product Selction when at end of List (true vs false)
loopselection=true
# Name of InfoCard Given from ! Button
infocard=myinfocard
# Name of Vendor Help Card Given from ? Button
helpcard=vendorhelp
#Should we auto cycle through your products
slideshow=true
# If slideshow is enabled how often should we switch Products (in seconds)
slidetimer=10
#Enable Profit Sharing (TRUE/FALSE)
profitsharing=TRUE
# UUIDs of ShareHolders, Un-Used lines are ignored.
ShareHolder=Tech Guy||33
ShareHolder=Zoie Viper||33
ShareHolder=Sebastian Viper||33

View File

@@ -0,0 +1,729 @@
// Hard-Coded Variables
string cName = ".config"; // Name of Configuration NoteCard
integer BufferFace = 3; // Face to Preload the Next Texture Given the Last Direction used. LOL "BUFFER FACE!!!"
integer DisplayFace = 1; // Face to Display Product
integer DisplayPrimID = 2; // Link number of Prim used to Display and Buffer Textures
integer DHandleChannel = -18006; // Dialog Handle Channel
float DHandleTimeOut = 60.0;
// Color Vectors
list colorsVectors = [<0.000, 0.122, 0.247>, <0.000, 0.455, 0.851>, <0.498, 0.859, 1.000>, <0.224, 0.800, 0.800>, <0.239, 0.600, 0.439>, <0.180, 0.800, 0.251>, <0.004, 1.000, 0.439>, <1.000, 0.863, 0.000>, <1.000, 0.522, 0.106>, <1.000, 0.255, 0.212>, <0.522, 0.078, 0.294>, <0.941, 0.071, 0.745>, <0.694, 0.051, 0.788>, <1.000, 1.000, 1.000>, <0.867, 0.867, 0.867>, <0.667, 0.667, 0.667>, <0.000, 0.000, 0.000>];
// List of Names for Colors
list colors = ["NAVY", "BLUE", "AQUA", "TEAL", "OLIVE", "GREEN", "LIME", "YELLOW", "ORANGE", "RED", "MAROON", "FUCHSIA", "PURPLE", "WHITE", "SILVER", "GRAY", "BLACK"];
// Empty Variales to be filled by script
key user; // UUID of Customer Avatar
string mode = "";
list prodBoxes; // List that will contain Product Box Names
list prodNC; // List that will contain Product Notecard Names
list prodImages; // List that will contain Product Images for Display on main Board.
list prodPrices; // List that will contain Product Prices of Configured to read prices from box description.
integer NumProds; // Hold Total NUmber of Products
integer prodIndex; // Product Index Storage Variable (Changes with Current viewed Product)
string GiftRecipientID; // Hold Key of User object will be gifted too.
integer cLine; // Holds Configuration Line Index for Loading Config Loop
key cQueryID; // Holds Current Configuration File Line during Loading Loop
string NavDirection = "up"; // Will Hold Direction of users surfing through vendor, (up vs down)
integer SlideCount = 0; // Hold Product ID If SlideShow Mode is turned on.
integer MoneyPerm; // Holds Script Money Permissions Mask
integer price; // Hold Price for Final Money Event Call
// Share Holders Configuration Variables
integer ProfitSharing = FALSE;
list ShareHolders = [];
float SharePercentage = 0.0;
integer NumShareHolders = 0;
list ShareHoldersCut = [];
integer TotalShareHolderPercent = 0;
// Handles
integer DListener; // Main Dialog Listener Handle
// Initially Coded but flexible Switches
integer SinglePrice = TRUE; // True if All Items use One Uniform Price
integer SPrice; // Holds Price obtained from Config file (If previous swich is TRUE)
integer PriceInDesc = FALSE; // True if price can be found in description of each box in inventory
integer HoverText = TRUE; // Enable HoverText By Default
integer TextFromNames = FALSE; // Should Hover Text be based on Currently viewed product.
string HTextString = "Vendor Hover Text"; // Default Vendor Hover Text
vector HTextColor; // Default Vendor Hover Text Color Vector
string HTextColorString; // Hold Name of Currently Selected Hover Text Color
string HTextPriceLabel; // Hover Text Price Label Holder
integer LoopProducts = TRUE; // True if we want to cycle product list upon reaching the end.
string InfoCard = ""; // Name of InfoCard NC
string VendorHelpCard = ""; // Name of Vendor Help NC
string ResetReason = "Refresh";
float SlideTimer = 10.0;
float ResetTimer = 600.0;
integer SlideShow = TRUE;
integer CheckConfig(string NCtoCheck){
integer ConfigFileCheck = llGetInventoryType(NCtoCheck);
if(ConfigFileCheck == INVENTORY_NOTECARD){ // File Exists and is a NoteCard
return TRUE;
}else{ // File Exists but is of different Type
return FALSE;
}
}
LoadConfig(string data){
if(data!=""){ // If Line is not Empty
// if the line does not begin with a comment
if(llSubStringIndex(data, "#") != 0)
{
// find first equal sign
integer i = llSubStringIndex(data, "=");
// if line contains equal sign
if(i != -1){
// get name of name/value pair
string name = llGetSubString(data, 0, i - 1);
// get value of name/value pair
string value = llGetSubString(data, i + 1, -1);
// trim name
list temp = llParseString2List(name, [" "], []);
name = llDumpList2String(temp, " ");
// make name lowercase
name = llToLower(name);
// trim value
temp = llParseString2List(value, [" "], []);
value = llDumpList2String(temp, " ");
// Check Key/Value Pairs and Set Switches and Lists
if(name == "luna"){ // Found Luna Directive
if(value=="1251"){ // Check Value and Continue
integer luna = TRUE; // Luna Directive Marked TRUE;
}else{ // Incorrect Value Break Vendor and wait for inventory change
llOwnerSay("Configuration file Error! Please reload from Example File contained in vendor. Consult Documentation.");
state broken;
}
}else if(name == "singleprice" && value!=""){
value = llToLower(value);
if(value=="true"){
SinglePrice = TRUE;
llOwnerSay("Single Price Configuration...");
}else{
SinglePrice = FALSE;
}
}else if(name == "price" && value!=""){
if(SinglePrice){
SPrice = (integer)value;
llOwnerSay("Single Price: "+value);
}
}else if(name=="hovertext"){
value = llToLower(value);
if(value=="true"){
HoverText = TRUE;
llOwnerSay("Hover Text: Enabled");
}else{
HoverText = FALSE;
llOwnerSay("Hover Text: Disabled");
}
}else if(name=="hovertextstring"){
if(value==llToLower(value)){
TextFromNames = TRUE;
llOwnerSay("Dynamic HoverText Set...");
}else{
TextFromNames = FALSE;
HTextString = value;
llOwnerSay("Staic HoverText: "+value);
}
}else if(name=="slideshow"){
value = llToLower(value);
if(value=="true"){
SlideShow = TRUE;
llOwnerSay("SlideShow Mode: Enabled");
}else{
SlideShow = FALSE;
llOwnerSay("SlideShow Mode: Disabled");
}
}else if(name=="hovertextcolor"){
if(HoverText){
value = llToUpper(value);
integer cIndex;
integer lLength = llGetListLength(colors);
for(cIndex=0;cIndex<lLength;cIndex++){
if(value==llToUpper(llList2String(colors, cIndex))){
HTextColor = llList2Vector(colorsVectors, cIndex);
HTextColorString = value;
}
}
llOwnerSay("Hover Text Color: "+HTextColorString);
}
}else if(name=="hoverpricelabel"){
HTextPriceLabel = value;
llOwnerSay("Price Label set to: "+HTextPriceLabel);
}else if(name=="loopselection"){
value = llToLower(value);
if(value=="true"){
LoopProducts = TRUE;
llOwnerSay("Vendor set to Loop Product Selection...");
}else{
LoopProducts = FALSE;
llOwnerSay("Vendor set to NOT Loop Product Selection...");
}
}else if(name=="infocard"){
if(value!=""){
integer FF = llGetInventoryType(value);
integer InfoCardPerm = llGetInventoryPermMask(value, MASK_NEXT);
if(FF==INVENTORY_NOTECARD){
if(!InfoCardPerm & PERM_COPY){
llOwnerSay("InfoCard not set with COPY Permissions! You will lose it on first request!");
}
InfoCard = value;
llOwnerSay("Info Card Set to: "+InfoCard);
}else{
llOwnerSay("No Info Card Found! Please add a General Info card and/or check .config file");
state broken;
}
}else{ // Not Info Card Specified, Break Script and Wait for .config Update
llOwnerSay("Please specify an Info Card in the .config file!");
state broken;
}
}else if(name=="helpcard"){
if(value!=""){
integer FF = llGetInventoryType(value);
integer HelpCardPerm = llGetInventoryPermMask(value, MASK_NEXT);
if(FF==INVENTORY_NOTECARD){
if(!HelpCardPerm & PERM_COPY){
llOwnerSay("HelpCard not set with COPY Permissions! You will lose it on first request!");
}
VendorHelpCard = value;
llOwnerSay("Info Card Set to: "+VendorHelpCard);
}else{
llOwnerSay("No Info Card Found! Please add a General Info card and/or check .config file");
state broken;
}
}else{ // Not Info Card Specified, Break Script and Wait for .config Update
llOwnerSay("Please specify an Info Card in the .config file!");
state broken;
}
}else if(name=="slidetimer"){
SlideTimer = (integer)value;
llOwnerSay("Slide Timer: "+value+" seconds");
}else if(name=="profitsharing"){
if(value=="TRUE"){
llOwnerSay("Profit Sharing Enabled");
ProfitSharing = TRUE;
}else if(value=="FALSE"){
llOwnerSay("Profit Sharing Disabled");
ProfitSharing = FALSE;
}else{
llOwnerSay("Invalid Value for ProfitSharing Config Directive!\nProfit Sharing Disabled!");
ProfitSharing = FALSE;
}
}else if(name=="shareholder" && ProfitSharing && value!=""){
integer ListLength = llGetListLength(ShareHolders); // Get Length of ShareHolder List to Compare with End of Function for Success Test
integer SpaceIndex = llSubStringIndex(value, " "); // Find Index of Space
integer IOPipeIndex = llSubStringIndex(value, "||"); // Find Index of IO Pipe
string FName = llGetSubString(value, 0, SpaceIndex-1); // Extract First Name
string LName = llGetSubString(value, SpaceIndex+1, IOPipeIndex-1); // Extract Last Name
string HisCut = llGetSubString(value, IOPipeIndex+2, -1); // Determine Share Holders Cut
ShareHoldersCut = ShareHoldersCut + [HisCut]; // Save Cut to List
ShareHolders = ShareHolders + [osAvatarName2Key(FName, LName)]; // Save ShareHolder UUID to List
if(llGetListLength(ShareHolders)>ListLength){
llOwnerSay("\nShare Holder '"+FName+" "+LName+"' Added!\nThier UUID: "+llList2String(ShareHolders, NumShareHolders)+"\nShare Holder Cut: "+llList2String(ShareHoldersCut, llListFindList(ShareHoldersCut, [HisCut]))+"%");
NumShareHolders++;
TotalShareHolderPercent = TotalShareHolderPercent + (integer)HisCut;
if(TotalShareHolderPercent>100){
ProfitSharing = FALSE;
llOwnerSay("ERROR! Total ShareHolder Percentage is Greater than 100%!\nProfit Sharing Disabled!");
}
}
}else if(name=="shareholder" && !ProfitSharing){
}else{
llOwnerSay("Unknown configuration value: " + name + " on line " + (string)cLine);
}
}else{ // line does not contain equal sign
llOwnerSay("Configuration could not be read on line " + (string)cLine);
}
}
}
}
CheckPerms(string Name, integer InvType){
integer permCode = llGetInventoryPermMask(Name, MASK_NEXT);
if(InvType==INVENTORY_OBJECT){
if(~permCode & PERM_COPY){
llOwnerSay("Item: "+Name+" is not marked as copy, your object will be lost from vendor inventory on purchase.\n Please Mark as Copy to avoid this issue.");
}
if(permCode & PERM_TRANSFER){
llOwnerSay("Item: "+Name+" is marked as TRANSFER, Customers will be able to resell this product.");
}
}else if(InvType==INVENTORY_NOTECARD){
if(~permCode & PERM_COPY){
llOwnerSay("Item: "+Name+" is not marked as copy, your object will be lost from vendor inventory on purchase.\n Please Mark as Copy to avoid this issue.");
}
if(permCode & PERM_TRANSFER){
llOwnerSay("Item: "+Name+" is marked as TRANSFER, Customers will be able to resell this product.");
}
}
}
ShareProfits(integer Income){
integer i;
for(i=0;i<=llGetListLength(ShareHolders)-1;i++){ // For Each Share Holder in the List
string ShareHolderID = llList2String(ShareHolders, i);
float HisCut = (float)Income * (llList2Float(ShareHoldersCut, i) / 100);
integer PayHim = (integer)HisCut;
string Name = osKey2Name((key)ShareHolderID);
llGiveMoney(ShareHolderID, PayHim);
}
}
LoadInventory(){ // Load Invectory into prodBoxes & prodImages Lists
integer i;
NumProds = llGetInventoryNumber(INVENTORY_OBJECT);
if(NumProds<=0){
llOwnerSay("No Products Found! Please place your products inside the vendors 'Content' Tab");
state broken;
}else{
llOwnerSay((string)NumProds+" Found!");
}
for(i=0;i<=NumProds-1;i++){
//Get Product Box By Name and Checks it's Permissions
string objName = llGetInventoryName(INVENTORY_OBJECT, i);
CheckPerms(objName, INVENTORY_OBJECT);
prodBoxes += objName;
//Get Product Texture by Name and Check It's Permissions
string TextureName = llGetInventoryName(INVENTORY_TEXTURE, i);
CheckPerms(TextureName, INVENTORY_TEXTURE);
prodImages += llGetInventoryKey(llGetInventoryName(INVENTORY_TEXTURE, i));
// Get Product Notecards by Name and Check Their Permissions
string NoteName = llGetInventoryName(INVENTORY_NOTECARD, i);
if(NoteName==".config" || NoteName==InfoCard || NoteName == VendorHelpCard){
i++;
NoteName = llGetInventoryName(INVENTORY_NOTECARD, i);
if(NoteName == ".config" || NoteName == InfoCard || NoteName == VendorHelpCard){
i++;
NoteName = llGetInventoryName(INVENTORY_NOTECARD, i);
if(NoteName == ".config" || NoteName == InfoCard || NoteName == VendorHelpCard){
i++;
NoteName = llGetInventoryName(INVENTORY_NOTECARD, i);
if(NoteName == ".config" || NoteName == InfoCard || NoteName == VendorHelpCard){
i=i-3;
llOwnerSay("Unable to Find Matching Notecard to Found Product: "+llList2String(prodBoxes, i)+"\nPlease consult documentation...");
state broken;
}else{
CheckPerms(NoteName, INVENTORY_NOTECARD);
prodNC += llGetInventoryName(INVENTORY_NOTECARD, i);
i = i-3;
}
}else{
CheckPerms(NoteName, INVENTORY_NOTECARD);
prodNC += llGetInventoryName(INVENTORY_NOTECARD, i);
i = i-2;
}
}else{
CheckPerms(NoteName, INVENTORY_NOTECARD);
prodNC += llGetInventoryName(INVENTORY_NOTECARD, i);
i--;
}
}else{
CheckPerms(NoteName, INVENTORY_NOTECARD);
prodNC += llGetInventoryName(INVENTORY_NOTECARD, i);
}
// Set All Prices in List to 9999
prodPrices += 9999;
if(llList2String(prodBoxes, i)!="" && llList2String(prodImages, i)!=""){
llOwnerSay("Found Item: "+llList2String(prodBoxes, i));
llOwnerSay("Found Texture: "+llList2String(prodImages, i));
llOwnerSay("Found NoteCard: "+llList2String(prodNC, i));
}else{
llOwnerSay("ERROR: Could not find Matching Texture for Product: "+llList2String(prodBoxes, i));
}
}
llOwnerSay(NumProds+" Different Products Successfully Loaded!");
Init();
}
Init(){
if(!SinglePrice){
llOwnerSay("Starting Vendor...\nVendor is in Custom Price Mode. See Documentation for help setting prices in this mode.\nAll Prices set to P$ 9999");
}else{
llOwnerSay("Starting Vendor in Single Price Mode...");
}
if(HoverText){
if(TextFromNames){
if(SinglePrice){
llSetText(llList2String(prodBoxes, prodIndex)+"\n"+HTextPriceLabel+": P$ "+SPrice, HTextColor, 1.0);
}else{
llSetText(llList2String(prodBoxes, prodIndex)+"\n"+HTextPriceLabel+": P$ "+llList2Integer(prodPrices, prodIndex), HTextColor, 1.0);
}
}else{
llSetText(HTextString, HTextColor, 1.0);
}
}else{
llSetText("", HTextColor, 1.0);
}
state running;
}
DisplayProduct(integer ProdID, string Direction){
if(Direction=="up"){
if(TextFromNames){
if(HoverText){
if(SinglePrice){
llSetText(llList2String(prodBoxes, ProdID)+"\n"+HTextPriceLabel+": P$ "+SPrice, HTextColor, 1.0);
}else{
llSetText(llList2String(prodBoxes, ProdID)+"\n"+HTextPriceLabel+": P$ "+llList2Integer(prodPrices, ProdID), HTextColor, 1.0);
}
}
}
llSetLinkPrimitiveParamsFast(DisplayPrimID, [PRIM_TEXTURE, DisplayFace, llList2String(prodImages, prodIndex), <1.0, 1.0, 0.0>, ZERO_VECTOR,0.0]);
llSetLinkPrimitiveParamsFast(DisplayPrimID, [PRIM_TEXTURE, BufferFace, llList2String(prodImages, prodIndex+1), <1.0, 1.0, 0.0>, ZERO_VECTOR,0.0]);
}else if(Direction=="down"){
if(TextFromNames){
if(HoverText){
if(SinglePrice){
llSetText(llList2String(prodBoxes, ProdID)+"\n"+HTextPriceLabel+": P$ "+SPrice, HTextColor, 1.0);
}else{
llSetText(llList2String(prodBoxes, ProdID)+"\n"+HTextPriceLabel+": P$ "+llList2Integer(prodPrices, ProdID), HTextColor, 1.0);
}
}
}
llSetLinkPrimitiveParamsFast(DisplayPrimID, [PRIM_TEXTURE, DisplayFace, llList2String(prodImages, prodIndex), <1.0, 1.0, 0.0>, ZERO_VECTOR,0.0]);
llSetLinkPrimitiveParamsFast(DisplayPrimID, [PRIM_TEXTURE, BufferFace, llList2String(prodImages, prodIndex-1), <1.0, 1.0, 0.0>, ZERO_VECTOR,0.0]);
}
}
default{
on_rez(integer start_param){
llResetScript();
}
state_entry(){
llSetLinkPrimitiveParamsFast(DisplayPrimID, [PRIM_TEXTURE, DisplayFace, TEXTURE_BLANK, <1.0, 1.0, 1.0>, ZERO_VECTOR,0.0]);
llSetText("",<1.0,1.0,1.0>,1.0);
llOwnerSay("Searching for Configuration File...");
// Check for Config NoteCard
integer ConfigFound = CheckConfig(cName);
if(ConfigFound==TRUE){ // Configuration Notecard Was Found
llOwnerSay("Configuration File Found!"); // Tell User File was found and allow script to proceed
}else{ // Config File was not found, Notify User and Switch to Broken State.
llOwnerSay("Configuration File NOT Found or is Incorrect FileType!\nPlease copy the contents of NoteCard EXAMPLE.config to a Notecard Named .config\nSee Documentation for further details.");
state broken; // Switch to Broken State and wait for inventory change.
}
llOwnerSay("Configuring...");
cQueryID = llGetNotecardLine(cName, cLine);
}
dataserver(key query_id, string data){ // Config Notecard Read Function Needs to be Finished
if (query_id == cQueryID){
if (data != EOF){
LoadConfig(data); // Process Current Line
++cLine; // Incrment Line Index
cQueryID = llGetNotecardLine(cName, cLine); // Attempt to Read Next Config Line (Re-Calls DataServer Event)
}else{ // IF EOF (End of Config loop, and on Blank File)
llOwnerSay("Please accept Debit Permissions...");
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
}
}
run_time_permissions(integer perm)
{
MoneyPerm = perm;
if(MoneyPerm & PERMISSION_DEBIT){
llOwnerSay("Debit Permissions OK");
llSetPayPrice(PAY_HIDE, [PAY_HIDE ,PAY_HIDE, PAY_HIDE, PAY_HIDE]);
llOwnerSay("Configuration Loaded!\nLoading Inventory...");
LoadInventory();
}
}
}
state broken{
state_entry(){
llOwnerSay("Vendor Offline");
}
changed(integer change){
if(change && change == CHANGED_INVENTORY){
llOwnerSay("Inventory Modification Detected, Resetting...");
llResetScript();
}
}
}
state running{
state_entry(){
if(SinglePrice){
llOwnerSay("Vendor Online!");
if(SlideShow){
ResetReason = "NextSlide";
llSetTimerEvent(SlideTimer);
}
}else{
llOwnerSay("Vendor Online! Please Remember to Set Product Prices!\n Consult Documentation for Help.");
}
llSetLinkPrimitiveParamsFast(DisplayPrimID, [PRIM_TEXTURE, DisplayFace, llList2String(prodImages, prodIndex), <1.0, 1.0, 0.0>, ZERO_VECTOR,0.0]);
llSetLinkPrimitiveParamsFast(DisplayPrimID, [PRIM_TEXTURE, BufferFace, llList2String(prodImages, prodIndex+1), <1.0, 1.0, 0.0>, ZERO_VECTOR,0.0]);
}
link_message(integer sender_num, integer num, string message, key id)
{
// Admin Dialog
if(message=="admin" && id==llGetOwner() && !SinglePrice){
llSetTimerEvent(0);
DListener = llListen(DHandleChannel, "", id, "");
llDialog(id, "What would you like to do?", ["Change Price", "Cancel"], DHandleChannel);
ResetReason = "Dialog";
llSetTimerEvent(DHandleTimeOut);
mode = "admin";
}else if(message=="admin"){
if(llList2String(prodNC, prodIndex)==""){
llSay(0, "There is not NoteCard Associated with this product to give you.");
return;
}
llGiveInventory(id, llList2String(prodNC, prodIndex));
}
if(message=="next"){
ResetReason = "NextSlide";
llSetTimerEvent(60);
if(prodIndex==0){
prodIndex++;
NavDirection = "up";
DisplayProduct(prodIndex, NavDirection);
}else if(prodIndex==NumProds-1){
if(LoopProducts){
prodIndex = 0;
NavDirection = "up";
DisplayProduct(prodIndex, NavDirection);
}else{
llSay(0, "End of product list reached!");
}
}else if(prodIndex<NumProds-1){
prodIndex++;
NavDirection = "up";
DisplayProduct(prodIndex, NavDirection);
}
}else if(message=="prev"){
ResetReason = "NextSlide";
llSetTimerEvent(60);
if(prodIndex==0){
if(LoopProducts){
prodIndex = NumProds-1;
NavDirection = "down";
DisplayProduct(prodIndex, NavDirection);
}else{
llSay(0, "End of product list reached!");
}
}else if(prodIndex==NumProds-1){
prodIndex--;
NavDirection = "down";
DisplayProduct(prodIndex, NavDirection);
}else if(prodIndex<NumProds-1){
prodIndex--;
NavDirection = "down";
DisplayProduct(prodIndex, NavDirection);
}
}else if(message=="help"){
if(!llGetInventoryType(VendorHelpCard) || VendorHelpCard==""){
llSay(0, "No Vendor Help Card to give you.");
return;
}
llGiveInventory(id, VendorHelpCard);
}else if(message=="info"){
if(!llGetInventoryType(InfoCard) || InfoCard==""){
llSay(0, "No InfoCard to Give you.");
return;
}
llGiveInventory(id, InfoCard);
}else if(message=="gift"){
DListener = llListen(DHandleChannel, "", id, "");
if(!DListener){
llSay(0, "Error!\n Unable to open dialog, please contact vendor support!");
state broken;
}else{
llTextBox(id, "Please enter the first and last name of the person you wish you buy this item for.\nYou have 60 seconds...", DHandleChannel);
llSetTimerEvent(DHandleTimeOut);
}
}else if(message=="buy"){
ResetReason = "OrderRefresh";
llSetTimerEvent(20);
user = id;
if(MoneyPerm & PERMISSION_DEBIT){
if(HoverText){
llSetText("Preparing Vendor for purcahse...", HTextColor, 1.0);
}
if(SinglePrice){
llSetPayPrice(PAY_HIDE, [(integer)SPrice, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
}else{
llSetPayPrice(PAY_HIDE, [llList2Integer(prodPrices, prodIndex), PAY_HIDE, PAY_HIDE, PAY_HIDE]);
}
if(HoverText){
llSetText("Please pay vendor to buy this item...", HTextColor, 1.0);
}
llSay(0, "Please pay vendor to buy this item...\nYou have 20 seconds to pay the vendor...");
}
}
}
listen(integer chan, string name, key id, string msg){
llOwnerSay(name);
if(chan==DHandleChannel){
if(mode=="admin"){
if(msg!=""){
if(msg=="Change Price"){
llTextBox(id, "Please enter new price...\n\nExample: 199", DHandleChannel);
}else if(msg=="Cancel"){
llOwnerSay("Admin Mode Canceled");
if(SlideShow){
llSetTimerEvent(SlideTimer);
}
}else if(mode=="admin" && msg!=""){
llOwnerSay("Setting Price to "+msg);
list newlist = [(integer)msg];
list finallist = llListInsertList(prodPrices, newlist, prodIndex);
prodPrices = finallist;
llOwnerSay("Leaving Admin Mode...");
mode = "";
DisplayProduct(prodIndex, NavDirection);
if(SlideShow){
llSetTimerEvent(SlideTimer);
}
}
}
}else if(msg!=""){
if(GiftRecipientID!="" && msg=="Yes"){
// Setup Money Transaction and Notify User
ResetReason = "OrderRefresh";
llSetTimerEvent(20);
user = (key)GiftRecipientID;
if(MoneyPerm & PERMISSION_DEBIT){
if(HoverText){
llSetText("Preparing Vendor for purcahse...", HTextColor, 1.0);
}
llSay(0, "Preparing Vendor for pruchase...");
if(SinglePrice){
llSetPayPrice(PAY_HIDE, [(integer)SPrice, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
}else{
llSetPayPrice(PAY_HIDE, [llList2Integer(prodPrices, prodIndex), PAY_HIDE, PAY_HIDE, PAY_HIDE]);
}
if(HoverText){
llSetText("Please pay vendor to buy this item...", HTextColor, 1.0);
}
llSay(0, "Please pay vendor to buy this item...\nYou have 20 seconds to pay the vendor...");
}
}else if(msg=="No"){
GiftRecipientID = NULL_KEY;
llSay(0, "Gift Process Cleared\nRestarting SlideShow...");
llListenRemove(DListener);
ResetReason = "OrderRefresh";
llSetTimerEvent(5.0);
}else if(msg=="Forget It"){
GiftRecipientID = NULL_KEY;
llSay(0, "Gift Process Cleared\nRestarting SlideShow...");
llListenRemove(DListener);
ResetReason = "OrderRefresh";
llSetTimerEvent(5.0);
}else{
integer spaceIndex = llSubStringIndex(msg, " ");
string firstName = llGetSubString(name, 0, spaceIndex - 1);
string lastName = llGetSubString(name, spaceIndex + 1, -1);
GiftRecipientID = osAvatarName2Key(firstName, lastName);
if(GiftRecipientID==""){
llSay(0, "ERROR! Invalid UUID. Please consult documentation");
}else{
llSay(0, "Please Note your gift recipient must be on this sim!\n\nYou are buying for "+firstName+" "+lastName);
llDialog(id, "Please Note your gift recipient must be on this sim!\n\nYou are buying for "+firstName+" "+lastName+".\nIs this correct?", ["Yes", "No", "Forget It"], DHandleChannel);
}
}
}
}
}
timer(){
if(ResetReason=="Dialog"){
llSay(0, "Dialog Menu Timed-Out");
user = NULL_KEY;
llListenRemove(DListener);
ResetReason = "Refresh";
llSetTimerEvent(ResetTimer);
}else if(ResetReason=="Refresh"){
user = NULL_KEY;
llListenRemove(DListener);
prodIndex = 0;
DisplayProduct(prodIndex, NavDirection);
}else if(ResetReason=="NextSlide"){
if(SlideShow){
if(SlideCount<ResetTimer){
llSetTimerEvent(SlideTimer);
SlideCount = SlideCount + 10;
if(prodIndex<NumProds-1){
prodIndex++;
DisplayProduct(prodIndex, NavDirection);
}else{
prodIndex = 0;
DisplayProduct(prodIndex, NavDirection);
}
}else{
SlideCount = 0;
ResetReason = "Refresh";
}
}else{
}
llListenRemove(DListener);
}else if(ResetReason=="OrderRefresh"){
llSetPayPrice(PAY_HIDE, [PAY_HIDE ,PAY_HIDE, PAY_HIDE, PAY_HIDE]);
user = NULL_KEY;
GiftRecipientID = "";
llListenRemove(DListener);
ResetReason = "NextSlide";
llSetTimerEvent(0);
llSetTimerEvent(SlideTimer);
prodIndex = 0;
DisplayProduct(prodIndex, NavDirection);
}
}
money(key id, integer amount){
if(SinglePrice){
price = (integer)SPrice;
}else{
price = llList2Integer(prodPrices, prodIndex);
}
if(id!=user){
llSay(0, "Please, Only the person who clicked 'Buy' May pay for the item.\n If you wish please use 'Buy as Gift' Button");
llSetTimerEvent(ResetTimer);
DisplayProduct(prodIndex, NavDirection);
}else{
if(amount<price){
llSay(0, "You did not pay enough, Refunding...\nYou have 60 seconds to pay the correct amount before the vendor resets.");
llGiveMoney(user, amount);
ResetReason = "OrderRefresh";
llSetTimerEvent(0);
llSetTimerEvent(60);
}else if(amount>price){
llSay(0, "You paid too much, Refunding Difference...");
integer amtDiff = amount-price;
llGiveMoney(user, amtDiff);
llGiveInventory(user, llList2String(prodBoxes, prodIndex));
ResetReason = "OrderRefresh";
llSay(0, "Order Successful! Please accept your new item...");
llSetTimerEvent(0);
llSetTimerEvent(15);
}else if(amount==price){
llSay(0, "Thank You, Please accept your new item...");
llGiveInventory(user, llList2String(prodBoxes, prodIndex));
ResetReason = "OrderRefresh";
if(ProfitSharing){
ShareProfits(amount);
}
llSetTimerEvent(0);
llSetTimerEvent(15);
}
}
}
}

View File

@@ -0,0 +1,135 @@
// Street Light Command Receiver v1.0
// Created by Tech Guy of IO 2015
// Configuration
// Constants
integer ComChannel = -8000;
string EMPTY = "";
list LightFaces = [2, 3];
list Poles = [1, 4];
// Input Message Reference IDS
integer STATE = 0;
integer LIGHTCOLOR = 1;
integer WHITECOLOR = 2;
integer INTENSITY = 3;
integer RADIUS = 4;
integer FALLOFF = 5;
integer POLECOLOR = 6;
// Light Parameters
vector LightColor = <1.0,1.0,0.0>; // Yellow
vector WhiteColor = <1.0,1.0,1.0>; // White
float Intensity = 1.0;
float Radius = 20.0;
float FallOff = 0.5;
float GlowON = 0.10;
float GlowOFF = 0.0;
// Light Pole Parameters
vector PoleColor = <1.0,1.0,0.851>;
float Alpha = 1.0; // Alpha Used with Color Parameters
// Variables
integer LightState = FALSE;
integer ComHandle;
// Switches
integer DebugMode = FALSE;
// Flags
// Menus
// Functions
Initialize(){
llOwnerSay("Initializing...");
ComChannel = (integer)llGetObjectDesc();
DebugMessage("Com Channel: "+(string)ComChannel);
llListenRemove(ComHandle);
llSleep(0.1);
ComHandle = llListen(ComChannel, EMPTY, EMPTY, EMPTY);
}
ProcessMessage(string msg){
list IncomingProperties = llParseString2List(msg, ["||"], []);
string tempstate = llList2String(IncomingProperties, STATE);
if(tempstate=="TRUE"){
LightState = TRUE;
}else{
LightState = FALSE;
}
DebugMessage("Light State: "+(string)LightState);
LightColor = llList2Vector(IncomingProperties, LIGHTCOLOR);
DebugMessage("Light Color: "+(string)LightColor);
WhiteColor = llList2Vector(IncomingProperties, WHITECOLOR);
DebugMessage("White Color: "+(string)WhiteColor);
Intensity = llList2Float(IncomingProperties, INTENSITY);
DebugMessage("Radius: "+(string)Radius);
Radius = llList2Float(IncomingProperties, RADIUS);
DebugMessage("Fall Off: "+(string)FallOff);
FallOff = llList2Float(IncomingProperties, FALLOFF);
DebugMessage("Pole Color: "+(string)PoleColor);
PoleColor = llList2Vector(IncomingProperties, POLECOLOR);
LightSwitch(LightState);
}
LightSwitch(integer Mode){
integer i;
if(Mode){
DebugMessage("Turning Light On...");
for(i=0;i<llGetListLength(LightFaces);i++){
llSetLinkPrimitiveParamsFast(llList2Integer(LightFaces, i), [
PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_POINT_LIGHT, TRUE, LightColor, Intensity, Radius, FallOff,
PRIM_GLOW, ALL_SIDES, GlowON,
PRIM_COLOR, ALL_SIDES, LightColor, Alpha
]);
}
for(i=0;i<llGetListLength(Poles);i++){
llSetLinkPrimitiveParamsFast(llList2Integer(Poles, i), [
PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_COLOR, ALL_SIDES, PoleColor, Alpha
]);
}
}else{
DebugMessage("Turning Light Off...");
for(i=0;i<llGetListLength(LightFaces);i++){
llSetLinkPrimitiveParamsFast(llList2Integer(LightFaces, i), [
PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
PRIM_POINT_LIGHT, FALSE, WhiteColor, Intensity, Radius, FallOff,
PRIM_GLOW, ALL_SIDES, GlowOFF,
PRIM_COLOR, ALL_SIDES, WhiteColor, Alpha
]);
}
for(i=0;i<llGetListLength(Poles);i++){
llSetLinkPrimitiveParamsFast(llList2Integer(Poles, i), [
PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
PRIM_COLOR, ALL_SIDES, WhiteColor, Alpha
]);
}
}
}
DebugMessage(string msg){
if(DebugMode){
llOwnerSay(msg);
}
}
// Main Program Operation
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
listen(integer chan, string server, key id, string message){
if(chan==ComChannel){
ProcessMessage(message);
}
}
}

View File

@@ -0,0 +1,262 @@
// Street Light Control Server v1.0
// Created by Tech Guy
// Configuration
// Constants
integer ServerComChannel; // Secret Negative Channel for Server Communication
integer MenuComChannel; // Channel for Menu Communication
integer ComHandle; // Hold Handle to Control Server Com Channel
integer MenuComHandle; // Handle for Menu Communications Listener
list AuthedUsers = []; // Wil Contain List of Authorized Users (For Menu)
string EMPTY = "";
float LightHoldLength = 0.1;
string cName = ".config"; // Name of Configuration NoteCard
// Indicator Light Config
float GlowOn = 0.10;
float GlowOff = 0.0;
list ONColorVectors = [<0.0,1.0,0.0>,<1.0,0.5,0.0>,<1.0,0.0,0.0>];
list ColorNames = ["Green", "Orange", "Red"];
list OFFColorVectors = [<0.0,0.5,0.0>,<0.5,0.25,0.0>,<0.5,0.0,0.0>];
integer PWRLIGHT = 2;
integer CFGLIGHT = 3;
integer INLIGHT = 4;
integer OUTLIGHT = 5;
// Variables
integer cLine; // Holds Configuration Line Index for Loading Config Loop
key cQueryID; // Holds Current Configuration File Line during Loading Loop
integer lightsOn = FALSE;
string PropertiesString; // Hold Compiled String of Light Properties and Colors
float HoldTimer; // Length of Timer before rerunning Sky Check after a manual light mode change.
// Light Parameters
vector LightColor = <1.0,1.0,0.0>; // Yellow
vector WhiteColor = <1.0,1.0,1.0>; // White
float Intensity = 1.0;
float Radius = 20.0;
float FallOff = 0.5;
// Light Pole Parameters
vector PoleColor = <1.0,1.0,0.851>;
float Alpha = 0.0; // Alpha Used with Color Parameters
// Switches
integer DebugMode = FALSE; // Are we running in with Debug Messages ON?
// Flags
// Configuration Directives
float CheckTimer = 30.0; // Frequency of Sun Angle Check Routine
// Functions
Initialize(){
llSleep(LightHoldLength);
llListenRemove(ComHandle);
llListenRemove(MenuComChannel);
llSleep(0.5);
ComHandle = llListen(ServerComChannel, EMPTY, EMPTY, EMPTY);
MenuComChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
DebugMessage(llGetObjectName()+" Server Online");
llOwnerSay("Configuring...");
cQueryID = llGetNotecardLine(cName, cLine);
}
LightToggle(integer LinkID, integer ISON, string Color){
if(ISON){
vector ColorVector = llList2Vector(ONColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOn,
PRIM_FULLBRIGHT, ALL_SIDES, TRUE
]);
}else{
vector ColorVector = llList2Vector(OFFColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOff,
PRIM_FULLBRIGHT, ALL_SIDES, FALSE
]);
}
}
LoadConfig(string data){
LightToggle(CFGLIGHT, TRUE, "Orange");
if(data!=""){ // If Line is not Empty
// if the line does not begin with a comment
if(llSubStringIndex(data, "#") != 0)
{
// find first equal sign
integer i = llSubStringIndex(data, "=");
// if line contains equal sign
if(i != -1){
// get name of name/value pair
string name = llGetSubString(data, 0, i - 1);
// get value of name/value pair
string value = llGetSubString(data, i + 1, -1);
// trim name
list temp = llParseString2List(name, [" "], []);
name = llDumpList2String(temp, " ");
// make name lowercase
name = llToLower(name);
// trim value
temp = llParseString2List(value, [" "], []);
value = llDumpList2String(temp, " ");
// Check Key/Value Pairs and Set Switches and Lists
if(name=="debugmode"){
if(value=="TRUE" || value=="true"){
DebugMode = TRUE;
llOwnerSay("Debug Mode: Enabled!");
}else if(value=="FALSE" || value=="false"){
DebugMode = FALSE;
llOwnerSay("Debug Mode: Disabled!");
}
}else if(name=="lightcolor"){ // Set Color of Light during On State
LightColor = (vector)value;
DebugMessage("Light Color: "+(string)LightColor);
}else if(name=="whitecolor"){
WhiteColor = (vector)value;
DebugMessage("White Color: "+(string)WhiteColor);
}else if(name=="intensity"){
Intensity = (float)value;
DebugMessage("Light Intensity: "+(string)Intensity);
}else if(name=="radius"){
Radius = (float)value;
DebugMessage("Light Radius: "+(string)Radius);
}else if(name=="falloff"){
FallOff = (float)value;
DebugMessage("Light FallOff: "+(string)FallOff);
}else if(name=="polecolor"){
PoleColor = (vector)value;
DebugMessage("Pole Color: "+(string)PoleColor);
}else if(name=="user"){
AuthedUsers = AuthedUsers + [value];
DebugMessage("New Machine Authed User: "+value);
}else if(name=="servercomchannel"){
ServerComChannel = (integer)value;
DebugMessage("Server Com Channel: "+(string)ServerComChannel);
}else if(name=="checktimer"){
CheckTimer = (float)value;
DebugMessage("Check Timer: "+(string)CheckTimer);
}else if(name=="holdtimer"){
HoldTimer = (float)value;
DebugMessage("Hold Timer: "+(string)HoldTimer);
}
LightToggle(CFGLIGHT, FALSE, "Orange");
}else{ // line does not contain equal sign
llOwnerSay("Configuration could not be read on line " + (string)cLine);
}
}
}
}
// Check Sun Angle Routine (If Below Horizon, Toggle Lights)
CheckSun()
{
vector sun = llGetSunDirection();
integer turnLightsOn = (sun.z < 0);
if(turnLightsOn != lightsOn)
{
DebugMessage("Sun Position Changed...");
lightsOn = turnLightsOn;
MessageLights(lightsOn); // Send Message to Lights
}
}
// Check if Light Should be on/off and send appropriate message
MessageLights(integer LightState){
string StateMessage;
if(LightState==TRUE){
DebugMessage("SunSet Detected, Messaging Lights...");
StateMessage = "TRUE";
}else if(LightState==FALSE){
DebugMessage("SunRise Detected, Messaging Lights...");
StateMessage = "FALSE";
}
string SendString = StateMessage + "||" + PropertiesString;
llRegionSay(ServerComChannel, SendString);
DebugMessage("Sending String: "+SendString+"\rOn Channel: "+(string)ServerComChannel);
}
DebugMessage(string msg){
if(DebugMode){
llOwnerSay(msg);
}
}
CompileProperties(){
DebugMessage("Compiling Properties String...");
list Properties = [LightColor, WhiteColor, Intensity, Radius, FallOff, PoleColor];
PropertiesString = llDumpList2String(Properties, "||");
DebugMessage("Properties String:\r"+PropertiesString);
}
// Main Program
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
LightToggle(PWRLIGHT, TRUE, "Red");
llSleep(LightHoldLength);
LightToggle(INLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
Initialize();
}
dataserver(key query_id, string data){ // Config Notecard Read Function Needs to be Finished
if (query_id == cQueryID){
if (data != EOF){
LoadConfig(data); // Process Current Line
++cLine; // Incrment Line Index
cQueryID = llGetNotecardLine(cName, cLine); // Attempt to Read Next Config Line (Re-Calls DataServer Event)
}else{ // IF EOF (End of Config loop, and on Blank File)
LightToggle(CFGLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(CFGLIGHT, FALSE, "Green");
CompileProperties();
// CHECK HERE
llSetTimerEvent(CheckTimer);
}
}
}
touch(integer num){
if(num>1){
return;
}
llSetTimerEvent(HoldTimer);
if(lightsOn){
DebugMessage("Turning Lights OFF for "+(string)CheckTimer+" Seconds!");
MessageLights(FALSE);
lightsOn = FALSE;
}else{
DebugMessage("Turning Lights ON for "+(string)CheckTimer+" Seconds!");
MessageLights(TRUE);
lightsOn = TRUE;
}
}
timer(){
llSetTimerEvent(CheckTimer);
if(DebugMode){
llOwnerSay("Checking Sun Angle...");
}
CheckSun();
}
changed(integer c){
if(c & CHANGED_INVENTORY){
llResetScript();
}
}
}

340
SwingingDoor/LICENSE.txt Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,127 @@
// Smooth Swinging Door Script v1.0 by Tech Guy
// Configuration
string SwingDirection = ""; // Inward vs Outward
string SwingMessage = "I do not know which way to swing.\nPlease enter either Inward or Outward (Case-Sensitive) into my description, Thanks";
// Variables
float MoveTimer = 2.5;
vector test; // Input Vector to Convert to Rotation
rotation rot; // Rotation Amount to Move
integer TotalTouched = 0; // Amount of Times Touched
// Switches
integer IsOpen = FALSE;
// Configuration Values Placeholders
float DoorCloseTimeOut = 0;
key nrofnamesoncard;
integer nrofnames;
list names;
list keynameoncard;
string nameoncard;
string storedname;
Initialize(){
SwingDirection = llGetObjectDesc();
if(SwingDirection==""){
llOwnerSay(SwingMessage);
}else if(SwingDirection=="Inward"){
test.x = 0;
test.y = 0;
test.z = 0.5 * PI;
}else if(SwingDirection=="Outward"){
test.x = 0;
test.y = 0;
test.z = -0.5 * PI;
}else{
llOwnerSay(SwingMessage);
}
llOwnerSay("Startup state reading whitelist notecard");
nrofnamesoncard = llGetNumberOfNotecardLines("whitelist");
}
OpenDoor(){
rot = llEuler2Rot(test);
llSetKeyframedMotion([rot, 2.5],[KFM_DATA, KFM_ROTATION, KFM_MODE, KFM_FORWARD]);
}
CloseDoor(){
rot = llEuler2Rot(test);
llSetKeyframedMotion([rot, 2.5],[KFM_DATA, KFM_ROTATION, KFM_MODE, KFM_REVERSE]);
}
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
touch(integer num){
TotalTouched = TotalTouched + num;
if(TotalTouched>1){
return;
}else if(llList2String(names, 0)!="" && llListFindList(names, [llDetectedName(0)])==-1){
llSay(0, "You are not allowed in!");
}else{
if(IsOpen){
llSetTimerEvent(0);
CloseDoor();
}else{
OpenDoor();
llSetTimerEvent(DoorCloseTimeOut);
}
IsOpen = !IsOpen;
}
}
touch_end(integer num){
TotalTouched = 0;
}
timer(){
llSetTimerEvent(0);
IsOpen = FALSE;
CloseDoor();
}
dataserver (key queryid, string data){
if (queryid == nrofnamesoncard)
{
nrofnames = (integer) data;
integer i;
for (i=0;i < nrofnames;i++){
keynameoncard += llGetNotecardLine("whitelist", i);
}
} else
{
integer listlength;
listlength = llGetListLength(keynameoncard);
integer j;
for(j=0;j<listlength;j++) {
if (queryid == (key) llList2String(keynameoncard,j))
{
if(data!=""){
llOwnerSay("Name added to whitelist: "+data);
names += data;
}else{
llOwnerSay("Security Turned Off.");
}
}
}
}
}
changed(integer change){
if(change & CHANGED_INVENTORY){
llResetScript();
}
}
}

View File

@@ -0,0 +1,26 @@
vector test;
rotation rot;
integer hidden = FALSE;
default
{
state_entry()
{
}
link_message(integer sender, integer num, string msg, key id){
if(msg=="TOGVIS"){
if(hidden){
// test.x = 0;
// test.z = 0;
// test.y = -0.5 * PI;
// rot = llEuler2Rot(test);
rot = llEuler2Rot(<0.000000,-1.570796,0.000000>);
llSetLocalRot(rot);
}else if(!hidden){
llSetLocalRot(ZERO_ROTATION);
}
hidden = !hidden;
}
}
}

View File

@@ -0,0 +1,20 @@
integer TotalTouched = 0;
default
{
state_entry()
{
}
touch(integer num){
TotalTouched = TotalTouched + num;
if(TotalTouched>1){
return;
}
llMessageLinked(LINK_ROOT, 0, "TOGVIS", "");
}
touch_end(integer num){
TotalTouched = 0;
}
}

33
TGAO/AttachScript.lsl Normal file
View File

@@ -0,0 +1,33 @@
integer DefaultAttachPoint = ATTACH_HUD_CENTER_2;
default
{
state_entry()
{
llRequestPermissions( llGetOwner(), PERMISSION_ATTACH );
}
run_time_permissions( integer vBitPermissions )
{
if ( vBitPermissions & PERMISSION_ATTACH )
llAttachToAvatar( DefaultAttachPoint );
else
llOwnerSay( "Permission to attach denied" );
}
on_rez(integer rez)
{
if (!llGetAttached()) //reset the script if it's not attached.
llResetScript();
}
attach(key id)
{
// The attach event is called on both attach and detach, but 'id' is only valid on attach
if (id){
llOwnerSay( "The object is attached to " + llKey2Name(id) );
}else {
llOwnerSay( "The object is not attached");
}
}
}

12
TGAO/ColorChanger.lsl Normal file
View File

@@ -0,0 +1,12 @@
default
{
link_message( integer _sender, integer _num, string _message, key _id)
{
// Coming from an interface script
if ( _message == "ZHAO_AOON" ) {
llSetColor(<0.2,1,0.2>, ALL_SIDES);
} else if ( _message == "ZHAO_AOOFF" ) {
llSetColor(<1,0.2,0.2>, ALL_SIDES);
}
}
}

375
TGAO/ConfigLoader.lsl Normal file
View File

@@ -0,0 +1,375 @@
integer counter;
// List of all the animation states
list animState = [ "Sitting on Ground", "Sitting", "Striding", "Crouching", "CrouchWalking",
"Soft Landing", "Standing Up", "Falling", "Hovering Down", "Hovering Up",
"FlyingSlow", "Flying", "Hovering", "Jumping", "PreJumping", "Running",
"Turning Right", "Turning Left", "Walking", "Landing", "Standing", "Dancing" ];
// Logic change - we now have a list of tokens. The 'overrides' list is the same length as this,
// i.e. it has one entry per token, *not* one entry per animation. Multiple options for a token
// are stored as | separated strings in a single list entry. This was done to save memory, and
// allow a larger number of stands etc. All the xxxIndex variables now refer to the token index,
// since that's how long 'overrides' is.
// List of internal tokens. This *must* be in the same sequence as the animState list. Note that
// we combine some tokens after the notecard is read (striding/walking, landing/soft landing), etc.
// The publicized tokens list only contains one entry for each pair, but we'll accept both, and
// combine them later
list tokens = [
"[ Sitting On Ground ]", // 0
"[ Sitting ]", // 1
"", // 2 - We don't allow Striding as a token
"[ Crouching ]", // 3
"[ Crouch Walking ]", // 4
"", // 5 - We don't allow Soft Landing as a token
"[ Standing Up ]", // 6
"[ Falling ]", // 7
"[ Flying Down ]", // 8
"[ Flying Up ]", // 9
"[ Flying Slow ]", // 10
"[ Flying ]", // 11
"[ Hovering ]", // 12
"[ Jumping ]", // 13
"[ Pre Jumping ]", // 14
"[ Running ]", // 15
"[ Turning Right ]", // 16
"[ Turning Left ]", // 17
"[ Walking ]", // 18
"[ Landing ]", // 19
"[ Standing ]", // 20
"[ Swimming Down ]", // 21
"[ Dancing ]", // 22 For Dancing Animations
"[ Swimming Up ]", // 23
"[ Swimming Forward ]", // 24
"[ Floating ]", // 25
"[ Typing ]", // 26
"[ Settings ]" // 27 this is new... we'll see how i can make it work
];
// The tokens for which we allow multiple animations
list multiAnimTokenIndexes = [
0, // "[ Sitting On Ground ]"
1, // "[ Sitting ]"
18, // "[ Walking ]"
20, // "[ Standing ]"
15, // "[ Running ]"
22 // "[ Dancing ]"
];
// Index of interesting animations
integer noAnimIndex = -1;
integer sitgroundIndex = 0;
integer sittingIndex = 1;
integer stridingIndex = 2;
integer standingupIndex = 6;
integer hoverdownIndex = 8;
integer hoverupIndex = 9;
integer flyingslowIndex = 10;
integer flyingIndex = 11;
integer hoverIndex = 12;
integer walkingIndex = 18;
integer standingIndex = 20;
integer swimdownIndex = 21;
integer swimupIndex = 22;
integer swimmingIndex = 23;
integer waterTreadIndex = 24;
integer typingIndex = 25;
integer settingsIndex = 26;
integer dancingIndex = 22;
list overrides = []; // List of animations we override
key notecardLineKey; // notecard reading keys
integer notecardIndex; // current line being read from notecard
integer numOverrides; // # of overrides
string notecardName = ""; // The notecard we're currently reading
// String constants to save a few bytes
string EMPTY = "";
string SEPARATOR = "|";
string TIMINGSEPARATOR = ":";
string TRYAGAIN = "Please correct the notecard and try again.";
string FLAG = "flag";
string VAR = "var";
string COMMANDS = "commands";
// Settings keywords, their type and respective command(s)
// e.g. Standtime would be tye variable and the command is ZHAO_STANDTIME|<time>
// "Time", VAR, "ZHAO_STANDTIME|",
// ... TypingAO is type flag and the commands are ZHAO_TYPEAO_ON/ZHAO_TYPEAO_OFF
// "Type", FLAG, "ZHAO_TYPE_"
// ... those 2 suck bad:
// ZHAO_RANDOMSTANDS Stands cycle randomly
// ZHAO_SEQUENTIALSTANDS Stands cycle sequentially
// they get the type COMMANDS
list settingsKeywords = [
"standtime", "var", "ZHAO_STANDTIME|",
"random", "commands", "ZHAO_RANDOMSTANDS", "ZHAO_SEQUENTIALSTANDS",
"typingao", "flag", "ZHAO_TYPEAO_",
"typingkill", "flag", "ZHAO_TYPEKILL_",
"mouselook", "flag", "ZHAO_MOUSELOOK_"
];
// Load all the animation names from a notecard
loadNoteCard()
{
// Clear out saved override information, since we now allow sparse notecards
overrides = [];
integer i;
for ( i=0; i<numOverrides; i++ )
overrides += [EMPTY];
llOwnerSay( "Loading notecard '" + notecardName + "'..." );
// Faster events while processing our notecard
llMinEventDelay( 0.0 );
counter = 0;
// Start reading the data
notecardIndex = 0;
notecardLineKey = llGetNotecardLine( notecardName, notecardIndex );
}
// Stop loading notecard
endNotecardLoad(integer success)
{
if(success)
{
llOwnerSay((string)counter + " animation entries found in Notecard.");
llMessageLinked(LINK_SET, success, "END_NC_LOAD|" + llList2CSV(overrides), NULL_KEY);
}
else
{
llMessageLinked(LINK_SET, success, "END_NC_LOAD|", NULL_KEY);
}
notecardName = EMPTY;
}
checkAnimInInventory( string _csvAnims )
{
list anims = llCSV2List( _csvAnims );
integer i;
for( i=0; i<llGetListLength(anims); i++ ) {
string animName = llList2String( anims, i );
if ( llGetInventoryType( animName ) != INVENTORY_ANIMATION ) {
// Only a warning, so built-in anims can be used
llOwnerSay( "Warning: Couldn't find animation '" + animName + "' in inventory." );
}
}
}
// Checks for too many animations - can't do menus with > 12 animations
checkMultiAnim( integer _animIndex, string _animName )
{
list animsList = llParseString2List( llList2String(overrides, _animIndex), [SEPARATOR], [] );
if ( llGetListLength(animsList) > 12 )
llOwnerSay( "You have more than 12 " + _animName + " animations (You will be able to choose from only the first 12). Please correct this." );
}
//read Settings from NC and send them
doSettings(string settingsPart)
{
integer i = 0;
list settings = llParseString2List( settingsPart, [SEPARATOR], [] );
for( i=0; i < llGetListLength(settings); i++)
{
list aSetting = llParseString2List( llList2String(settings, i), [TIMINGSEPARATOR], [] );
if( 2 == llGetListLength(aSetting) )
{
string settingName = llToLower(llList2String(aSetting, 0));
integer settingValue = llList2Integer(aSetting, 1);
if( ( settingValue >= 0 ) && ( settingValue <= 1000 ) )
{
integer sIndex = llListFindList(settingsKeywords, [settingName]);
if( sIndex != -1 )
{
string msg = "";
if(VAR == llList2String(settingsKeywords, (sIndex + 1)))
{
msg = llList2String(settingsKeywords, (sIndex + 2));
msg += (string)settingValue;
}
else if(FLAG == llList2String(settingsKeywords, (sIndex + 1)))
{
msg = llList2String(settingsKeywords, (sIndex + 2));
if(settingValue)
{
msg += "ON";
}
else
{
msg += "OFF";
}
}
else if(FLAG == llList2String(settingsKeywords, (sIndex + 1)))
{
if(settingValue)
{
msg = llList2String(settingsKeywords, (sIndex + 2));
}
else
{
msg = llList2String(settingsKeywords, (sIndex + 3));
}
}
llMessageLinked(LINK_SET, 0, msg, NULL_KEY);
}
}
}
}
}
default
{
state_entry()
{
llMinEventDelay( 0 );
numOverrides = llGetListLength( tokens );
}
link_message(integer _sender, integer _num, string _message, key _id)
{
if ( llGetSubString(_message, 0, 7) == "LOAD_NC|" ) {
notecardName = llGetSubString(_message, 8, llStringLength(_message) - 1);
loadNoteCard();
}
}
dataserver( key _query_id, string _data )
{
if ( _query_id != notecardLineKey ) {
llOwnerSay( "Error in reading notecard. Please try again." );
endNotecardLoad(FALSE);
return;
}
if ( _data == EOF ) {
// Now the read ends when we hit EOF
// See how many walks/sits/ground-sits we have
checkMultiAnim( walkingIndex, "walking" );
checkMultiAnim( sittingIndex, "sitting" );
checkMultiAnim( sitgroundIndex, "sitting on ground" );
checkMultiAnim( dancingIndex, "dancing" );
endNotecardLoad(TRUE);
return;
}
// We ignore blank lines and lines which start with a #
if (( _data == EMPTY ) || ( llGetSubString(_data, 0, 0) == "#" )) {
notecardLineKey = llGetNotecardLine( notecardName, ++notecardIndex );
return;
}
// Check for a valid token
integer i;
integer found = FALSE;
for ( i=0; i<numOverrides; i++ ) {
string token = llList2String( tokens, i );
// We have some blank entries in 'tokens' to get it to line up with animState... make
// sure we don't match on a blank.
if (( token != EMPTY ) && ( llGetSubString( _data, 0, llStringLength(token) - 1 ) == token )) {
// We found a token on this line, so we don't have to throw an error or keep
// trying to match tokens
found = TRUE;
// Make sure the line has data after the token, or our sub-string calculation goes off
if ( _data != token ) {
string animPart = llGetSubString( _data, llStringLength(token), -1 );
//check for [ Settings ] token
if( llListFindList( tokens, [token] ) == settingsIndex ) {
doSettings(animPart);
}
// See if this is a token for which we allow multiple animations
else if ( llListFindList( multiAnimTokenIndexes, [i] ) != -1 ) {
list anims2Add = llParseString2List( animPart, [SEPARATOR], [] );
// Make sure the anims exist
integer j;
for ( j=0; j<llGetListLength(anims2Add); j++ ) {
//
// Mod: Cut the animation name from time parameter:
list newAnim = llParseStringKeepNulls( llList2String(anims2Add,j), [TIMINGSEPARATOR], [] );
string newAnimName = llList2String(newAnim, 0);
if(llGetListLength(newAnim) > 1)
{
integer timr = FALSE;
integer ix = 1;
for(ix = 1; ix < llGetListLength(newAnim) ; ix++)
{
timr = timr || llList2Integer(newAnim, ix);
}
if(timr > 0)
{
string str = llDumpList2String(newAnim, "²Ø");
anims2Add = llListReplaceList(anims2Add, [ str ], j, j);
}
if(!timr)
{
newAnimName = llDumpList2String(newAnim, "");
}
}
//
//
// checkAnimInInventory( llList2String(anims2Add,j) );
checkAnimInInventory( newAnimName );
++counter;
}
// Join the 2 lists and put it back into overrides
list currentAnimsList = llParseString2List( llList2String(overrides, i), [SEPARATOR], [] );
currentAnimsList = currentAnimsList + anims2Add;
overrides = llListReplaceList( overrides, [llDumpList2String(currentAnimsList, SEPARATOR)], i, i );
} else {
// This is an animation for which we only allow one override
if ( llSubStringIndex( animPart, SEPARATOR ) != -1 ) {
llOwnerSay( "Cannot have multiple animations for " + token + ". " + TRYAGAIN );
endNotecardLoad(FALSE);
return;
}
// Inventory check
checkAnimInInventory( animPart );
++counter;
// We're good
overrides = llListReplaceList( overrides, [animPart], i, i );
} // End if-else for multi-anim vs. single-anim
} // End if line has more than just a token
// Break, no need to continue the search loop
jump done;
} // End if token matched
} // End search for tokens
@done;
if ( !found ) {
llOwnerSay( "Could not recognize token on line " + (string)notecardIndex + ": " +
_data + ". " + TRYAGAIN );
endNotecardLoad(FALSE);
return;
}
// Wow, after all that, we read one line of the notecard
notecardLineKey = llGetNotecardLine( notecardName, ++notecardIndex );
return;
}
}

1254
TGAO/Core.lsl Normal file

File diff suppressed because it is too large Load Diff

604
TGAO/Interface.lsl Normal file
View File

@@ -0,0 +1,604 @@
// ZHAO-II-interface - Ziggy Puff, 06/07
////////////////////////////////////////////////////////////////////////
// Interface script - handles all the UI work, sends link
// messages to the ZHAO-II 'engine' script
//
// Interface definition: The following link_message commands are
// handled by the core script. All of these are sent in the string
// field. All other fields are ignored
//
// ZHAO_RESET Reset script
// ZHAO_LOAD|<notecardName> Load specified notecard
// ZHAO_NEXTSTAND Switch to next stand
// ZHAO_STANDTIME|<time> Time between stands. Specified
// in seconds, expects an integer.
// 0 turns it off
// ZHAO_AOON AO On
// ZHAO_AOOFF AO Off
// ZHAO_SITON Sit On
// ZHAO_SITOFF Sit Off
// ZHAO_RANDOMSTANDS Stands cycle randomly
// ZHAO_SEQUENTIALSTANDS Stands cycle sequentially
// ZHAO_SETTINGS Prints status
// ZHAO_SITS Select a sit
// ZHAO_GROUNDSITS Select a ground sit
// ZHAO_WALKS Select a walk
//
// ZHAO_SITANYWHERE_ON Sit Anywhere mod On
// ZHAO_SITANYWHERE_OFF Sit Anywhere mod Off
//
// ZHAO_TYPE_ON Typing AO On
// ZHAO_TYPE_OFF Typing AO Off
//
// ZHAO_TYPEKILL_ON Typing Killer On
// ZHAO_TYPEKILL_OFF Typing Killer Off
//
// So, to send a command to the ZHAO-II engine, send a linked message:
//
// llMessageLinked(LINK_SET, 0, "ZHAO_AOON", NULL_KEY);
//
////////////////////////////////////////////////////////////////////////
// Johann Ehrler, 12/13/2008:
// ZHAO failed to recognize owner change...FIXED!
// This interface send a reset request to all other scripts if owner changed.
// Marcus Gray/Johann Ehrler, 09/28/2008:
// Added ability to toggle stand ON or OFF.
// Johann Ehrler, 09/16/2008:
// Provisory added ability to control the ZHAO's power switch via chat line or a gesture.
// TODO: Rethink about the currently implementation. xD
//
// WARNING: This script was MONO-recompiled!
// Marcus Gray, 04/06/2008:
// Added TypingAO support with new NC-token [ Typing ] & Typing-kill-functionality (core)
// Dialog-Menu entries for TypingAO & TypingKill ...made 14 buttons which forces me to do multipage dialog...
// f**k!!! (interface)
// Freed huge amount of mem by moving NC-loading to an extra script (core --> zhao-II-loadcards)
// Marcus Gray, 03/26/2008:
// Included Seamless Sit mod by Moeka Kohime (core script).
// Freed some memory DELETING THE DEFAULT UNOVERRIDABLE ANIMS!!!!!!!! (core script)
// Added sit anywhere functionality to replace stands by groundsits (core script).
// Therefore changed functionality of Sit-ON/OFF button to work as Sit Anywhere button (interface).
// Johann Ehrler, 08/01/2007:
// Color-mod - Now you can use standard RGB-notation for the ON-OFF-states.
// Link names - You can use the link names instead the link numbers
// Marcus Gray, 08/01/2007:
// Added some extra buttons for easier access of the main functions.
// Created new funtions loadNotecard() and toggleSit() containing the code now used by Dialog/Listen AND Button handling.
// In addition, swapped Menu and Sit-ON/OFF buttons
// Ziggy, 07/16/07 - Single script to handle touches, position changes, etc., since idle scripts take up
//
// Ziggy, 06/07:
// Single script to handle touches, position changes, etc., since idle scripts take up
// scheduler time
// Tokenize notecard reader, to simplify notecard setup
// Remove scripted texture changes, to simplify customization by animation sellers
// Fennec Wind, January 18th, 2007:
// Changed Walk/Sit/Ground Sit dialogs to show animation name (or partial name if too long)
// and only show buttons for non-blank entries.
// Fixed minor bug in the state_entry, ground sits were not being initialized.
//
// Dzonatas Sol, 09/06: Fixed forward walk override (same as previous backward walk fix).
// Based on Francis Chung's Franimation Overrider v1.8
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Help notecard
string helpNotecard = "READ ME FIRST - ZHAO-II";
// How long before flipping stand animations
integer standTimeDefault = 30;
// Listen channel for pop-up menu...
// should be different from channel used by ZHAO engine (-91234)
//
// Mod: Channel will now be generated from owner UUID.
integer listenChannel = -2; //-91235;
integer listenHandle; // Listen handlers - only used for pop-up menu, then turned off
integer listenState = 0; // What pop-up menu we're handling now
// Overall AO state
integer zhaoOn = TRUE;
////////////////////////////////////////////////////////////
// BEGIN mod by Johann Ehrler - 08/01/2007
//
// Link names/numbers for the extra buttons:
string btnMenu = "menu"; //Menu button
string btnLNC = "load"; //Load notecard button
string btnTSitOnOff = "sit_toggle"; //Sit-ON/OFF button
string btnTSitAW = "toggle_gs_ao"; //Sit ANYWHERE-ON/OFF button
string btnWalk = "walks"; //Choose walk button
string btnGSits = "groundsits"; //Choose groundsit button
string btnSits = "sits"; //Choose sit button
string btnTStandOnOff = "standtoggle"; //Stand-ON/OFF button
string btnNStand = "nextstand"; //Play next stand button
string btnMinMax = "minmax"; //Minimize/Maximize button
string btnHelp = "help"; //HELP button
string btnRuns = "Runs"; //Runs Button
string btnDanceAO = "dancetoggle"; //Dance AO Button
string btnNextDance = "nextdance"; // Next Dance Button
string btnDances = "dances"; // Dances Menu Button
//
// END Mod by Johann Ehrler
////////////////////////////////////////////////////////////
// Interface script now keeps track of these states. The defaults
// match what the core script starts out with
integer standOverride = TRUE;
integer sitOverride = TRUE;
integer danceOverride = FALSE;
integer sitAnywhere = FALSE;
integer randomStands = FALSE;
integer randomRuns = FALSE;
integer randomDance = FALSE;
integer typingOverrideOn = TRUE; // Whether we're overriding typing or not
integer typingKill = FALSE; // Whether we're killing the typing completely
key Owner = NULL_KEY;
// MENU VARS
integer MMAIN = 0;
integer MSIT = 1;
integer MSTAND = 2;
integer MRUN = 3;
integer MDANCE = 4;
integer menuState = 0;
// CODE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize listeners, and reset some status variables
Initialize() {
Owner = llGetOwner();
// On init, open a new listener...
if ( listenHandle )
llListenRemove( listenHandle );
// Generate the channel from the owner UUID and adds 1 cuz we need a different channel as the core script.
listenChannel = ( 1 + (integer)( "0xF" + llGetSubString( llGetOwner(), 0, 6) ) ) + 1;
listenHandle = llListen( listenChannel, "", Owner, "" );
// ... And turn it off
llListenControl(listenHandle, FALSE);
}
DoMenu()
{
// The rows are inverted in the actual dialog box. This must match
// the checks in the listen() handler
string menutxt = "Please select an option:\n \n";
list buttons = [];
if(menuState == MMAIN)
{
menutxt += "Submenus:";
menutxt += "\n \tSIT: Sit-submenu";
menutxt += "\n \tSTAND: Stand-submenu";
menutxt += "\n \tRUN: Run-submenu";
buttons = [
"Walks", "SIT", "STAND", "RUN", "DANCE",
"Load", "Settings", "Next Stand",
"Help", "Reset"
];
listenState = 0;
}
else if(menuState == MSIT)
{
buttons = [
"Sits", "Ground Sits",
"Sit On/Off", "Sit Anywhere",
"MAIN"
];
}
else if(menuState == MSTAND)
{
buttons = [
"Rand/Seq", "Stand Time", "Next Stand",
"MAIN"
];
}
else if(menuState == MRUN)
{
buttons = [
"Rand/Single", "Select Run",
"MAIN"
];
}
else if(menuState == MDANCE)
{
buttons = [
"Rand/Single", "Select Dance",
"MAIN"
];
}
llListenControl(listenHandle, TRUE);
llDialog( Owner, menutxt, buttons, listenChannel );
}
////////////////////////////////////////////////////////////
// BEGIN mod by Marcus Gray - 08/01/2007
// new functions for now multi-used code for loading notecards and toggling sit
//
loadNotecard()
{
integer n = llGetInventoryNumber( INVENTORY_NOTECARD );
// Can only have 12 buttons in a dialog box
if ( n > 13 ) {
llOwnerSay( "You cannot have more than 12 animation notecards." );
return;
}
integer i;
list animSets = [];
// Build a list of notecard names and present them in a dialog box
for ( i = 0; i < n; i++ ) {
string notecardName = llGetInventoryName( INVENTORY_NOTECARD, i );
if ( notecardName != helpNotecard )
animSets += [ notecardName ];
}
llListenControl(listenHandle, TRUE);
llDialog( Owner, "Select the notecard to load:", animSets, listenChannel );
listenState = 1;
}
toggleAO()
{
if (zhaoOn) {
llOwnerSay("Sending OFF Signal...");
llMessageLinked(LINK_SET, 0, "ZHAO_AOOFF", NULL_KEY);
} else {
llOwnerSay("Sending ON Signal...");
llMessageLinked(LINK_SET, 0, "ZHAO_AOON", NULL_KEY);
}
zhaoOn = !zhaoOn;
}
toggleStand()
{
//s t a n d BUTTON COLOR IS HANDLED BY A SCRIPT INSIDE THE BUTTON ITSELF!!!
if (standOverride == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_STANDOFF", NULL_KEY);
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_STANDON", NULL_KEY);
}
standOverride = !standOverride;
}
toggleSit()
{
//SIT BUTTON COLOR IS HANDLED BY A SCRIPT INSIDE THE BUTTON ITSELF!!!
if (sitOverride == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_SITOFF", NULL_KEY);
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_SITON", NULL_KEY);
}
sitOverride = !sitOverride;
}
toggleSitAnywhere()
{
//SIT ANYWHERE BUTTON COLOR IS HANDLED BY A SCRIPT INSIDE THE BUTTON ITSELF!!!
if (sitAnywhere == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_SITANYWHERE_OFF", NULL_KEY);
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_SITANYWHERE_ON", NULL_KEY);
}
sitAnywhere = !sitAnywhere;
}
toggleTyping()
{
//SIT ANYWHERE BUTTON COLOR IS HANDLED BY A SCRIPT INSIDE THE BUTTON ITSELF!!!
if (typingOverrideOn == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_TYPEAO_OFF", NULL_KEY);
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_TYPEAO_ON", NULL_KEY);
}
typingOverrideOn = !typingOverrideOn;
}
toggleTypingKill()
{
//SIT ANYWHERE BUTTON COLOR IS HANDLED BY A SCRIPT INSIDE THE BUTTON ITSELF!!!
if (typingKill == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_TYPEKILL_OFF", NULL_KEY);
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_TYPEKILL_ON", NULL_KEY);
}
typingKill = !typingKill;
}
toggleDanceAO()
{
//SIT ANYWHERE BUTTON COLOR IS HANDLED BY A SCRIPT INSIDE THE BUTTON ITSELF!!!
if (danceOverride == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_DANCEOFF", NULL_KEY);
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_DANCEON", NULL_KEY);
}
danceOverride = !danceOverride;
}
help()
{
if (llGetInventoryType(helpNotecard) == INVENTORY_NOTECARD)
llGiveInventory(Owner, helpNotecard);
else
llOwnerSay("No help notecard found.");
}
//
// END mod by Marcus Gray
////////////////////////////////////////////////////////////
// STATE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
default {
state_entry() {
Initialize();
// Sleep a little to let other script reset (in case this is a reset)
llSleep(2.0);
// We start out as AO ON
zhaoOn = TRUE;
llMessageLinked(LINK_SET, 0, "ZHAO_AOON", NULL_KEY);
//stand override ON by default
llMessageLinked(LINK_SET, 0, "ZHAO_STANDON", NULL_KEY);
standOverride = TRUE;
//sit override ON by default
llMessageLinked(LINK_SET, 0, "ZHAO_SITON", NULL_KEY);
sitOverride = TRUE;
//sit anywhere OFF by default
llMessageLinked(LINK_SET, 0, "ZHAO_SITANYWHERE_OFF", NULL_KEY);
sitAnywhere = FALSE;
//show ZHAO
llMessageLinked(LINK_SET, 0, "ZHAO_SHOW", NULL_KEY);
//typing AO & typing Killer
llMessageLinked(LINK_SET, 0, "ZHAO_TYPEAO_OFF", NULL_KEY);
llMessageLinked(LINK_SET, 0, "ZHAO_TYPEKILL_OFF", NULL_KEY);
}
on_rez( integer _code ) {
Initialize();
}
touch_start( integer _num ) {
////////////////////////////////////////////////////////////
// BEGIN mod by Marcus Gray - 08/01/2007
//
integer lntmp = llDetectedLinkNumber(0);
string btmp = llGetLinkName(lntmp);
if (btmp == btnMenu) {
// Menu prim... use number instead of name
DoMenu();
}
//
// Added button handlers
//
else if (btmp == btnLNC) {
loadNotecard();
}
else if (btmp == btnTSitAW) {
toggleSitAnywhere();
}
else if (btmp == btnTSitOnOff) { //while btnTSit == btnTSitAW this won't be reached!
toggleSit();
}
else if (btmp == btnTStandOnOff) { //while btnTSit == btnTSitAW this won't be reached!
toggleStand();
}
else if(btmp == btnRuns){
menuState = MRUN;
DoMenu();
}
else if(btmp == btnDances){
menuState = MDANCE;
DoMenu();
}
else if (btmp == btnWalk) {
llMessageLinked(LINK_SET, 0, "ZHAO_WALKS", NULL_KEY);
}
else if (btmp == btnGSits) {
llMessageLinked(LINK_SET, 0, "ZHAO_GROUNDSITS", NULL_KEY);
}
else if (btmp == btnSits) {
llMessageLinked(LINK_SET, 0, "ZHAO_SITS", NULL_KEY);
}
else if (btmp == btnNStand) {
llMessageLinked(LINK_SET, 0, "ZHAO_NEXTSTAND", NULL_KEY);
}
else if (btmp == btnMinMax) {
llMessageLinked(LINK_SET, 0, "ZHAO_TOGGLE_SHOW", NULL_KEY);
}
else if (btmp == btnDanceAO) {
toggleDanceAO();
}
else if (btmp == btnNextDance) {
llMessageLinked(LINK_SET, 0, "ZHAO_NEXTDANCE", NULL_KEY);
}
else if (btmp == btnHelp) {
help();
}
//
// END mod by Marcus Gray
////////////////////////////////////////////////////////////
else if (lntmp == 1) {
// On/Off prim ==> MYSELF ^^
toggleAO();
}
}
listen( integer _channel, string _name, key _id, string _message) {
// Turn listen off. We turn it on again if we need to present
// another menu.
llListenControl(listenHandle, FALSE);
if ( _message == "Help" ) {
help();
}
else if ( _message == "Reset" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_RESET", NULL_KEY);
llSleep(1.0);
llResetScript();
}
else if ( _message == "Settings" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_SETTINGS", NULL_KEY);
}
else if ( _message == "MAIN" ) {
menuState = MMAIN;
DoMenu();
}
else if ( _message == "SIT" ) {
menuState = MSIT;
DoMenu();
}
else if ( _message == "STAND" ) {
menuState = MSTAND;
DoMenu();
}
else if ( _message == "RUN" ) {
menuState = MRUN;
DoMenu();
}
else if ( _message == "DANCE" ) {
menuState = MDANCE;
DoMenu();
}
else if ( _message == "Sit On/Off" ) {
//code moved to toggleSit() by Marcus Gray
toggleSit();
}
else if ( _message == "TypingAO" ) {
//code moved to toggleTyping() by Marcus Gray
toggleTyping();
}
else if ( _message == "TypingKill" ) {
//code moved to toggleTypingKill() by Marcus Gray
toggleTypingKill();
}
else if ( _message == "Sit Anywhere" ) {
//toggleSitAnywhere() by Marcus Gray
toggleSitAnywhere();
}
else if ( _message == "Rand/Seq" ) {
if (randomStands == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_SEQUENTIALSTANDS", NULL_KEY);
randomStands = FALSE;
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_RANDOMSTANDS", NULL_KEY);
randomStands = TRUE;
}
}
else if ( _message == "Rand/Single" && menuState == 3 ) {
if (randomRuns == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_SINGLERUN", NULL_KEY);
randomRuns = FALSE;
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_RANDOMRUN", NULL_KEY);
randomRuns = TRUE;
}
}
else if ( _message == "Rand/Single" && menuState == 4 ) {
if (randomDance == TRUE) {
llMessageLinked(LINK_SET, 0, "ZHAO_SINGLEDANCE", NULL_KEY);
randomDance = FALSE;
} else {
llMessageLinked(LINK_SET, 0, "ZHAO_RANDOMDANCE", NULL_KEY);
randomDance = TRUE;
}
}
else if ( _message == "Next Stand" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_NEXTSTAND", NULL_KEY);
}
else if ( _message == "Load" ) {
//code moved to loadNotecard() by Marcus Gray
loadNotecard();
}
else if ( _message == "Stand Time" ) {
// Pick stand times
list standTimes = ["0", "5", "10", "15", "20", "30", "40", "60", "90", "120", "180", "240"];
llListenControl(listenHandle, TRUE);
llDialog( Owner, "Select stand cycle time (in seconds). \n\nSelect '0' to turn off stand auto-cycling.",
standTimes, listenChannel);
listenState = 2;
}
else if ( _message == "Select Run" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_RUNS", NULL_KEY);
}
else if ( _message == "Select Dance" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_DANCES", NULL_KEY);
}
else if ( _message == "Sits" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_SITS", NULL_KEY);
}
else if ( _message == "Walks" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_WALKS", NULL_KEY);
}
else if ( _message == "Ground Sits" ) {
llMessageLinked(LINK_SET, 0, "ZHAO_GROUNDSITS", NULL_KEY);
}
else if ( listenState == 1 ) {
// Load notecard
llMessageLinked(LINK_SET, 0, "ZHAO_LOAD|" + _message, NULL_KEY);
}
else if ( listenState == 2 ) {
// Stand time change
llMessageLinked(LINK_SET, 0, "ZHAO_STANDTIME|" + _message, NULL_KEY);
}
}
changed(integer _change) {
if(_change & CHANGED_OWNER) {
llMessageLinked(LINK_SET, 0, "ZHAO_RESET", NULL_KEY);
llSleep(1.0);
llResetScript();
}
}
}

21
TGLM/MENUITEMS.Test.txt Normal file
View File

@@ -0,0 +1,21 @@
// Single Person Animations
MENU Single | ALL | WHITE
POSE Sleep Back | sleeping-onback
POSE Sleep Front | sleeping-stomach
POSE Breakfast | breakfastinbed
POSE Read | read-a-book-onstomach
POSE Meditate | meditate
SWAP
STOP
BACK
MENU Cuddles | ALL | BLUE | PINK
POSE Memories | makingmemories-m | makingmemories-f
POSE Cuddle 03 | Cuddle 03M | Cuddle 03F
POSE Cuddle 04 | Cuddle KM | Cuddle KF
POSE Cuddle 05 | Cuddle LM | Cuddle LF
SWAP
STOP
BACK

74
TGLM/MENUITEMS.txt Normal file
View File

@@ -0,0 +1,74 @@
POSE stand | stand | stand | stand //pose before starting and when stopping
POSE default | sit_ground | sit_ground | sit_ground //default pose when no animation entered
MENUORDER // use new (sane) menu button order -- same as in files. Omit this for WELM compatibility.
// NORELOAD // inhibit reload on rez -- use for worn item, but "Menu Reset" if you make a copy!
MENU MAIN MENU | ALL
// link-message button. LINKMSG buttonname | parms
// where parms is a comma-separated list: menu,primnum,lm-num-arg,lm-str-arg
// menu is 1 if the LM will cause a menu, or 0 if not (to avoid menu stacking if remenu is on).
// primnum is the primitive number (see llMessageLinked() docs)
// lm-num-arg is the 'num' arg in the LM. If sending to same prim as WELM, avoid -100 to 100 range.
// lm-str-arg is the 'str' arg in the LM
// The menu user's key is passed as the LM 'key' arg.
//
// Example (commented out):
// LINKMSG Show/Hide | 0,-4,-100,show-hide
// -- inhibits remenu and calls llMessageLinked(-4, 100, "textures", toucherKey)
TOMENU - // 10 (total) blank spaces for modular configs. Unused entries are automatically deleted.
TOMENU -
TOMENU -
TOMENU -
TOMENU -
TOMENU -
TOMENU -
TOMENU -
TOMENU -
TOMENU -
STOP //remove poseballs
TOMENU OPTIONS // options menu
MENU OPTIONS | OWNER //this menu can be accessed by the OWNER only (other options: GROUP / ALL)
BALLUSERS BallUsers | ALL //switches who can sit on the poseballs: ALL/GROUP (set default)
MENUUSERS MenuUsers | ALL //switches who access main menu: ALL/GROUP/OWNER (set default)
ADJUST Adjust Pos //changes poseballs into transparant beams easy to select for moving
DUMP Dump Pos //lists all positions stored in memory, copy/paste into .POSITIONS for backup
SAVE Save Pos //saves the poseball positions of the currently selected pose into memory
TOMENU Height
LINKMSG Dump Props | 0,-4,1,DUMPPROPS // dump all prop configs
LINKMSG Save Prop | 0,-4,1,SAVEPROP // save position/rotation for a prop
CHAT Chat Info | ON //switches chat info: ON/OFF (set default)
TOMENU ShutDown...
BACK
//REDO RedoMenu | ON //switches if menu reappears automatically: ON/OFF (set default)
//INVISIBLE Invisible //make the main object invisible/visible (usefull if it's worn)
//SHOW //put this in some menu in case you want an option to show/hide the balls
//HIDE //(usually not needed, as the balls are created and removed in a click)
MENU Height | OWNER
Z+1 //adjust Z = height offset in cm - use any integer to set the step size
Z+5 // (note: the Z-buttons are deactivated for other users)
Z+25
Z-1
Z-5
Z-25
BACK
MENU ShutDown... | OWNER
RELOAD Pos Reset // use after changing *.POSITIONS* or *.PROPS* files
RESTART Restart // solves any problem but stack/heap collision (tools->reset scripts for that)
CHECK ConfigCheck // check config consistency. NOTE: does a Pos Reset when done!
RESET Menu Reset // use after changing *.MENUITEMS* files
OFF ShutDown! //(note: only the owner can Shutdown/Startup, even if menu set to ALL)
BACK

9
TGLM/POSITIONS.txt Normal file
View File

@@ -0,0 +1,9 @@
{Sleep Back} <-0.445,1.354,0.629> <-4.8,0.2,176.6>
{Sleep Front} <-0.282,1.373,0.632> <0.0,0.0,178.0>
{Breakfast} <-0.786,2.144,0.675> <-4.2,-7.0,-92.0>
{Read} <-0.820,1.179,0.537> <0.0,0.0,178.0>
{Meditate} <-0.783,2.230,0.561> <-14.1,-7.7,-62.0>
{Memories} <0.697,1.242,0.723> <-2.4,16.1,177.9> <-0.076,1.240,0.706> <-1.8,5.7,178.0>
{Cuddle 03} <-0.783,2.230,0.467> <-14.1,-7.7,-62.0> <0.783,2.357,0.439> <-17.9,6.4,-109.0>
{Cuddle 04} <-0.783,2.230,0.467> <-14.1,-7.7,-62.0> <0.783,2.357,0.439> <-17.9,6.4,-109.0>
{Cuddle 05} <-0.783,2.230,0.467> <-14.1,-7.7,-62.0> <0.783,2.357,0.439> <-17.9,6.4,-109.0>

358
TGLM/memory.lsl Normal file
View File

@@ -0,0 +1,358 @@
//MPLV2 Version 2.2 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
// v2.2 - rotate all poses, cleaner dump
integer Checking = FALSE; // whether doing consistency check
integer line;
integer PosCount;
list Poses; // list of pose names
// indexed by same index as Poses, entry contains text string of pos/rot pairs, one for each ball in pose
// list Positions;
list Positions0;
list Positions1;
list Positions2;
list Positions3;
vector Pos1;
vector Pos2;
vector Pos3;
vector Pos4;
vector Pos5;
vector Pos6;
vector Rot1;
vector Rot2;
vector Rot3;
vector Rot4;
vector Rot5;
vector Rot6;
integer Ballcount;
announce()
{
llOwnerSay((string)PosCount
+ " positions stored ("
+ llGetScriptName()
+ ": "
+ (string)llGetFreeMemory()
+ " bytes free)");
}
getPosePos(string pdata) {
list plist = llParseString2List(pdata,[" "],[]);
Ballcount = llGetListLength(plist) / 2;
Pos1 = (vector)llList2String(plist, 0);
Rot1 = (vector)llList2String(plist, 1);
Pos2 = (vector)llList2String(plist, 2);
Rot2 = (vector)llList2String(plist, 3);
Pos3 = (vector)llList2String(plist, 4);
Rot3 = (vector)llList2String(plist, 5);
Pos4 = (vector)llList2String(plist, 6);
Rot4 = (vector)llList2String(plist, 7);
Pos5 = (vector)llList2String(plist, 8);
Rot5 = (vector)llList2String(plist, 8);
Pos6 = (vector)llList2String(plist, 10);
Rot6 = (vector)llList2String(plist, 11);
}
string adjust(integer doOffset, vector pos, vector erot, vector amt) {
if (doOffset) {
pos += amt/100.;
return (vround(pos) + " " + vround(erot));
}
rotation amount = llEuler2Rot(amt * DEG_TO_RAD);
erot *= DEG_TO_RAD;
rotation oldrot = llEuler2Rot(erot);
rotation newrot = oldrot / amount;
erot = llRot2Euler(newrot) * RAD_TO_DEG;
pos = pos / amount;
return(vround(pos) + " " + vround(erot));
}
adjust_all(integer doOffset, vector amt) {
integer ix;
integer bx;
string data;
for (ix = 0; ix < PosCount; ++ix) {
data = get_pose_by_index(ix);
getPosePos(data);
list parms = [ Pos1, Rot1, Pos2, Rot2, Pos3, Rot3, Pos4, Rot4, Pos5, Rot5, Pos6, Rot6 ];
data = adjust(doOffset, Pos1, Rot1, amt);
integer ballix = 1;
while (ballix < Ballcount) {
string stuff = adjust(doOffset, llList2Vector(parms, 2*ballix), llList2Vector(parms, 2*ballix+1), amt);
data += " " + stuff;
++ballix;
}
store_pose(data, ix);
}
}
string get_pose_data(string name) {
integer ix = llListFindList(Poses, [name]);
// if not found, use default positions
if (ix == -1) {
ix = 0;
}
return (get_pose_by_index(ix));
}
string get_pose_by_index(integer ix) {
if ((ix & 3) == 0) {
return llList2String(Positions0, ix>>2);
} else if ((ix & 3) == 1) {
return llList2String(Positions1, ix>>2);
} else if ((ix & 3) == 2) {
return llList2String(Positions2, ix>>2);
}
return llList2String(Positions3, ix>>2);
}
store_pose(string data, integer ix) {
if ((ix & 3) == 0) {
Positions0 = llListReplaceList(Positions0,[ data ],ix>>2,ix>>2);
} else if ((ix & 3) == 1) {
Positions1 = llListReplaceList(Positions1,[ data ],ix>>2,ix>>2);
} else if ((ix & 3) == 2) {
Positions2 = llListReplaceList(Positions2,[ data ],ix>>2,ix>>2);
} else if ((ix & 3) == 3) {
Positions3 = llListReplaceList(Positions3,[ data ],ix>>2,ix>>2);
}
}
save_pose(string name, string data) {
integer ix = llListFindList(Poses, [name]);
if (ix == -1) {
add_pose(name, data);
} else {
store_pose(data, ix);
}
}
add_pose(string name, string data) {
integer ix = llListFindList(Poses, (list)name);
if (ix != -1) {
llOwnerSay("===> WARNING: Multiple .POSITIONS* entries for '" + name + "'");
} else {
Poses = [] + Poses + (list) name;
ix = ++PosCount;
}
store_pose(data, ix-1);
}
check_pose(string name) {
integer ix;
// if this is the last pose, report results
if (name == "CHECK2") {
string name1;
for (ix = 0; ix < llGetListLength(Poses); ++ix) {
name1 = llList2String(Poses, ix);
if (get_pose_data(name1) != "") {
if (name1 != "default" && name1 != "stand") {
llOwnerSay("No .MENUITEMS* entry for '" + name1 + "'.");
}
}
}
llOwnerSay("Checks complete, resetting.");
llResetScript();
}
ix = llListFindList(Poses, [name]);
if (ix == -1) {
llOwnerSay("No .POSITIONS* entry for '" + name + "'.");
return;
}
save_pose(name, "");
}
string vround(vector vec) {
return ("<"+round(vec.x, 3)+","+round(vec.y, 3)+","+round(vec.z, 3)+">");
}
string round(float number, integer places) {
float shifted;
integer rounded;
string s;
shifted = number * llPow(10.0,(float)places);
rounded = llRound(shifted);
s = (string)((float)rounded / llPow(10.0,(float)places));
s = llGetSubString(s,0,llSubStringIndex(s, ".")+places);
return s;
}
dashes() {
llOwnerSay("_______________________________________________________________________________");
llOwnerSay("");
}
// Globals for reading card config
integer ConfigLineIndex;
list ConfigCards; // list of names of config cards
string ConfigCardName; // name of card being read
integer ConfigCardIndex; // index of next card to read
key ConfigQueryId;
integer next_card()
{
if (ConfigCardIndex >= llGetListLength(ConfigCards)) {
ConfigCards = [];
return (FALSE);
}
ConfigLineIndex = 0;
ConfigCardName = llList2String(ConfigCards, ConfigCardIndex);
ConfigCardIndex++;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex);
llOwnerSay("Reading " + ConfigCardName);
return (TRUE);
}
default {
state_entry() {
string item;
ConfigCards = [];
integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
while (n-- > 0) {
item = llGetInventoryName(INVENTORY_NOTECARD, n);
if (llSubStringIndex(item, ".POSITIONS") != -1) {
ConfigCards = [] + ConfigCards + (list) item;
}
}
ConfigCardIndex = 0;
ConfigCards = llListSort(ConfigCards, 1, TRUE);
next_card();
}
dataserver(key query_id, string data) {
if (query_id != ConfigQueryId) {
return;
}
if (data == EOF) {
if (next_card()) {
return;
}
state on;
}
if (llGetSubString(data,0,0) != "/") { // skip comments
integer ix = llSubStringIndex(data, "{"); //split name from positions, remove junk
integer jx = llSubStringIndex(data, "} <");
if (ix != -1 && jx != -1) {
add_pose(llGetSubString(data, ix+1, jx-1), llGetSubString(data, jx+2, -1));
}
}
++ConfigLineIndex;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex); //read next line of positions notecard
}
state_exit() {
if (PosCount < 1) {
add_pose("stand", "<-0.7,0.0,0.9> <0.0,0.0,0.0> <0.7,0.0,0.9> <0.0,0.0,-180.0>");
}
if (PosCount < 2) {
add_pose("default", "<-0.7,0.0,0.7> <0.0,0.0,0.0> <0.7,0.0,0.7> <0.0,0.0,-180.0>");
}
// do one save to indicate actual amount of available memory
string position = llList2String(Positions1, 0);
Positions1 = llListReplaceList(Positions1, [position],0,0);
if (llGetInventoryType("~props") == INVENTORY_SCRIPT) {
llSetScriptState("~props", TRUE);
llResetOtherScript("~props");
llSleep(1.0); // give props a chance to run -- doesn't really matter if not enough
}
}
}
state on {
state_entry() {
llMessageLinked(LINK_THIS, 2, "OK", (key)""); //msg to menu, in case it's waiting for loading
announce();
}
link_message(integer from, integer num, string str, key dkey) {
if (str == "PRIMTOUCH" || num < 0) {
return;
}
if (num == 0 && str == "POSEB") {
string name = (string)dkey;
if (name == "CHECK1") {
Checking = TRUE;
} else if (Checking) {
check_pose((string)dkey);
} else {
llMessageLinked(LINK_THIS, 0, "POSEPOS", (key)get_pose_data((string)dkey)); // to ~pos
}
return;
}
if (num != 1) {
return;
}
if (str == "OK?") { //question from menu, before loading menu
llMessageLinked(from, 2, "OK", (key)""); //answer to menu
} else if (str == "DUMP") {
dashes();
llOwnerSay("Copy to .POSITIONS; delete any other *.POSITIONS* cards");
dashes();
string name1 = llGetObjectName();
llSetObjectName("");
integer ix;
for (ix = 0; ix < PosCount; ++ix) {
string name2 = llList2String(Poses, ix);
llOwnerSay("{" + name2 + "} " + get_pose_data(name2));
}
llSetObjectName(name1);
dashes();
} else if (llSubStringIndex(str, "REORIENT=") == 0) {
// Reorient command (LINKMENU command from .MENUITEMS file)
// str format: REORIENT=OFF=<x,y,z> or REORIENT=ROT=<x,y,z> (in degrees)
list parms = llParseString2List(str, ["="], []);
vector amount = (vector)llList2String(parms, 2);
llWhisper(0, "Adjusting Poses, please wait");
if (llList2String(parms, 1) == "OFF") {
adjust_all(TRUE, amount);
} else {
adjust_all(FALSE, amount);
}
llMessageLinked(LINK_THIS, 0, "AGAIN", (key)"");
llWhisper(0, "Pose adjustment complete");
} else {
if (llGetSubString((string)dkey, 0, 0) == "<") { //SAVE
save_pose(str, (string)dkey);
announce();
}
}
}
}

47
TGLM/~MLPT-AutoZhao.lsl Normal file
View File

@@ -0,0 +1,47 @@
// MLPV2.2 Add-On example.
// Use a script like this to support xcite, chains, etc.
// This one supports AutoZhao, whic h is a ZHAO variant that turns off
// automatically when you sit.
// LM parameters:
//
// num = 0 and msg = "POSEB": new pose
// id = is pose name
//
// num = -11000: avatar sits
// msg = ball number (0,1,...), as a string
// id = avatar who
//
// num = -11001: avatar unsits
// msg = ball number (0,1,...), as a string
// id = avatar who
integer AutoZhaoChan = -4200;
string Pose;
string Avname;
key Avkey;
default
{
link_message(integer from, integer num, string msg, key id) {
if (msg == "POSEB") {
Pose = (string)msg;
return;
}
if (num == -11000) {
// av hopped on, so turn ZHAO off
llWhisper(AutoZhaoChan, "ZHAO_AOOFF");
Avkey = id;
Avname = llKey2Name(id);
} else if (num == -11001) {
// av hopped off, so turn ZHAO on
llWhisper(AutoZhaoChan, "ZHAO_AOON");
Avkey = NULL_KEY;
Avname = "";
} else {
return;
}
}
}

358
TGLM/~memory.lsl Normal file
View File

@@ -0,0 +1,358 @@
//MPLV2 Version 2.2 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
// v2.2 - rotate all poses, cleaner dump
integer Checking = FALSE; // whether doing consistency check
integer line;
integer PosCount;
list Poses; // list of pose names
// indexed by same index as Poses, entry contains text string of pos/rot pairs, one for each ball in pose
// list Positions;
list Positions0;
list Positions1;
list Positions2;
list Positions3;
vector Pos1;
vector Pos2;
vector Pos3;
vector Pos4;
vector Pos5;
vector Pos6;
vector Rot1;
vector Rot2;
vector Rot3;
vector Rot4;
vector Rot5;
vector Rot6;
integer Ballcount;
announce()
{
llOwnerSay((string)PosCount
+ " positions stored ("
+ llGetScriptName()
+ ": "
+ (string)llGetFreeMemory()
+ " bytes free)");
}
getPosePos(string pdata) {
list plist = llParseString2List(pdata,[" "],[]);
Ballcount = llGetListLength(plist) / 2;
Pos1 = (vector)llList2String(plist, 0);
Rot1 = (vector)llList2String(plist, 1);
Pos2 = (vector)llList2String(plist, 2);
Rot2 = (vector)llList2String(plist, 3);
Pos3 = (vector)llList2String(plist, 4);
Rot3 = (vector)llList2String(plist, 5);
Pos4 = (vector)llList2String(plist, 6);
Rot4 = (vector)llList2String(plist, 7);
Pos5 = (vector)llList2String(plist, 8);
Rot5 = (vector)llList2String(plist, 8);
Pos6 = (vector)llList2String(plist, 10);
Rot6 = (vector)llList2String(plist, 11);
}
string adjust(integer doOffset, vector pos, vector erot, vector amt) {
if (doOffset) {
pos += amt/100.;
return (vround(pos) + " " + vround(erot));
}
rotation amount = llEuler2Rot(amt * DEG_TO_RAD);
erot *= DEG_TO_RAD;
rotation oldrot = llEuler2Rot(erot);
rotation newrot = oldrot / amount;
erot = llRot2Euler(newrot) * RAD_TO_DEG;
pos = pos / amount;
return(vround(pos) + " " + vround(erot));
}
adjust_all(integer doOffset, vector amt) {
integer ix;
integer bx;
string data;
for (ix = 0; ix < PosCount; ++ix) {
data = get_pose_by_index(ix);
getPosePos(data);
list parms = [ Pos1, Rot1, Pos2, Rot2, Pos3, Rot3, Pos4, Rot4, Pos5, Rot5, Pos6, Rot6 ];
data = adjust(doOffset, Pos1, Rot1, amt);
integer ballix = 1;
while (ballix < Ballcount) {
string stuff = adjust(doOffset, llList2Vector(parms, 2*ballix), llList2Vector(parms, 2*ballix+1), amt);
data += " " + stuff;
++ballix;
}
store_pose(data, ix);
}
}
string get_pose_data(string name) {
integer ix = llListFindList(Poses, [name]);
// if not found, use default positions
if (ix == -1) {
ix = 0;
}
return (get_pose_by_index(ix));
}
string get_pose_by_index(integer ix) {
if ((ix & 3) == 0) {
return llList2String(Positions0, ix>>2);
} else if ((ix & 3) == 1) {
return llList2String(Positions1, ix>>2);
} else if ((ix & 3) == 2) {
return llList2String(Positions2, ix>>2);
}
return llList2String(Positions3, ix>>2);
}
store_pose(string data, integer ix) {
if ((ix & 3) == 0) {
Positions0 = llListReplaceList(Positions0,[ data ],ix>>2,ix>>2);
} else if ((ix & 3) == 1) {
Positions1 = llListReplaceList(Positions1,[ data ],ix>>2,ix>>2);
} else if ((ix & 3) == 2) {
Positions2 = llListReplaceList(Positions2,[ data ],ix>>2,ix>>2);
} else if ((ix & 3) == 3) {
Positions3 = llListReplaceList(Positions3,[ data ],ix>>2,ix>>2);
}
}
save_pose(string name, string data) {
integer ix = llListFindList(Poses, [name]);
if (ix == -1) {
add_pose(name, data);
} else {
store_pose(data, ix);
}
}
add_pose(string name, string data) {
integer ix = llListFindList(Poses, (list)name);
if (ix != -1) {
llOwnerSay("===> WARNING: Multiple .POSITIONS* entries for '" + name + "'");
} else {
Poses = [] + Poses + (list) name;
ix = ++PosCount;
}
store_pose(data, ix-1);
}
check_pose(string name) {
integer ix;
// if this is the last pose, report results
if (name == "CHECK2") {
string name1;
for (ix = 0; ix < llGetListLength(Poses); ++ix) {
name1 = llList2String(Poses, ix);
if (get_pose_data(name1) != "") {
if (name1 != "default" && name1 != "stand") {
llOwnerSay("No .MENUITEMS* entry for '" + name1 + "'.");
}
}
}
llOwnerSay("Checks complete, resetting.");
llResetScript();
}
ix = llListFindList(Poses, [name]);
if (ix == -1) {
llOwnerSay("No .POSITIONS* entry for '" + name + "'.");
return;
}
save_pose(name, "");
}
string vround(vector vec) {
return ("<"+round(vec.x, 3)+","+round(vec.y, 3)+","+round(vec.z, 3)+">");
}
string round(float number, integer places) {
float shifted;
integer rounded;
string s;
shifted = number * llPow(10.0,(float)places);
rounded = llRound(shifted);
s = (string)((float)rounded / llPow(10.0,(float)places));
s = llGetSubString(s,0,llSubStringIndex(s, ".")+places);
return s;
}
dashes() {
llOwnerSay("_______________________________________________________________________________");
llOwnerSay("");
}
// Globals for reading card config
integer ConfigLineIndex;
list ConfigCards; // list of names of config cards
string ConfigCardName; // name of card being read
integer ConfigCardIndex; // index of next card to read
key ConfigQueryId;
integer next_card()
{
if (ConfigCardIndex >= llGetListLength(ConfigCards)) {
ConfigCards = [];
return (FALSE);
}
ConfigLineIndex = 0;
ConfigCardName = llList2String(ConfigCards, ConfigCardIndex);
ConfigCardIndex++;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex);
llOwnerSay("Reading " + ConfigCardName);
return (TRUE);
}
default {
state_entry() {
string item;
ConfigCards = [];
integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
while (n-- > 0) {
item = llGetInventoryName(INVENTORY_NOTECARD, n);
if (llSubStringIndex(item, ".POSITIONS") != -1) {
ConfigCards = [] + ConfigCards + (list) item;
}
}
ConfigCardIndex = 0;
ConfigCards = llListSort(ConfigCards, 1, TRUE);
next_card();
}
dataserver(key query_id, string data) {
if (query_id != ConfigQueryId) {
return;
}
if (data == EOF) {
if (next_card()) {
return;
}
state on;
}
if (llGetSubString(data,0,0) != "/") { // skip comments
integer ix = llSubStringIndex(data, "{"); //split name from positions, remove junk
integer jx = llSubStringIndex(data, "} <");
if (ix != -1 && jx != -1) {
add_pose(llGetSubString(data, ix+1, jx-1), llGetSubString(data, jx+2, -1));
}
}
++ConfigLineIndex;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex); //read next line of positions notecard
}
state_exit() {
if (PosCount < 1) {
add_pose("stand", "<-0.7,0.0,0.9> <0.0,0.0,0.0> <0.7,0.0,0.9> <0.0,0.0,-180.0>");
}
if (PosCount < 2) {
add_pose("default", "<-0.7,0.0,0.7> <0.0,0.0,0.0> <0.7,0.0,0.7> <0.0,0.0,-180.0>");
}
// do one save to indicate actual amount of available memory
string position = llList2String(Positions1, 0);
Positions1 = llListReplaceList(Positions1, [position],0,0);
if (llGetInventoryType("~props") == INVENTORY_SCRIPT) {
llSetScriptState("~props", TRUE);
llResetOtherScript("~props");
llSleep(1.0); // give props a chance to run -- doesn't really matter if not enough
}
}
}
state on {
state_entry() {
llMessageLinked(LINK_THIS, 2, "OK", (key)""); //msg to menu, in case it's waiting for loading
announce();
}
link_message(integer from, integer num, string str, key dkey) {
if (str == "PRIMTOUCH" || num < 0) {
return;
}
if (num == 0 && str == "POSEB") {
string name = (string)dkey;
if (name == "CHECK1") {
Checking = TRUE;
} else if (Checking) {
check_pose((string)dkey);
} else {
llMessageLinked(LINK_THIS, 0, "POSEPOS", (key)get_pose_data((string)dkey)); // to ~pos
}
return;
}
if (num != 1) {
return;
}
if (str == "OK?") { //question from menu, before loading menu
llMessageLinked(from, 2, "OK", (key)""); //answer to menu
} else if (str == "DUMP") {
dashes();
llOwnerSay("Copy to .POSITIONS; delete any other *.POSITIONS* cards");
dashes();
string name1 = llGetObjectName();
llSetObjectName("");
integer ix;
for (ix = 0; ix < PosCount; ++ix) {
string name2 = llList2String(Poses, ix);
llOwnerSay("{" + name2 + "} " + get_pose_data(name2));
}
llSetObjectName(name1);
dashes();
} else if (llSubStringIndex(str, "REORIENT=") == 0) {
// Reorient command (LINKMENU command from .MENUITEMS file)
// str format: REORIENT=OFF=<x,y,z> or REORIENT=ROT=<x,y,z> (in degrees)
list parms = llParseString2List(str, ["="], []);
vector amount = (vector)llList2String(parms, 2);
llWhisper(0, "Adjusting Poses, please wait");
if (llList2String(parms, 1) == "OFF") {
adjust_all(TRUE, amount);
} else {
adjust_all(FALSE, amount);
}
llMessageLinked(LINK_THIS, 0, "AGAIN", (key)"");
llWhisper(0, "Pose adjustment complete");
} else {
if (llGetSubString((string)dkey, 0, 0) == "<") { //SAVE
save_pose(str, (string)dkey);
announce();
}
}
}
}

511
TGLM/~menu.lsl Normal file
View File

@@ -0,0 +1,511 @@
// MLPV2 Version 2.3, by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
// 15-color balls by Lizz Silverstar
// 2.3: sequences
// 6 avs
// Adjusting state
integer MAX_BALLS = 6;
string Version = "WELM v1.0";
integer b;
integer b0;
integer ballusers;
list BallColors;
integer ch;
integer chat = 1;
integer group;
integer i;
integer menu;
integer menuusers;
integer redo = 1;
integer swap;
integer visible;
integer BallCount;
integer SaneMenuOrder;
integer ReloadOnRez;
integer Adjusting;
string LastPose;
integer BallsNeeded;
float alpha;
string cmd;
string pose;
string Posemsg; // for 'AGAIN'
key owner;
key user;
key user0;
list buttons;
list buttonindex;
list commands;
list menus;
list balls;
list users;
list SoundNames;
list Sounds;
list LMButtons;
list LMParms;
list MenuStack = [0]; // indices to previous menus, for "BACK" command
integer MenuPage; // which page of current menu we're on, 0 for first
stop() {
sendStand(); //msg to pos/pose
llMessageLinked(LINK_THIS, 1, "STOP", (key)"");
llSleep(0.2);
killBalls();
swap = 0;
Adjusting = FALSE;
}
check_poses() {
llOwnerSay("Checking configs");
llMessageLinked(LINK_THIS,0,"POSEB", (key)"CHECK1"); //msg to memory
integer ix;
string name;
for (ix = 0; ix < llGetListLength(buttons); ++ix) {
name = llList2String(buttons, ix);
if (((integer)llList2String(commands, ix)) != 0) {
llMessageLinked(LINK_THIS,0,"POSEB", (key)name); //msg to memory
}
}
llMessageLinked(LINK_THIS,0,"POSEB", (key)"CHECK2"); //msg to memory
}
// Return a channel number that's based on the prim's key -- unique per object
integer channel() {
return (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1));
}
// setup for a pose based on menu characteristics
setup_pose() {
if (BallsNeeded) { // if submenu includes balls:
if (BallCount != BallsNeeded) {
rezBalls(); // if not enough balls present: create balls
llSleep(0.5);
}
integer ix;
for (ix = 0; ix < BallsNeeded; ++ix) {
llSay(ch + ix, llList2String(BallColors, ix) // to ball: color, ballnum, adjusting
+ "|" + (string) ix
+ "|" + (string) Adjusting);
}
if (ballusers) setBalls("GROUP"); //if group access only
}
}
unauth(string button, string who) {
llDialog(user0, "\n" + button + " button allowed only for " + who, ["OK"], -1);
}
continMenu(string str) {
llDialog(user0, "\n"+str+llKey2Name(user)+" is using the menu, continue?", ["Yes","Cancel"], ch - 1);
}
mainMenu() {
MenuPage = 0;
menu = 0;
doMenu(FALSE);
}
//menu partly based on Menu Engine by Zonax Delorean (BSD License)
//llDialog(user, menuname, buttons(from index to nextindex-1), channel)
doMenu(integer inhibit_showing) {
integer colors = llList2Integer(balls,menu);
integer ix;
integer mask = 0xf;
integer shift = 0;
BallsNeeded = 0;
BallColors = [];
for (ix = 0; ix < MAX_BALLS; ++ix) {
integer bc = (colors & mask) >> ix*4;
BallColors += (list)bc;
if (bc) {
BallsNeeded += 1;
}
mask = mask << 4;
}
if (inhibit_showing) {
return;
}
b0 = llList2Integer(buttonindex, menu); //position of first butt on for this (sub)menu
b = llList2Integer(buttonindex, menu+1); //position of first button for next (sub)menu
b0 += MenuPage * 12;
if (b - b0 > 12) {
b = b0 + 12;
}
list buttons1 = llList2List(buttons, b0, b - 1);
if (SaneMenuOrder) {
buttons1 =
llList2List(buttons1, -3, -1)
+ llList2List(buttons1, -6, -4)
+ llList2List(buttons1, -9, -7)
+ llList2List(buttons1, -12, -10);
}
llDialog(user, Version + "\n\n" + llList2String(menus,menu), buttons1, ch - 1);
llResetTime();
}
say(string str) {
if (menuusers) llWhisper(0,str);
else llOwnerSay(str);
}
killBalls() {
integer ix;
for (ix = 0; ix < MAX_BALLS; ++ix) {
llSay(ch + ix, "DIE"); //msg to balls
}
BallCount = 0;
llSetTimerEvent(0.0);
}
setBalls(string cmd) {
integer ix;
for (ix = 0; ix < BallCount; ++ix) {
llSay(ch + ix, cmd); //msg to balls
}
}
rezBalls() {
integer current = BallCount;
if (BallsNeeded == BallCount) return;
if (BallCount == 0) {
killBalls(); // for reinitialization, if old balls are around
}
while (BallCount > BallsNeeded) {
--BallCount;
llSay(ch + BallCount, "DIE");
}
while (BallCount < BallsNeeded) {
llRezObject("~ball",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,ch+BallCount);
++BallCount;
}
// Only do this if there were no balls
if (! current) {
llMessageLinked(LINK_THIS,0,"REPOS",(key)""); //msg to pos
}
llSetTimerEvent(60.0);
}
sendStand() {
llMessageLinked(LINK_THIS,0,"POSE","0,"+(string)BallCount); //msg to pos/pose
llMessageLinked(LINK_THIS,0,"POSEB", "stand");
}
touched(integer same_group) {
if (user0 == owner || (menuusers == 1 && same_group) || menuusers == 2) { //0=owner 1=group 2=all
if (user0 != user) {
if (llGetTime() < 60.0 && user != (key)"") {
continMenu("");
return;
}
user = user0;
group = same_group;
}
mainMenu();
}
}
// return TRUE if caller should do menu
integer handle_cmd(string button, integer sequenced) {
b = llListFindList(buttons, (list) button); //find position of cmd
string cmd = llList2String(commands,b); //get command
if (cmd == "TOMENU") {
integer newmenu = llListFindList(menus,[ button ]); //find submenu
if (newmenu == -1) return FALSE;
if (sequenced) {
integer oldmenu = menu;
menu = newmenu;
doMenu(TRUE);
setup_pose();
menu = oldmenu;
return FALSE;
}
i = llList2Integer(users, newmenu);
if (user == owner || (i == 1 && group) || i == 2) { //0=owner 1=group 2=all
MenuStack = [] + (list)menu + MenuStack;
MenuPage = 0;
menu = newmenu;
doMenu(sequenced);
return FALSE;
}
if (i == 1) unauth(button, "group");
else unauth(button, "owner");
return FALSE;
} else if (cmd == "BACK") {
if (MenuPage) {
--MenuPage;
doMenu(sequenced);
return FALSE;
}
menu = llList2Integer(MenuStack,0);
MenuStack = llList2List(MenuStack,1,-1);
doMenu(sequenced);
return FALSE;
} else if (cmd == "MORE") {
++MenuPage;
doMenu(sequenced);
return FALSE;
} else if (cmd == "CHECK") {
check_poses();
} else if ((integer)cmd > 0) { //POSE
if (Adjusting && button != pose) {
llMessageLinked(LINK_THIS,0,"SAVE",pose); //msg to pos/pose
llSleep(5.);
}
setup_pose();
Posemsg = cmd + "," + (string) BallCount;
llMessageLinked(LINK_THIS,0,"POSE", Posemsg); //msg to pose
llMessageLinked(LINK_THIS,0,"POSEB", (key)button); //msg to memory
if (chat) say(button);
pose = button;
} else if (cmd == "SWAP") {
swap += 1;
llMessageLinked(LINK_THIS,0,"SWAP",(key)((string)swap)); //msg to pos/pose
} else if (cmd == "STAND") {
sendStand(); //msg to pos/pose
if (chat) say(button);
pose = "stand";
} else if (cmd == "STOP") {
if (chat) say(button);
stop();
return FALSE;
} else if (cmd == "ADJUST") {
Adjusting = ! Adjusting;
setBalls("ADJUST|" + (string)Adjusting);
} else if (cmd == "HIDE") {
setBalls("0");
} else if (cmd == "SHOW") {
setBalls("SHOW");
} else if (cmd == "DUMP") {
llMessageLinked(LINK_THIS,1,"DUMP",(key)"");
} else if (cmd == "INVISIBLE") {
visible = !visible;
llSetAlpha((float)visible*alpha, ALL_SIDES);
} else if (cmd == "REDO") {
redo = !redo;
if (redo) say(button+" ON"); else say(button+" OFF");
} else if (cmd == "CHAT") {
chat = !chat;
if (chat) say(button+" ON"); else say(button+" OFF");
} else if (cmd == "BALLUSERS") {
ballusers = !ballusers;
if (ballusers) {
llOwnerSay(button+" GROUP");
setBalls("GROUP");
} else {
llOwnerSay(button+" ALL");
setBalls("ALL");
}
} else if (cmd == "MENUUSERS") {
if (user == owner) {
if (!menuusers) {
menuusers = 1;
llOwnerSay(button+" GROUP");
} else if (menuusers == 1) {
menuusers = 2;
llOwnerSay(button+" ALL");
} else if (menuusers == 2) {
menuusers = 0;
llOwnerSay(button+" OWNER");
}
} else unauth(button, "owner");
} else if (cmd == "RESET" || cmd == "RELOAD" || cmd == "RESTART") {
stop();
if (chat) say(button);
if (cmd == "RESET") {
llResetScript();
} else {
llResetOtherScript("~memory");
if (cmd == "RESTART") {
llResetScript();
}
}
} else if (cmd == "OFF") {
sendStand(); //msg to pos/pose
stop();
if (user == owner) {
llOwnerSay(button);
llResetOtherScript("~run");
llResetScript();
}
unauth(button, "owner");
return FALSE;
} else if (llGetSubString(cmd, 0, 0) == "Z" || (cmd == "SAVE")) { //SAVE or Z-adjust
llMessageLinked(LINK_THIS,0,cmd,pose); //msg to pos/pose
doMenu(sequenced);
return FALSE;
} else if (cmd == "LINKMSG") {
// menu button to send LM to a non-MLPV2 script
integer ix = llListFindList(LMButtons, [button]);
if (ix != -1) {
list lmparms = llCSV2List(llList2String(LMParms, ix));
llMessageLinked(
llList2Integer(lmparms, 1), // destination link#
llList2Integer(lmparms, 2), // 'num' arg
llList2String(lmparms, 3), // 'str' arg
user0); // key arg
if (llList2Integer(lmparms,0)) { // inhibit remenu?
return FALSE; // yes, bug out
}
}
} else if (cmd == "SOUND") {
integer ix = llListFindList(SoundNames, (list)button);
if (ix >= 0) {
llPlaySound(llList2String(Sounds, ix), 1.);
}
}
return TRUE;
}
default {
state_entry() {
ch = channel();
killBalls();
llSleep(2.0); // give ~run a chance to shut us down
llResetOtherScript("~menucfg");
llResetOtherScript("~pos");
llResetOtherScript("~pose");
llResetOtherScript("~poser");
llResetOtherScript("~poser 1");
llResetOtherScript("~poser 2");
llResetOtherScript("~poser 3");
llResetOtherScript("~poser 4");
llResetOtherScript("~poser 5");
alpha = llGetAlpha(0); //store object transparancy (alpha)
if (alpha < 0.1) alpha = 0.5; else visible = 1; //if invisibl e store a visible alpha
}
link_message(integer from, integer num, string str, key id) {
if (from != llGetLinkNumber()) { return; }
if (num >= 0) { return;}
// LMs from ~memory, passing configuration
if (num == -1) {
buttons = llCSV2List(str);
} else if (num == -2) {
commands = llCSV2List(str);
} else if (num == -3) {
menus = llCSV2List(str);
} else if (num == -4) {
buttonindex = llCSV2List(str);
} else if (num == -5) {
balls = llCSV2List(str);
} else if (num == -6) {
users = llCSV2List(str);
} else if (num == -7) {
LMButtons = llCSV2List(str);
} else if (num == -8) {
LMParms = llParseStringKeepNulls(str, ["|"], []);
} else if (num == -9) {
SoundNames = llCSV2List(str);
} else if (num == -10) {
Sounds = llCSV2List(str);
} else if (num == -20) {
list args = llCSV2List(str);
redo = llList2Integer(args,0);
chat = llList2Integer(args,1);
ballusers = llList2Integer(args,2);
menuusers = llList2Integer(args,3);
SaneMenuOrder = llList2Integer(args,4);
ReloadOnRez = llList2Integer(args,5);
state on;
}
}
state_exit() {
llOwnerSay("("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free)");
llWhisper(0, Version + ": READY");
}
}
state re_on {
state_entry() {
state on;
}
}
state on {
state_entry() {
ch = channel();
owner = llGetOwner();
llListen(ch - 1, "", NULL_KEY, ""); //listen for pressed buttons
// llWhisper(0, "Channel: " + (string)ch);
}
on_rez(integer arg) {
if (ReloadOnRez) {
llResetScript();
}
BallCount = 0;
llSetTimerEvent(0.0);
state re_on;
}
touch_start(integer tcount) {
user0 = llDetectedKey(0);
touched(llDetectedGroup(0));
}
listen(integer channel, string name, key id, string button) {
if (id != user) {
if (button == "Yes") {
user = id;
group = llSameGroup(user0);
mainMenu();
} else if (button != "Cancel") {
continMenu("Selection cancelled because ");
}
return;
}
if (handle_cmd(button, FALSE) && redo) doMenu(FALSE);
}
link_message(integer from, integer num, string str, key id) {
if (str == "PRIMTOUCH") {
user0 = id;
touched(num);
return;
}
if (num == 0 && str == "AGAIN") {
llMessageLinked(LINK_THIS,0,"POSE", Posemsg); //msg to pose
llMessageLinked(LINK_THIS,0,"POSEB", (key)pose); //msg to memory
return;
}
if (num == -12002) {
handle_cmd(str, TRUE);
return;
}
}
timer() {
setBalls("LIVE"); //msg to balls: stay alive
}
}

272
TGLM/~menucfg.lsl Normal file
View File

@@ -0,0 +1,272 @@
// MLPV2 Version 2.2, by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
// 15-color balls by Lizz Silverstar
// autoback, multi-contin menu fixed
integer MAX_BALLS = 6;
// Multicolor ball patch by Lizz Silverstar
// The colors var used to store the color values is a 32 bit integer (0x00000000)
// This is broken up into 8 nibbles of which we will currently use the lower 4 nibbles
// the first ball color is in the lower 4 bits, the second in the next 4 bits, etc
// Masks and shifting are used to store and extract the data.
// 4 bits gives us 15 colors. 0 = no ball, 1-15 = color
// these index values are then used by the ~ball code to set the correct color
// 1st ball mask is 0x0000000F, no shift
// 2nd ball mask is 0x000000F0, shift of 4
// 3rd ball mask is 0x00000F00, shift of 8
// 4th ball mask is 0x0000F000, shift of 12
list Colornames = [
"HIDE", "PINK", "BLUE", "PINK2",
"BLUE2", "GREEN", "MAGENTA", "RED",
"ORANGE", "WHITE", "BLACK", "YELLOW",
"CYAN", "RED2", "TEAL", "GREEN2"];
integer PoseIx;
integer CurButtonIx; // index of current button
integer b0; // index of current button from start of current menu
integer AutoBack;
integer chat = TRUE;
integer redo = TRUE;
integer menuusers;
integer group;
integer ballusers;
integer SaneMenuOrder;
integer ReloadOnRez = FALSE;
string cmd;
string pose;
string pose0;
list buttons;
list buttonindex;
list commands;
list menus;
list balls;
list users;
list SoundNames;
list Sounds;
list LMButtons;
list LMParms;
// Globals for reading card config
integer ConfigLineIndex;
list ConfigCards; // list of names of config cards
string ConfigCardName; // name of card being read
integer ConfigCardIndex; // index of next card to read
key ConfigQueryId;
integer next_card()
{
if (ConfigCardIndex >= llGetListLength(ConfigCards)) {
ConfigCards = [];
return (FALSE);
}
ConfigLineIndex = 0;
ConfigCardName = llList2String(ConfigCards, ConfigCardIndex);
ConfigCardIndex++;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex);
llOwnerSay("Reading " + ConfigCardName);
return (TRUE);
}
default {
state_entry() {
// ch = (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
llMessageLinked(LINK_THIS,1,"OK?",(key)""); //msg to memory: ask if ready
}
link_message(integer from, integer num, string str, key id) {
if (num == 2 && str == "OK") state load; //memory ready
}
}
state load {
state_entry() {
string item;
ConfigCards = [];
integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
while (n-- > 0) {
item = llGetInventoryName(INVENTORY_NOTECARD, n);
if (llSubStringIndex(item, ".MENUITEMS") != -1) {
ConfigCards = [] + ConfigCards + (list)item;
}
}
ConfigCardIndex = 0;
ConfigCards = llListSort(ConfigCards, 1, TRUE);
next_card();
}
dataserver(key query_id, string data) {
if (query_id != ConfigQueryId) {
return;
}
if (data == EOF) {
if (next_card()) {
return;
}
state on;
}
integer ix = llSubStringIndex(data,"//"); //remove comments
if (ix != -1) {
if (ix == 0) data = "";
else data = llGetSubString(data, 0, ix - 1);
}
data = llStringTrim(data, STRING_TRIM_TAIL);
if (data != "") {
ix = llSubStringIndex(data," ");
cmd = data;
if (ix != -1) { //split command from data
cmd = llGetSubString(data, 0, ix - 1);
data = llGetSubString(data, ix+1, -1);
}
list ldata = llParseStringKeepNulls(data,[" | "," | "," | "," | "," |","| ","|"],[]);
string arg1 = llList2String(ldata, 0);
//llSay(0, cmd + ":" + data);
if (cmd == "MENU") {
integer auth;
if (PoseIx < 2) {
llOwnerSay("warning: first two items in .MENUITEMS must be: POSE stand / POSE default");
}
llOwnerSay("loading '"+arg1+"' menu");
if (llList2String(ldata, 1) == "GROUP") auth = 1; //access to submenus
else if (llList2String(ldata, 1) != "OWNER") auth = 2; //0=owner 1=group 2=all
integer colors;
string ball_color;
integer colorIx;
integer ix1;
for (ix1=0; ix1 < MAX_BALLS; ++ix1) { // for each possible ball
ball_color = llList2String(ldata, ix1 + 2); // get next color name from config
colorIx = llListFindList(Colornames, (list)ball_color);
if (colorIx != -1) {
colors += (colorIx << (4 * ix1)); // 4 = bits per color (16 colors)
}
}
menus = [] + menus + (list) arg1;
balls = [] + balls + (list) colors;
buttonindex = [] + buttonindex + (list) CurButtonIx;
users = [] + users + (list) auth;
if (llListFindList(buttons, (list)arg1) == -1) {
integer jx = llListFindList(buttons, (list) "-");
if (jx != -1) {
buttons = llListReplaceList(buttons, (list)arg1, jx, jx);
// "TOMENU" is already in commands list from the 'TOMENU -'
} else if (CurButtonIx > 2) {
llOwnerSay("No unused 'TOMENU -' for " + arg1);
}
}
b0 = 0;
} else if (cmd == "AUTOBACK") {
AutoBack = (arg1 != "0");
} else if (cmd == "NORELOAD") {
ReloadOnRez = (arg1 != "0"); // whether to reload menu on rez
} else if (cmd == "MENUORDER") {
SaneMenuOrder = (arg1 != "0"); // keep menu buttons in same order as in file
} else {
// automatic menu extension (don't do for main menu)
if (b0 == 12 && llGetListLength(menus) > 1) {
// Add a "more" button before last item
integer ix1 = -1;
if (AutoBack) {
ix1 = -2;
// Add a "BACK" button
buttons = llListInsertList(buttons, (list)"BACK", ix1);
commands = llListInsertList(commands, (list)"BACK", ix1);
++CurButtonIx;
}
buttons = llListInsertList(buttons, (list)"More-->", ix1);
commands = llListInsertList(commands, (list)"MORE", ix1);
++CurButtonIx;
b0 = -ix1;
}
if (cmd == "POSE") {
llMessageLinked(LINK_THIS,9+PoseIx,data, (key)"");
if (!PoseIx) pose0 = arg1;
cmd = (string)PoseIx;
++PoseIx;
} else if (cmd == "REDO") {
if (llList2String(ldata, 1) != "OFF") redo = 1;
} else if (cmd == "CHAT") {
if (llList2String(ldata, 1) != "OFF") chat = 1;
} else if (cmd == "BALLUSERS") {
if (llList2String(ldata, 1) == "GROUP") ballusers = 1;
} else if (cmd == "MENUUSERS") {
if (llList2String(ldata, 1) == "GROUP") menuusers = 1;
else if (llList2String(ldata, 1) != "OWNER") menuusers = 2;
} else if (cmd == "LINKMSG") {
LMButtons = [] + LMButtons + arg1;
LMParms = [] + LMParms + llList2String(ldata, 1);
} else if (cmd == "SOUND") {
SoundNames += (list) arg1;
Sounds += (list) llList2String(ldata, 1);
}
commands = [] + commands + (list) cmd;
buttons = [] + buttons + (list) arg1;
++CurButtonIx;
++b0;
}
}
++ConfigLineIndex;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex); //read next line of menuitems notecard
}
state_exit() {
buttonindex = [] + buttonindex + (list) CurButtonIx; //enter last buttonindex
commands = [] + commands + (list) ""; //empty command for undefined buttons (-1)
integer ix;
integer count;
while ((ix = llListFindList(buttons, (list)"-")) != -1) {
++count;
buttons = llDeleteSubList(buttons, ix, ix);
commands = llDeleteSubList(commands, ix, ix);
}
if (count) {
for (ix = 1; ix < llGetListLength(buttonindex); ++ix) {
buttonindex = llListReplaceList(buttonindex,
(list)(llList2Integer(buttonindex, ix) - count), ix, ix);
}
}
// llMessageLinked(LINK_THIS,1,"LOADED",(string)PoseIx); //msg to memory
llMessageLinked(LINK_THIS,9+PoseIx,"LOADED",(key)""); //msg to pose
}
}
state on {
state_entry() {
// llSay(0, llList2CSV(buttons));
llMessageLinked(LINK_THIS, -3, llList2CSV(menus), (key)""); menus = [];
llMessageLinked(LINK_THIS, -4, llList2CSV(buttonindex), (key)""); buttonindex = [];
llMessageLinked(LINK_THIS, -5, llList2CSV(balls), (key)""); balls = [];
llMessageLinked(LINK_THIS, -6, llList2CSV(users), (key)""); users = [];
llMessageLinked(LINK_THIS, -7, llList2CSV(LMButtons), (key)""); LMButtons = [];
llMessageLinked(LINK_THIS, -8, llDumpList2String(LMParms, "|"), (key)""); LMParms = [];
llMessageLinked(LINK_THIS, -9, llList2CSV(SoundNames), (key)""); SoundNames = [];
llMessageLinked(LINK_THIS, -10, llList2CSV(Sounds), (key)""); Sounds = [];
llMessageLinked(LINK_THIS, -2, llList2CSV(commands), (key)""); commands = [];
llMessageLinked(LINK_THIS, -1, llList2CSV(buttons), (key)""); buttons = [];
// finally, scalars (signals 'done' as well)
llMessageLinked(LINK_THIS, -20,
llList2CSV([ redo, chat, ballusers, menuusers, SaneMenuOrder, ReloadOnRez ]), (key)"");
llOwnerSay((string)CurButtonIx+" menuitems loaded ("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free)");
}
}

102
TGLM/~pos.lsl Normal file
View File

@@ -0,0 +1,102 @@
// MLPV2 Version 2.3j, by Learjeff Innis, based o n
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer MAX_BALLS = 6;
integer ch;
integer swap;
integer BallCount;
string pr1;
string pr2;
integer Zoffset;
vector RefPos;
rotation RefRot;
getRefPos() { //reference position
RefPos = llGetPos();
RefRot = llGetRot();
Zoffset = (integer)llGetObjectDesc();
RefPos.z += (float) Zoffset / 100.;
}
list Pdata;
getPosNew(string pdata) {
Pdata = llParseString2List(pdata, [" "],[]);
}
setPos() {
pr1 = (string)((vector)llList2String(Pdata, 0) * RefRot + RefPos);
pr2 = (string)((vector)llList2String(Pdata, 2) * RefRot + RefPos);
pr1 += (string)(llEuler2Rot((vector)llList2String(Pdata, 1) * DEG_TO_RAD) * RefRot);
pr2 += (string)(llEuler2Rot((vector)llList2String(Pdata, 3) * DEG_TO_RAD) * RefRot);
if (BallCount > 1) {
llSay(ch+swap,pr1); //msg to ball1/2
llSay(ch+!swap,pr2);
} else {
llSay(ch,pr1); //msg to ball1/2
}
integer ix;
for (ix = 2; ix < BallCount; ++ix) {
llSay(ch + ix, (string)((vector)llList2String(Pdata, 2*ix) * RefRot + RefPos)
+ (string)(llEuler2Rot((vector)llList2String(Pdata, 2*ix + 1) * DEG_TO_RAD) * RefRot));
}
}
getChan() {
ch = (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
state_entry() {
getRefPos();
getChan();
}
on_rez(integer arg) {
getRefPos();
getChan();
}
link_message(integer from, integer num, string cmd, key pkey) {
if (cmd == "PRIMTOUCH"){
return;
}
if (num == 1 && cmd == "STOP") {
swap = 0;
return;
}
if (num) return;
if (cmd == "POSE") {
list parms = llCSV2List((string)pkey);
BallCount = llList2Integer(parms,1);
return;
} else if (cmd == "POSEPOS") {
// p = (integer)((string)pkey
getPosNew((string)pkey);
setPos();
} else if (cmd == "SWAP") {
swap = (integer)((string)pkey) & 1;
llSay(ch+swap,pr1); //msg to ball1/2
llSay(ch+!swap,pr2);
} else if (cmd == "REPOS") {
getRefPos();
} else if (llGetSubString(cmd, 0, 0) == "Z") {
integer change = (integer)llGetSubString(cmd, 1, -1);
Zoffset += change;
RefPos.z += (float)change/100.;
setPos();
llOwnerSay("Height Adjustment: change by " + (string) change + "cm, new offset: " + (string)Zoffset + "cm");
llSetObjectDesc((string)Zoffset);
} else if (cmd == "GETREFPOS") {
llMessageLinked(LINK_THIS,8,(string)RefPos,(string)RefRot); //send reference position to pose
}
}
}

213
TGLM/~pose.lsl Normal file
View File

@@ -0,0 +1,213 @@
//MPLV2 Version 2.1, Lear Cale, from:
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer MAX_AVS = 6;
integer a;
integer ch;
integer i;
integer swap;
string an1;
string an2;
string an3;
string an4;
string an5;
string an6;
string pose;
list PRs; // pos/rot pairs for Save
list anims; // strided list of anims, indexed by pose*6
vector pos;
rotation rot;
integer BallCount; // number of balls
integer UpdateCount; // number of balls we've heard from, for save
string prStr(string str) {
i = llSubStringIndex(str,">");
vector p = ((vector)llGetSubString(str,0,i) - pos) / rot;
vector r = llRot2Euler((rotation)llGetSubString(str,i+1,-1) / rot)*RAD_TO_DEG;
return "<"+round(p.x, 3)+","+round(p.y, 3)+","+round(p.z, 3)+"> <"+round(r.x, 1)+","+round(r.y, 1)+","+round(r.z, 1)+">";
}
string round(float number, integer places) {
float shifted;
integer rounded;
string s;
shifted = number * llPow(10.0,(float)places);
rounded = llRound(shifted);
s = (string)((float)rounded / llPow(10.0,(float)places));
s = llGetSubString(s,0,llSubStringIndex(s, ".")+places);
return s;
}
check_anim(string aname) {
if (aname == "") {
return;
}
if ( aname != "PINK"
&& aname != "BLUE"
&& aname != "stand"
&& aname != "sit_ground") {
// ignore expression suffix of "*" or "::nnn"
if (llGetSubString(aname, -1, -1) == "*") {
aname = llGetSubString(aname, 0, -2);
} else {
integer ix = llSubStringIndex(aname, "::");
if (ix != -1) {
aname = llGetSubString(aname, 0, ix-1);
}
}
if (llGetInventoryType(aname) != INVENTORY_ANIMATION) {
llSay(0,"animation '"
+ aname
+ "' not in inventory (ok for build-in animations, otherwise check)");
}
}
}
getChan() {
ch = (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
link_message(integer from, integer num, string data, key id) {
if (num != 9+a) return;
if (data == "LOADED") state on;
list ldata = llParseString2List(data,[" | "," | "," | "," | "," |","| ","|"],[]);
an1 = llList2String(ldata,1);
an2 = llList2String(ldata,2);
an3 = llList2String(ldata,3);
an4 = llList2String(ldata,4);
an5 = llList2String(ldata,5);
an6 = llList2String(ldata,6);
if (a>1) {
check_anim(an1);
check_anim(an2);
check_anim(an3);
check_anim(an4);
check_anim(an5);
check_anim(an6);
} else if (a) { //pose1: set default
if (an1 == "") an1 = "sit_ground";
if (an2 == "") an2 = "sit_ground";
if (an3 == "") an3 = "sit_ground";
if (an4 == "") an4 = "sit_ground";
if (an5 == "") an5 = "sit_ground";
if (an6 == "") an6 = "sit_ground";
} else { //pose0: set stand
if (an1 == "") an1 = "stand";
if (an2 == "") an2 = "stand";
if (an3 == "") an3 = "stand";
if (an4 == "") an4 = "stand";
if (an5 == "") an5 = "stand";
if (an6 == "") an6 = "stand";
}
anims = [] + anims + [an1] + [an2] + [an3] + [an4] + [an5] + [an6];
++a;
}
state_exit() {
llOwnerSay((string)a+" poses loaded ("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free)");
}
}
state on {
state_entry() {
getChan();
}
on_rez(integer arg) {
getChan();
}
link_message(integer from, integer num, string cmd, key akey) {
if (cmd == "PRIMTOUCH"){
return;
}
if (num) return;
if (cmd == "POSE") {
list parms = llCSV2List((string)akey);
BallCount = llList2Integer(parms,1);
a = llList2Integer(parms,0) * 6;
an1 = llList2String(anims, a);
an2 = llList2String(anims, a+1);
an3 = llList2String(anims, a+2);
an4 = llList2String(anims, a+3);
an5 = llList2String(anims, a+4);
an6 = llList2String(anims, a+5);
} else if (cmd == "SWAP") {
swap = !swap;
} else if (cmd == "SAVE") {
pose = (string)akey;
state save;
} else return;
llMessageLinked(LINK_THIS,ch+swap, an1,(key)""); //msg to poser 1/2
llMessageLinked(LINK_THIS,ch+!swap,an2,(key)"");
llMessageLinked(LINK_THIS,ch+2, an3,(key)""); //msg to poser 3
llMessageLinked(LINK_THIS,ch+3, an4,(key)""); //msg to poser 4
llMessageLinked(LINK_THIS,ch+4, an5,(key)""); //msg to poser 4
llMessageLinked(LINK_THIS,ch+5, an6,(key)""); //msg to poser 4
}
}
state save {
state_entry() {
llMessageLinked(LINK_THIS,0,"GETREFPOS",""); //msg to pos: ask ref position
integer ix;
PRs = [ "", "", "", "", "", "" ];
for (ix = 0; ix < MAX_AVS; ++ix) {
llListen(ch+16+ix, "", NULL_KEY, "");
llSay(ch+ix,"SAVE"); //msg to balls
}
llSetTimerEvent(3);
UpdateCount = 0;
}
listen(integer channel, string name, key id, string pr) {
channel -= (ch + 16);
if (channel == 0) {
channel = channel + swap;
} else if (channel == 1) {
channel = channel - swap;
}
PRs = llListReplaceList(PRs, (list)pr, channel, channel);
if (++UpdateCount == BallCount) {
pr = "";
integer ix;
for (ix = 0; ix < BallCount; ++ix) {
pr += prStr(llList2String(PRs, ix)) + " ";
}
llOwnerSay("{"+pose+"} "+pr);
llMessageLinked(LINK_THIS,1,pose,pr); //write to memory
state on;
}
}
link_message(integer from, integer num, string posstr, key rotkey) {
if (posstr == "PRIMTOUCH"){
return;
}
if (num != 8) return;
pos = (vector)posstr; //revtrieve reference position from pos
rot = (rotation)((string)rotkey);
}
timer() {
state on;
}
state_exit() {
llSetTimerEvent(0);
}
}

198
TGLM/~poser 1.lsl Normal file
View File

@@ -0,0 +1,198 @@
// MPLV2 2.3 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V 1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch;
string animation = "stand";
key avatar;
integer ExprEnabled = TRUE;
string Expression;
float ExprTimer;
integer BallNum;
list Expressions = [
""
, "express_open_mouth" // 1
, "express_surprise_emote" // 2
, "express_tongue_out" // 3
, "express_smile" // 4
, "express_toothsmile" // 5
, "express_wink_emote" // 6
, "express_cry_emote" // 7
, "express_kiss" // 8
, "express_laugh_emote" // 9
, "express_disdain" // 10
, "express_repulsed_emote" // 11
, "express_anger_emote" // 12
, "express_bored_emote" // 13
, "express_sad_emote" // 14
, "express_embarrassed_emote" // 15
, "express_frown" // 16
, "express_shrug_emote" // 17
, "express_afraid_emote" // 18
, "express_worry_emote" // 19
, "SLEEP" // 20
];
stopAnim() {
key id = llGetPermissionsKey();
list anims = llGetAnimationList(id);
integer ix;
for (ix = 0; ix < llGetListLength(anims); ++ix) {
string anim = llList2String(anims, ix);
if (anim != "") {
llStopAnimation(anim);
}
}
llSetTimerEvent(0.0);
}
startAnim(string anim) {
if (Expression != "") {
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else {
llStartAnimation(Expression);
}
if (ExprEnabled) {
llSetTimerEvent(ExprTimer);
}
} else {
stopAnim();
}
if (anim != "") {
llStartAnimation(anim);
}
}
// Animation names with a "*" suffix get open mouth
// Those with a suffix of "::" followed by a number
// get the expression associated with that number.
// This can optionally be followed by another "::" delim,
// with a timer value following.
// Return the anim name without the suffix.
string getExpression(string anim) {
if (llGetSubString(anim,-1,-1) == "*") {
Expression = llList2String(Expressions, 1);
ExprTimer = 0.5;
return llGetSubString(anim, 0, -2);
}
integer ix = llSubStringIndex(anim, "::");
if (ix == -1) {
Expression = "";
ExprTimer = 0.5;
return anim;
}
list parms = llParseString2List(anim, ["::"], []);
anim = llList2String(parms, 0);
integer exprIx = (integer) llList2String(parms, 1);
Expression = llList2String(Expressions, exprIx);
ExprTimer = (float) llList2String(parms,2);
if (ExprTimer <= 0.0) {
ExprTimer = 0.5;
}
return anim;
}
getChan() {
BallNum = (integer) llGetSubString(llGetScriptName(),-1,-1); //offset from script name suffix
ch = BallNum
+ (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
state_entry() {
state s_on;
}
}
state s_on {
state_entry() {
getChan();
llListen(ch+8,"",NULL_KEY,"");
}
on_rez(integer arg) {
state default;
}
link_message(integer from, integer num, string an, key id) { //an animation is set
if (an == "PRIMTOUCH") {
return;
}
if (num != ch) return;
an = getExpression(an); // get & save expression, and return unadorned anim
if (avatar == llGetPermissionsKey()
&& avatar != NULL_KEY
&& animation != "") {
llStopAnimation(animation);
llMessageLinked(LINK_SET, -11002, (string)BallNum + "|" + an, llGetPermissionsKey());
startAnim(an);
}
animation = an;
}
timer() { // timer to keep mouth open
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else if (Expression != "") {
llStartAnimation(Expression);
}
}
listen(integer channel, string name, key id, string str) {
if (str == "ALIVE" || str == "DIE") {
llMessageLinked(LINK_THIS,2,str,""); //send msg from ball to menu
if (str == "DIE") {
avatar = NULL_KEY;
llSetTimerEvent(0.0);
}
return;
}
avatar = (key) str; //avatar (sit) or NULL_KEY (stand up)
if (avatar == NULL_KEY) {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
}
// llReleaseControls();
return;
}
if (avatar != llGetPermissionsKey()
|| ! (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
ExprEnabled = TRUE;
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);
} else {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
}
}
run_time_permissions(integer perm) {
if (avatar != llGetPermissionsKey()) {
llWhisper(DEBUG_CHANNEL, "avatar != perm key");
return;
}
if (perm & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
} else {
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
llSetTimerEvent(0.0);
}
}
}

198
TGLM/~poser 2.lsl Normal file
View File

@@ -0,0 +1,198 @@
// MPLV2 2.3 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - C opyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch;
string animation = "stand";
key avatar;
integer ExprEnabled = TRUE;
string Expression;
float ExprTimer;
integer BallNum;
list Expressions = [
""
, "express_open_mouth" // 1
, "express_surprise_emote" // 2
, "express_tongue_out" // 3
, "express_smile" // 4
, "express_toothsmile" // 5
, "express_wink_emote" // 6
, "express_cry_emote" // 7
, "express_kiss" // 8
, "express_laugh_emote" // 9
, "express_disdain" // 10
, "express_repulsed_emote" // 11
, "express_anger_emote" // 12
, "express_bored_emote" // 13
, "express_sad_emote" // 14
, "express_embarrassed_emote" // 15
, "express_frown" // 16
, "express_shrug_emote" // 17
, "express_afraid_emote" // 18
, "express_worry_emote" // 19
, "SLEEP" // 20
];
stopAnim() {
key id = llGetPermissionsKey();
list anims = llGetAnimationList(id);
integer ix;
for (ix = 0; ix < llGetListLength(anims); ++ix) {
string anim = llList2String(anims, ix);
if (anim != "") {
llStopAnimation(anim);
}
}
llSetTimerEvent(0.0);
}
startAnim(string anim) {
if (Expression != "") {
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else {
llStartAnimation(Expression);
}
if (ExprEnabled) {
llSetTimerEvent(ExprTimer);
}
} else {
stopAnim();
}
if (anim != "") {
llStartAnimation(anim);
}
}
// Animation names with a "*" suffix get open mouth
// Those with a suffix of "::" followed by a number
// get the expression associated with that number.
// This can optionally be followed by another "::" delim,
// with a timer value following.
// Return the anim name without the suffix.
string getExpression(string anim) {
if (llGetSubString(anim,-1,-1) == "*") {
Expression = llList2String(Expressions, 1);
ExprTimer = 0.5;
return llGetSubString(anim, 0, -2);
}
integer ix = llSubStringIndex(anim, "::");
if (ix == -1) {
Expression = "";
ExprTimer = 0.5;
return anim;
}
list parms = llParseString2List(anim, ["::"], []);
anim = llList2String(parms, 0);
integer exprIx = (integer) llList2String(parms, 1);
Expression = llList2String(Expressions, exprIx);
ExprTimer = (float) llList2String(parms,2);
if (ExprTimer <= 0.0) {
ExprTimer = 0.5;
}
return anim;
}
getChan() {
BallNum = (integer) llGetSubString(llGetScriptName(),-1,-1); //offset from script name suffix
ch = BallNum
+ (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
state_entry() {
state s_on;
}
}
state s_on {
state_entry() {
getChan();
llListen(ch+8,"",NULL_KEY,"");
}
on_rez(integer arg) {
state default;
}
link_message(integer from, integer num, string an, key id) { //an animation is set
if (an == "PRIMTOUCH") {
return;
}
if (num != ch) return;
an = getExpression(an); // get & save expression, and return unadorned anim
if (avatar == llGetPermissionsKey()
&& avatar != NULL_KEY
&& animation != "") {
llStopAnimation(animation);
llMessageLinked(LINK_SET, -11002, (string)BallNum + "|" + an, llGetPermissionsKey());
startAnim(an);
}
animation = an;
}
timer() { // timer to keep mouth open
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else if (Expression != "") {
llStartAnimation(Expression);
}
}
listen(integer channel, string name, key id, string str) {
if (str == "ALIVE" || str == "DIE") {
llMessageLinked(LINK_THIS,2,str,""); //send msg from ball to menu
if (str == "DIE") {
avatar = NULL_KEY;
llSetTimerEvent(0.0);
}
return;
}
avatar = (key) str; //avatar (sit) or NULL_KEY (stand up)
if (avatar == NULL_KEY) {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
}
// llReleaseControls();
return;
}
if (avatar != llGetPermissionsKey()
|| ! (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
ExprEnabled = TRUE;
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);
} else {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
}
}
run_time_permissions(integer perm) {
if (avatar != llGetPermissionsKey()) {
llWhisper(DEBUG_CHANNEL, "avatar != perm key");
return;
}
if (perm & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
} else {
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
llSetTimerEvent(0.0);
}
}
}

198
TGLM/~poser 3.lsl Normal file
View File

@@ -0,0 +1,198 @@
// MPLV2 2.3 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch;
string animation = "stand";
key avatar;
integer ExprEnabled = TRUE;
string Expression;
float ExprTimer;
integer BallNum;
list Expressions = [
""
, "express_open_mouth" // 1
, "express_surprise_emote" // 2
, "express_tongue_out" // 3
, "express_smile" // 4
, "express_toothsmile" // 5
, "express_wink_emote" // 6
, "express_cry_emote" // 7
, "express_kiss" // 8
, "express_laugh_emote" // 9
, "express_disdain" // 10
, "express_repulsed_emote" // 11
, "express_anger_emote" // 12
, "express_bored_emote" // 13
, "express_sad_emote" // 14
, "express_embarrassed_emote" // 15
, "express_frown" // 16
, "express_shrug_emote" // 17
, "express_afraid_emote" // 18
, "express_worry_emote" // 19
, "SLEEP" // 20
];
stopAnim() {
key id = llGetPermissionsKey();
list anims = llGetAnimationList(id);
integer ix;
for (ix = 0; ix < llGetListLength(anims); ++ix) {
string anim = llList2String(anims, ix);
if (anim != "") {
llStopAnimation(anim);
}
}
llSetTimerEvent(0.0);
}
startAnim(string anim) {
if (Expression != "") {
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else {
llStartAnimation(Expression);
}
if (ExprEnabled) {
llSetTimerEvent(ExprTimer);
}
} else {
stopAnim();
}
if (anim != "") {
llStartAnimation(anim);
}
}
// Animation names with a "*" suffix get open mouth
// Those with a suffix of "::" followed by a number
// get the expression associated with that number.
// This can optionally be followed by another "::" delim,
// with a timer value following.
// Return the anim name without the suffix.
string getExpression(string anim) {
if (llGetSubString(anim,-1,-1) == "*") {
Expression = llList2String(Expressions, 1);
ExprTimer = 0.5;
return llGetSubString(anim, 0, -2);
}
integer ix = llSubStringIndex(anim, "::");
if (ix == -1) {
Expression = "";
ExprTimer = 0.5;
return anim;
}
list parms = llParseString2List(anim, ["::"], []);
anim = llList2String(parms, 0);
integer exprIx = (integer) llList2String(parms, 1);
Expression = llList2String(Expressions, exprIx);
ExprTimer = (float) llList2String(parms,2);
if (ExprTimer <= 0.0) {
ExprTimer = 0.5;
}
return anim;
}
getChan() {
BallNum = (integer) llGetSubString(llGetScriptName(),-1,-1); //offset from script name suffix
ch = BallNum
+ (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
state_entry() {
state s_on;
}
}
state s_on {
state_entry() {
getChan();
llListen(ch+8,"",NULL_KEY,"");
}
on_rez(integer arg) {
state default;
}
link_message(integer from, integer num, string an, key id) { //an animation is set
if (an == "PRIMTOUCH") {
return;
}
if (num != ch) return;
an = getExpression(an); // get & save expression, and return unadorned anim
if (avatar == llGetPermissionsKey()
&& avatar != NULL_KEY
&& animation != "") {
llStopAnimation(animation);
llMessageLinked(LINK_SET, -11002, (string)BallNum + "|" + an, llGetPermissionsKey());
startAnim(an);
}
animation = an;
}
timer() { // timer to keep mouth open
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else if (Expression != "") {
llStartAnimation(Expression);
}
}
listen(integer channel, string name, key id, string str) {
if (str == "ALIVE" || str == "DIE") {
llMessageLinked(LINK_THIS,2,str,""); //send msg from ball to menu
if (str == "DIE") {
avatar = NULL_KEY;
llSetTimerEvent(0.0);
}
return;
}
avatar = (key) str; //avatar (sit) or NULL_KEY (stand up)
if (avatar == NULL_KEY) {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
}
// llReleaseControls();
return;
}
if (avatar != llGetPermissionsKey()
|| ! (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
ExprEnabled = TRUE;
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);
} else {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
}
}
run_time_permissions(integer perm) {
if (avatar != llGetPermissionsKey()) {
llWhisper(DEBUG_CHANNEL, "avatar != perm key");
return;
}
if (perm & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
} else {
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
llSetTimerEvent(0.0);
}
}
}

198
TGLM/~poser 4.lsl Normal file
View File

@@ -0,0 +1,198 @@
// MPLV2 2.3 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch;
string animation = "stand";
key avatar;
integer ExprEnabled = TRUE;
string Expression;
float ExprTimer;
integer BallNum;
list Expressions = [
""
, "express_open_mouth" // 1
, "express_surprise_emote" // 2
, "express_tongue_out" // 3
, "express_smile" // 4
, "express_toothsmile" // 5
, "express_wink_emote" // 6
, "express_cry_emote" // 7
, "express_kiss" // 8
, "express_laugh_emote" // 9
, "express_disdain" // 10
, "express_repulsed_emote" // 11
, "express_anger_emote" // 12
, "express_bored_emote" // 13
, "express_sad_emote" // 14
, "express_embarrassed_emote" // 15
, "express_frown" // 16
, "express_shrug_emote" // 17
, "express_afraid_emote" // 18
, "express_worry_emote" // 19
, "SLEEP" // 20
];
stopAnim() {
key id = llGetPermissionsKey();
list anims = llGetAnimationList(id);
integer ix;
for (ix = 0; ix < llGetListLength(anims); ++ix) {
string anim = llList2String(anims, ix);
if (anim != "") {
llStopAnimation(anim);
}
}
llSetTimerEvent(0.0);
}
startAnim(string anim) {
if (Expression != "") {
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else {
llStartAnimation(Expression);
}
if (ExprEnabled) {
llSetTimerEvent(ExprTimer);
}
} else {
stopAnim();
}
if (anim != "") {
llStartAnimation(anim);
}
}
// Animation names with a "*" suffix get open mouth
// Those with a suffix of "::" followed by a number
// get the expression associated with that number.
// This can optionally be followed by another "::" delim,
// with a timer value following.
// Return the anim name without the suffix.
string getExpression(string anim) {
if (llGetSubString(anim,-1,-1) == "*") {
Expression = llList2String(Expressions, 1);
ExprTimer = 0.5;
return llGetSubString(anim, 0, -2);
}
integer ix = llSubStringIndex(anim, "::");
if (ix == -1) {
Expression = "";
ExprTimer = 0.5;
return anim;
}
list parms = llParseString2List(anim, ["::"], []);
anim = llList2String(parms, 0);
integer exprIx = (integer) llList2String(parms, 1);
Expression = llList2String(Expressions, exprIx);
ExprTimer = (float) llList2String(parms,2);
if (ExprTimer <= 0.0) {
ExprTimer = 0.5;
}
return anim;
}
getChan() {
BallNum = (integer) llGetSubString(llGetScriptName(),-1,-1); //offset from script name suffix
ch = BallNum
+ (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
state_entry() {
state s_on;
}
}
state s_on {
state_entry() {
getChan();
llListen(ch+8,"",NULL_KEY,"");
}
on_rez(integer arg) {
state default;
}
link_message(integer from, integer num, string an, key id) { //an animation is set
if (an == "PRIMTOUCH") {
return;
}
if (num != ch) return;
an = getExpression(an); // get & save expression, and return unadorned anim
if (avatar == llGetPermissionsKey()
&& avatar != NULL_KEY
&& animation != "") {
llStopAnimation(animation);
llMessageLinked(LINK_SET, -11002, (string)BallNum + "|" + an, llGetPermissionsKey());
startAnim(an);
}
animation = an;
}
timer() { // timer to keep mouth open
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else if (Expression != "") {
llStartAnimation(Expression);
}
}
listen(integer channel, string name, key id, string str) {
if (str == "ALIVE" || str == "DIE") {
llMessageLinked(LINK_THIS,2,str,""); //send msg from ball to menu
if (str == "DIE") {
avatar = NULL_KEY;
llSetTimerEvent(0.0);
}
return;
}
avatar = (key) str; //avatar (sit) or NULL_KEY (stand up)
if (avatar == NULL_KEY) {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
}
// llReleaseControls();
return;
}
if (avatar != llGetPermissionsKey()
|| ! (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
ExprEnabled = TRUE;
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);
} else {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
}
}
run_time_permissions(integer perm) {
if (avatar != llGetPermissionsKey()) {
llWhisper(DEBUG_CHANNEL, "avatar != perm key");
return;
}
if (perm & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
} else {
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
llSetTimerEvent(0.0);
}
}
}

198
TGLM/~poser 5.lsl Normal file
View File

@@ -0,0 +1,198 @@
// MPLV2 2.3 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch;
string animation = "stand";
key avatar;
integer ExprEnabled = TRUE;
string Expression;
float ExprTimer;
integer BallNum;
list Expressions = [
""
, "express_open_mouth" // 1
, "express_surprise_emote" // 2
, "express_tongue_out" // 3
, "express_smile" // 4
, "express_toothsmile" // 5
, "express_wink_emote" // 6
, "express_cry_emote" // 7
, "express_kiss" // 8
, "express_laugh_emote" // 9
, "express_disdain" // 10
, "express_repulsed_emote" // 11
, "express_anger_emote" // 12
, "express_bored_emote" // 13
, "express_sad_emote" // 14
, "express_embarrassed_emote" // 15
, "express_frown" // 16
, "express_shrug_emote" // 17
, "express_afraid_emote" // 18
, "express_worry_emote" // 19
, "SLEEP" // 20
];
stopAnim() {
key id = llGetPermissionsKey();
list anims = llGetAnimationList(id);
integer ix;
for (ix = 0; ix < llGetListLength(anims); ++ix) {
string anim = llList2String(anims, ix);
if (anim != "") {
llStopAnimation(anim);
}
}
llSetTimerEvent(0.0);
}
startAnim(string anim) {
if (Expression != "") {
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else {
llStartAnimation(Expression);
}
if (ExprEnabled) {
llSetTimerEvent(ExprTimer);
}
} else {
stopAnim();
}
if (anim != "") {
llStartAnimation(anim);
}
}
// Animation names with a "*" suffix get open mouth
// Those with a suffix of "::" followed by a number
// get the expression associated with that number.
// This can optionally be followed by another "::" delim,
// with a timer value following.
// Return the anim name without the suffix.
string getExpression(string anim) {
if (llGetSubString(anim,-1,-1) == "*") {
Expression = llList2String(Expressions, 1);
ExprTimer = 0.5;
return llGetSubString(anim, 0, -2);
}
integer ix = llSubStringIndex(anim, "::");
if (ix == -1) {
Expression = "";
ExprTimer = 0.5;
return anim;
}
list parms = llParseString2List(anim, ["::"], []);
anim = llList2String(parms, 0);
integer exprIx = (integer) llList2String(parms, 1);
Expression = llList2String(Expressions, exprIx);
ExprTimer = (float) llList2String(parms,2);
if (ExprTimer <= 0.0) {
ExprTimer = 0.5;
}
return anim;
}
getChan() {
BallNum = (integer) llGetSubString(llGetScriptName(),-1,-1); //offset from script name suffix
ch = BallNum
+ (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
state_entry() {
state s_on;
}
}
state s_on {
state_entry() {
getChan();
llListen(ch+8,"",NULL_KEY,"");
}
on_rez(integer arg) {
state default;
}
link_message(integer from, integer num, string an, key id) { //an animation is set
if (an == "PRIMTOUCH") {
return;
}
if (num != ch) return;
an = getExpression(an); // get & save expression, and return unadorned anim
if (avatar == llGetPermissionsKey()
&& avatar != NULL_KEY
&& animation != "") {
llStopAnimation(animation);
llMessageLinked(LINK_SET, -11002, (string)BallNum + "|" + an, llGetPermissionsKey());
startAnim(an);
}
animation = an;
}
timer() { // timer to keep mouth open
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else if (Expression != "") {
llStartAnimation(Expression);
}
}
listen(integer channel, string name, key id, string str) {
if (str == "ALIVE" || str == "DIE") {
llMessageLinked(LINK_THIS,2,str,""); //send msg from ball to menu
if (str == "DIE") {
avatar = NULL_KEY;
llSetTimerEvent(0.0);
}
return;
}
avatar = (key) str; //avatar (sit) or NULL_KEY (stand up)
if (avatar == NULL_KEY) {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
}
// llReleaseControls();
return;
}
if (avatar != llGetPermissionsKey()
|| ! (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
ExprEnabled = TRUE;
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);
} else {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
}
}
run_time_permissions(integer perm) {
if (avatar != llGetPermissionsKey()) {
llWhisper(DEBUG_CHANNEL, "avatar != perm key");
return;
}
if (perm & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, llGetPermissionsKey());
startAnim(animation);
} else {
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
llSetTimerEvent(0.0);
}
}
}

198
TGLM/~poser.lsl Normal file
View File

@@ -0,0 +1,198 @@
// MPLV2 2.3 by Learjeff Innis, ba sed on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch;
string animation = "stand";
key avatar;
integer ExprEnabled = TRUE;
string Expression;
float ExprTimer;
integer BallNum;
list Expressions = [
""
, "express_open_mouth" // 1
, "express_surprise_emote" // 2
, "express_tongue_out" // 3
, "express_smile" // 4
, "express_toothsmile" // 5
, "express_wink_emote" // 6
, "express_cry_emote" // 7
, "express_kiss" // 8
, "express_laugh_emote" // 9
, "express_disdain" // 10
, "express_repulsed_emote" // 11
, "express_anger_emote" // 12
, "express_bored_emote" // 13
, "express_sad_emote" // 14
, "express_embarrassed_emote" // 15
, "express_frown" // 16
, "express_shrug_emote" // 17
, "express_afraid_emote" // 18
, "express_worry_emote" // 19
, "SLEEP" // 20
];
stopAnim() {
key id = llGetPermissionsKey();
list anims = llGetAnimationList(id);
integer ix;
for (ix = 0; ix < llGetListLength(anims); ++ix) {
string anim = llList2String(anims, ix);
if (anim != "") {
llStopAnimation(anim);
}
}
llSetTimerEvent(0.0);
}
startAnim(string anim) {
if (Expression != "") {
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else {
llStartAnimation(Expression);
}
if (ExprEnabled) {
llSetTimerEvent(ExprTimer);
}
} else {
stopAnim();
}
if (anim != "") {
llStartAnimation(anim);
}
}
// Animation names with a "*" suffix get open mouth
// Those with a suffix of "::" followed by a number
// get the expression associated with that number.
// This can optionally be followed by another "::" delim,
// with a timer value following.
// Return the anim name without the suffix.
string getExpression(string anim) {
if (llGetSubString(anim,-1,-1) == "*") {
Expression = llList2String(Expressions, 1);
ExprTimer = 0.5;
return llGetSubString(anim, 0, -2);
}
integer ix = llSubStringIndex(anim, "::");
if (ix == -1) {
Expression = "";
ExprTimer = 0.5;
return anim;
}
list parms = llParseString2List(anim, ["::"], []);
anim = llList2String(parms, 0);
integer exprIx = (integer) llList2String(parms, 1);
Expression = llList2String(Expressions, exprIx);
ExprTimer = (float) llList2String(parms,2);
if (ExprTimer <= 0.0) {
ExprTimer = 0.5;
}
return anim;
}
getChan() {
BallNum = (integer) llGetSubString(llGetScriptName(),-1,-1); //offset from script name suffix
ch = BallNum
+ (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
default {
state_entry() {
state s_on;
}
}
state s_on {
state_entry() {
getChan();
llListen(ch+8,"",NULL_KEY,"");
}
on_rez(integer arg) {
state default;
}
link_message(integer from, integer num, string an, key id) { //an animation is set
if (an == "PRIMTOUCH") {
return;
}
if (num != ch) return;
an = getExpression(an); // get & save expression, and return unadorned anim
if (avatar == llGetPermissionsKey()
&& avatar != NULL_KEY
&& animation != "") {
llStopAnimation(animation);
llMessageLinked(LINK_SET, -11002, (string)BallNum + "|" + an, avatar);
startAnim(an);
}
animation = an;
}
timer() { // timer to keep mouth open
if (Expression == "SLEEP") {
llStartAnimation("express_disdain");
llStartAnimation("express_smile");
} else if (Expression != "") {
llStartAnimation(Expression);
}
}
listen(integer channel, string name, key id, string str) {
if (str == "ALIVE" || str == "DIE") {
llMessageLinked(LINK_THIS,2,str,""); //send msg from ball to menu
if (str == "DIE") {
avatar = NULL_KEY;
llSetTimerEvent(0.0);
}
return;
}
avatar = (key) str; //avatar (sit) or NULL_KEY (stand up)
if (avatar == NULL_KEY) {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11001, (string)BallNum, llGetPermissionsKey());
}
// llReleaseControls();
return;
}
if (avatar != llGetPermissionsKey()
|| ! (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
ExprEnabled = TRUE;
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);
} else {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, avatar);
startAnim(animation);
}
}
run_time_permissions(integer perm) {
if (avatar != llGetPermissionsKey()) {
llWhisper(DEBUG_CHANNEL, "avatar != perm key");
return;
}
if (perm & PERMISSION_TRIGGER_ANIMATION) {
stopAnim();
llMessageLinked(LINK_SET, -11000, (string)BallNum + "|" + animation, avatar);
startAnim(animation);
} else {
llMessageLinked(LINK_SET, -11001, (string)BallNum, avatar);
llSetTimerEvent(0.0);
}
}
}

383
TGLM/~props.lsl Normal file
View File

@@ -0,0 +1,383 @@
//MPLV2 Version 2.3 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
// v2.2 - rotate all props
// This script handles props (object rezzed for a given pose)
integer Checking = FALSE; // whether doing consistency check
integer Line;
integer PoseCount;
list Poses; // name of each pose with a prop
list Positions; // position of prop, indexed as Poses
list Props; // name of each prop object, indexed as Poses
string Pose; // current pose name
integer ChatChan; // chan for talking to object
init()
{
ChatChan = - 1 - (integer)llFrand(-DEBUG_CHANNEL);
getRefPos();
}
vector RefPos;
rotation RefRot;
getRefPos() { //reference position
RefPos = llGetPos();
RefRot = llGetRot();
integer z = (integer)llGetObjectDesc();
RefPos.z = RefPos.z + (float)z/100.0;
}
string plural(string singular, string plural, integer count) {
if (count != 1) {
return plural;
}
return singular;
}
announce()
{
llOwnerSay((string)PoseCount
+ plural(" pose", " poses", PoseCount)
+ " with props ("
+ llGetScriptName()
+ ": "
+ (string)llGetFreeMemory()
+ " bytes free)");
}
string adjust(integer doOffset, vector pos, vector erot, vector amt) {
if (doOffset) {
pos = pos + amt/100.;
return (vround(pos) + "/" + vround(erot));
}
rotation amount = llEuler2Rot(amt * DEG_TO_RAD);
erot *= DEG_TO_RAD;
rotation oldrot = llEuler2Rot(erot);
rotation newrot = oldrot / amount;
erot = llRot2Euler(newrot) * RAD_TO_DEG;
pos = pos / amount;
return(vround(pos) + "/" + vround(erot));
}
adjust_all(integer doOffset, vector amt) {
integer ix;
integer bx;
string data;
list ldata;
vector pos;
vector erot;
for (ix = 0; ix < llGetListLength(Poses); ++ix) {
data = llList2String(Positions, ix);
ldata = llParseString2List(data, ["/"], []);
pos = (vector)llList2String(ldata, 0);
erot = (vector)llList2String(ldata, 1);
data = adjust(doOffset, pos, erot, amt);
Positions = llListReplaceList(Positions, (list)data, ix, ix);
}
llOwnerSay("Prop rotation complete");
}
string roundData(string data) {
list ldata = llParseString2List(data, ["/"], []);
return (vround((vector)llList2String(ldata, 0)) + "/" + vround((vector)llList2String(ldata, 1)));
}
// round a vector's components and return as vector value string
string vround(vector vec) {
return ("<"+round(vec.x, 3)+","+round(vec.y, 3)+","+round(vec.z, 3)+">");
}
string round(float number, integer places) {
float shifted;
integer rounded;
string s;
shifted = number * llPow(10.0,(float)places);
rounded = llRound(shifted);
s = (string)((float)rounded / llPow(10.0,(float)places));
s = llGetSubString(s,0,llSubStringIndex(s, ".")+places);
return s;
}
add_prop(string pose, string prop, string data) {
if (llListFindList(Props, (list)pose) != -1) {
llOwnerSay("Multiple *.PROPS* entries for pose '" + pose + "'");
}
if (llGetInventoryType(prop) != INVENTORY_OBJECT) {
llOwnerSay("Warning: can't find prop '" + prop + "' in inventory");
}
Poses = [] + Poses + (list) pose;
Props = [] + Props + (list) prop;
Positions = [] + Positions + (list)roundData(data);
++PoseCount;
}
string get_pose_data(string pose) {
integer ix = llListFindList(Poses, (list)pose);
if (ix == -1) {
return "";
}
return llList2String(Positions, ix);
}
save_prop(string pose, string prop, string data) {
integer ix = llListFindList(Poses, [pose]);
if (ix == -1) {
// llSay(0, "new pose");
add_prop(pose, prop, data); // don't expect this to happen
return;
}
// if the prop object name doesn't match, ignore it -- assume it's noise
if (llList2String(Props, ix) != prop) {
return;
}
// Data is the change in position since we rezzed it, in global coords
// Convert delta to local axes
list ldata = llParseString2List(data, ["/"], []);
vector pos = (vector) llList2String(ldata, 0);
rotation rot = (rotation)llList2String(ldata, 1);
pos = pos / RefRot;
vector erot = llRot2Euler(rot/RefRot) * RAD_TO_DEG;
// Now add to saved data (since it was a delta)
ldata = llParseStringKeepNulls(llList2String(Positions, ix), ["/"], []);
vector oldpos = (vector)llList2String(ldata, 0);
pos = pos + oldpos;
data = vround(pos) + "/" + vround(erot);
Props = llListReplaceList(Props, (list)prop, ix, ix);
Positions = llListReplaceList(Positions, (list)data, ix, ix);
string name = llGetObjectName();
llSetObjectName("");
llOwnerSay("| " + pose + " | " + prop + " | " + data);
llSetObjectName(name);
}
rez_prop(string pose) {
llSay(ChatChan, "DIE");
integer ix = llListFindList(Poses, [pose]);
if (ix == -1) {
Pose = "";
llSetTimerEvent(0.0);
return;
}
string prop = llList2String(Props, ix);
string data = llList2String(Positions, ix);
list ldata = llParseString2List(data, ["/"], []);
vector pos = (vector)llList2String(ldata, 0);
vector erot = (vector)llList2String(ldata, 1);
pos = pos * RefRot + RefPos;
rotation rot = llEuler2Rot(erot*DEG_TO_RAD) * RefRot;
// llSay(0, "rezzing '" + prop + "' at " + (string) pos);
llRezAtRoot(prop, pos, <0.,0.,0.>, rot, ChatChan);
llSetTimerEvent(60.0);
Pose = pose;
}
dashes() {
llOwnerSay("_______________________________________________________________________________");
llOwnerSay("");
}
// Globals for reading card config
integer ConfigLineIndex;
list ConfigCards; // list of names of config cards
string ConfigCardName; // name of card being read
integer ConfigCardIndex; // index of next card to read
key ConfigQueryId;
integer next_card()
{
if (ConfigCardIndex >= llGetListLength(ConfigCards)) {
ConfigCards = [];
return (FALSE);
}
ConfigLineIndex = 0;
ConfigCardName = llList2String(ConfigCards, ConfigCardIndex);
ConfigCardIndex++;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex);
llOwnerSay("Reading " + ConfigCardName);
return (TRUE);
}
default {
state_entry() {
llSleep(0.25); // give ~run a chance to shut us down
string item;
ConfigCards = [];
integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
while (n-- > 0) {
item = llGetInventoryName(INVENTORY_NOTECARD, n);
if (llSubStringIndex(item, ".PROPS") != -1) {
ConfigCards = [] + ConfigCards + (list) item;
}
}
ConfigCardIndex = 0;
ConfigCards = llListSort(ConfigCards, 1, TRUE);
next_card();
}
dataserver(key query_id, string data) {
if (query_id != ConfigQueryId) {
return;
}
if (data == EOF) {
if (next_card()) {
return;
}
state on;
}
data = llStringTrim(data, STRING_TRIM);
if (llGetSubString(data,0,0) != "/" && llStringLength(data)) { // skip comments and blank lines
list ldata = llParseStringKeepNulls(data, [" | "," | "," | "," | "," |","| ","|"], []);
if (llGetListLength(ldata) != 4) {
llOwnerSay(llGetScriptName() + ": error in " + ConfigCardName + ":" + (string)ConfigLineIndex
+ " - need exactly 3 vertical bars - line ignored");
} else {
string pose = llList2String(ldata, 1);
string prop = llList2String(ldata, 2);
string data1 = llStringTrim(llList2String(ldata, 3), STRING_TRIM);
if (data1 == "") {
data1 = "<0,0,1>/<0,0,0>";
}
add_prop(pose, prop, data1);
}
}
++ConfigLineIndex;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex); //read next line of positions notecard
}
state_exit() {
// do one save to indicate actual amount of available memory
string position = llList2String(Positions, 0);
Positions = llListReplaceList(Positions, [position],0,0);
llMessageLinked(LINK_THIS, 2, "OK", (key)""); //msg to menu, in case it's waiting for loading
announce();
}
}
state re_on
{
state_entry() {
state on;
}
}
state on {
state_entry() {
init();
llListen(ChatChan, "", NULL_KEY, "");
}
on_rez(integer arg) {
state re_on;
}
listen(integer chan, string name, key id, string msg) {
// llSay(0, name + ": " + msg);
if (Pose == "") {
return;
}
save_prop(Pose, name, msg);
announce();
}
link_message(integer from, integer num, string str, key dkey) {
if (str == "PRIMTOUCH" || num < 0) {
return;
}
if (num == 0) {
if (str == "POSEB") {
rez_prop((string)dkey);
return;
}
if (str == "REPOS") {
getRefPos();
return;
}
return;
}
if (num != 1) {
return;
}
if (str == "STOP") {
llSay(ChatChan, "DIE");
Pose = "";
llSetTimerEvent(0.0);
}
if (str == "DUMPPROPS") {
dashes();
llOwnerSay("Copy to .PROPS; delete any other *.PROPS* cards");
dashes();
string name = llGetObjectName();
llSetObjectName("");
integer ix;
for (ix = 0; ix < PoseCount; ++ix) {
string pose = llList2String(Poses, ix);
string prop = llList2String(Props, ix);
llOwnerSay("| " + pose + " | " + prop + " | " + get_pose_data(pose));
}
llSetObjectName(name);
dashes();
} else if (llSubStringIndex(str, "REORIENT=") == 0) {
// Reorient command (LINKMENU command from .MENUITEMS file)
// str format: REORIENT=OFF=<x,y,z> or REORIENT=ROT=<x,y,z> (in degrees)
list parms = llParseString2List(str, ["="], []);
vector amount = (vector)llList2String(parms, 2);
llWhisper(0, "Adjusting props, please wait");
if (llList2String(parms, 1) == "OFF") {
adjust_all(TRUE, amount);
} else {
adjust_all(FALSE, amount);
}
llMessageLinked(LINK_THIS, 0, "AGAIN", (key)"");
llWhisper(0, "Prop adjustment complete");
} else if (str == "SAVEPROP") {
llSay(ChatChan, "SAVE");
}
}
timer() {
llSay(ChatChan, "LIVE");
}
}

190
TGLM/~run.lsl Normal file
View File

@@ -0,0 +1,190 @@
//MLPV2 Version 2.3 - Learjeff Innis, from
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 20 06, by Miffy Fluffy (BSD License)
//To donate, go to my profile (Search - People - Miffy Fluffy) and use the "Pay..." button, thanks!
//You can also find the link to the latest version here.
integer MAX_AVS = 6;
integer ResetOnOwnerChange = FALSE;
// DESCRIPTION OF THE SCRIPTS
//
// ~run:
// Default: sets other scripts to not running.
// When the object is touched it will start all scrips.
//
// ~memory:
// Here the positions are stored permanently. Information is still kept when the script is
// not running or when everything is placed in inventory. The information will be lost only
// when the ~memory script is reset.
// A backup can be made on the .POSITIONS notecard, when the memory is empty, it will start
// reading the .POSITIONS notecard automatically.
//
// ~menu:
// 1.loading: reads the .MENUITEMS notecard and builds the menu.
// When it reads a "POSE": - the animations are stored in ~pose
// - their matching positions are looked up in ~memory and stored
// in ~pos.
// 2.ready:
// When the object is touched: - shows the main menu
// - listens for menu selections.
//
// When a submenu is selected: - shows the submenu
// - when balls are defined for this submenu it will rez
// balls (if not already there) and set their colors.
//
// When a pose is selected: - ~pose will send the animations to ~pose1 and ~pose2,
// they will set the animations to the avatars
// - ~pos wil send the matching positions to each ball.
//
// When a position is saved: - ~pose will ask the balls for their position
// - the positions are saved in ~memory ("permanent")
// - the positions are updated in ~pos
//
// When "STOP" is selected: - will hide the balls
// - will stop the pose
// When "STOP" is selected again (or if no pose is started yet):
// - will remove the balls (derez/die)
//
// ~pos:
// - loads the positions from ~memory and stores them (until shutdown/restart)
// - sends positions for the selected pose to the balls
//
// ~pose:
// - loads the animations from the .MENUITEMS notecard and stores them (until shutdown/restart)
// - sends animations for the selected pose to ~pose1 and ~pose2
// - when saving a position: will ask balls for their position and sends it to ~pos and ~memory
// (~pos would be a more logical place to handle this, but ~pose has more free memory).
//
// ~poser, ~poser 1, ~poser 2, ~poser 3 (one for each ball):
// - will ask permission to animate the avatar on ball
// - will set the animations to avatar
//
// ~ball
// - when balls are defined for a submenu (in .MENUITEMS), ~menu will rez copies of ~ball
// - each will receive a unique communication channel from ~menu
// - the color for each ball is set by ~menu
// - the position of each ball is set by ~pos
// - when an avatar selects to sit on a ball, the avatar info is sent to the appropriate; they
// will ask permission and set the animation directly to the avatar (not via the ball)
// - balls will commit suicide when they don't hear a "LIVE" message each minute (from ~menu).
//
// have fun!
//Note: if you make a revised version, please mention something like this:
//"MLP - alternative version by ... .... - Revision 1 (based on MLP V1.2 by Miffy Fluffy)
key Owner;
list Scripts = [
"~menucfg"
, "~pos"
, "~pose"
, "~poser"
, "~poser 1"
, "~poser 2"
, "~poser 3"
, "~poser 4"
, "~poser 5"
];
list OptionalScripts = [
"~props"
, "~sequencer"
];
setRunning(integer st) {
integer ix;
list scripts = Scripts;
string script;
for (ix = 0; ix < 100; ++ix) {
integer jx;
// try to stop any remaining scripts in the list
for (jx = llGetListLength(scripts) - 1; jx >= 0; --jx) {
script = llList2String(scripts, jx);
if (llGetInventoryType(script) == INVENTORY_SCRIPT) {
llSetScriptState(script, st);
scripts = llDeleteSubList(scripts, jx, jx);
--jx;
}
}
// got them all yet?
if (llGetListLength(scripts) == 0) {
// Yes -- handle key ones
llSetScriptState("~memory", st);
llSetScriptState("~menu", st);
if (st) {
llResetOtherScript("~memory");
llResetOtherScript("~menu");
}
// start/stop optional scripts if present
for (jx = llGetListLength(OptionalScripts) - 1; jx >= 0; --jx) {
script = llList2String(OptionalScripts, jx);
if (llGetInventoryType(script) == INVENTORY_SCRIPT) {
llSetScriptState(script, st);
}
}
return;
}
llSleep(0.1);
}
llOwnerSay("missing scripts: " + llList2CSV(scripts));
}
setBalls(string cmd) {
integer ch = channel();
integer ix;
for (ix = 0; ix < MAX_AVS; ++ix) {
llSay(ch + ix, cmd); //msg to balls
}
}
integer channel() {
return (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1));
}
default {
state_entry() {
setBalls("DIE");
Owner = llGetOwner();
setRunning(FALSE);
llOwnerSay("OFF (touch to switch on)");
}
touch_start(integer i) {
if (llDetectedKey(0) == llGetOwner()) state run;
}
// Waits for another script to send a link message.
link_message(integer sender_num, integer num, string str, key id) {
if (str == "PRIMTOUCH" && id == llGetOwner()) {
state run;
}
}
changed(integer change) {
if (change & CHANGED_OWNER && Owner != llGetOwner()) {
llResetScript();
}
}
}
state run {
state_entry() {
setRunning(TRUE);
}
changed(integer change) {
if (ResetOnOwnerChange
&& (change & CHANGED_OWNER)
&& Owner != llGetOwner()) {
llResetScript();
}
}
}

447
TGLM/~sequencer.lsl Normal file
View File

@@ -0,0 +1,447 @@
//MPLV2 Version 2.3 by Learjeff Innis, based on
//MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Mi ffy Fluffy (BSD License)
// Allow programmed sequences of poses
// This script resets whenever any of its config cards change.
integer MAX_AVS = 6;
list SeqNames; // name of each sequence
list SeqSteps; // CSV of steps for each seq, indexed as SeqNames
list CurSeqSteps;
string CurSeqName;
integer CurSeqStepIx;
string CurMenu;
string CurPose;
// debugs:
// 1 = sequence start/stop
// 2 = echo each step as executed
// 4 = av hop on/off
// 8 = avwait check
// 0x10 = debug config
integer Debug;
list DELIMS = [" | "," | "," | "," | "," |","| ","|"];
list COMMANDS = [
"MENU"
, "POSE"
, "WAIT"
, "REPEAT"
, "LABEL"
, "GOTO"
, "STOP"
, "WHISPER"
, "SAY"
, "AVWAIT"
];
config_init() {
SeqNames = [];
SeqSteps = [];
Debug = 0;
}
config_done() {
seq_save(); // save last sequence, if any
debug(0x10, "Names: " + llList2CSV(SeqNames));
}
parse_config_line(string data) {
if (llGetSubString(data,0,0) == "/" || llStringLength(data) == 0) { // skip comments and blank lines
return;
}
list ldata = llParseStringKeepNulls(data, DELIMS, []);
string cmd = llList2String(ldata, 0);
string arg1 = llList2String(ldata, 1);
string arg2 = llList2String(ldata, 2);
string arg3 = llList2String(ldata, 3);
if (cmd == "SEQUENCE") {
seq_save(); // save previous sequence, if any
CurSeqName = arg1;
CurSeqSteps = [];
} else if (llListFindList(COMMANDS, (list)cmd) >= 0) {
if (cmd == "LABEL") {
CurSeqSteps += (list) (cmd + "|" + arg1);
} else {
CurSeqSteps += (list) (cmd + "|" + arg1 + "|" + arg2 + "|" + arg3);
}
} else if (cmd == "debug") {
Debug += (integer)arg1;
} else {
llWhisper(0, "Unknown sequence command: '" + cmd + "' - ignoring");
}
}
list Avnames; // one for each ball
integer Avwait;
list AvwaitBalls;
// List of avatar names per ball: adding/removing/checking
addAv(string name, integer ballIx) {
Avnames = llListReplaceList(Avnames, (list)name, ballIx, ballIx);
if (Avwait && avs_seated()) {
Avwait = FALSE;
llSetTimerEvent(0.1);
}
}
removeAv(integer ballIx) {
addAv("", ballIx);
}
integer avs_seated() {
integer ix;
integer ball;
for (ix = llGetListLength(AvwaitBalls) - 1; ix >= 0; --ix) {
ball = llList2Integer(AvwaitBalls, ix);
if (llList2String(Avnames, ball) == "") {
debug(8, "Nobody on ball " + (string) ball);
return FALSE;
}
}
debug(8, "All avs seated");
return TRUE;
}
// In 'src', replace 'target' string with 'replacement' string,
// and return the result.
string replace_text(string src, string target, string replacement)
{
string text = src;
integer ix;
ix = llSubStringIndex(src, target);
if (ix >= 0) {
text = llDeleteSubString(text, ix, ix + llStringLength(target) - 1);
text = llInsertString(text, ix, replacement);
}
return (text);
}
string firstname(string name) {
return llList2String(llParseString2List(name, [" "], []), 0);
}
string customize(string src) {
integer avix;
string avname;
for (avix = 0; avix < MAX_AVS; ++avix) {
avname = firstname(llList2String(Avnames, avix));
if (avname == "") avname = "somebody";
src = replace_text(src, "/"+(string)avix, avname);
}
return src;
}
send_cmd(string cmd) {
llMessageLinked(LINK_THIS, -12002, cmd, (key)"");
}
seq_save() {
if (CurSeqName == "") {
return;
}
SeqNames += CurSeqName;
SeqSteps += llList2CSV(CurSeqSteps);
}
seq_start(string name) {
Avwait = FALSE;
integer ix = llListFindList(SeqNames, (list)name);
if (ix < 0) {
llWhisper(0, "No such sequence: '" + name + "'");
CurSeqSteps = [];
CurSeqStepIx = -1;
return;
}
debug(1, "Start sequence " + name);
CurSeqStepIx = 0;
CurSeqSteps = llCSV2List(llList2String(SeqSteps, ix));
seq_execute();
}
seq_advance() {
if (++CurSeqStepIx >= llGetListLength(CurSeqSteps)) {
seq_stop();
}
}
seq_execute() {
list step;
string cmd;
string arg1;
string arg2;
string arg3;
while (CurSeqStepIx >= 0) {
step = llParseString2List(llList2String(CurSeqSteps, CurSeqStepIx), DELIMS, []);
cmd = llList2String(step, 0);
arg1 = llList2String(step, 1);
arg2 = llList2String(step, 2);
arg3 = llList2String(step, 3);
debug(2, cmd + "|" + arg1);
if (cmd == "MENU") {
CurMenu = arg1;
send_cmd(CurMenu);
seq_advance();
} else if (cmd == "POSE") {
// llSleep(.5);
CurPose = arg1;
send_cmd(arg1);
if (arg3 != "") {
llWhisper((integer)arg2, customize(arg3));
}
seq_advance();
} else if (cmd == "WAIT") {
llSetTimerEvent((float) arg1);
seq_advance();
return;
} else if (cmd == "REPEAT") {
CurSeqStepIx = 0;
} else if (cmd == "LABEL") {
seq_advance();
} else if (cmd == "GOTO") {
CurSeqStepIx = llListFindList(CurSeqSteps, (list)("LABEL|" + arg1));
if (CurSeqStepIx < 0) {
llWhisper(0, "No such sequence label: '" + arg1 + "'");
seq_stop();
return;
}
} else if (cmd == "WHISPER") {
llWhisper((integer)arg1, customize(arg2));
seq_advance();
} else if (cmd == "SAY") {
llSay((integer)arg1, customize(arg2));
seq_advance();
} else if (cmd == "AVWAIT") {
integer argix;
integer ballix;
AvwaitBalls = [];
list balls = llParseString2List(arg1, [" "], []);
for (argix = llGetListLength(balls) - 1; argix >= 0; --argix) {
ballix = (integer)llList2String(balls, argix);
AvwaitBalls += (list)(ballix);
}
seq_advance();
if (! avs_seated()) {
llSetTimerEvent(0.); // just to be sure
if (arg2 != "") {
llWhisper(0, arg2);
}
Avwait = TRUE;
return;
}
} else {
send_cmd(cmd);
seq_advance();
}
}
}
seq_stop() {
Avwait = FALSE;
debug(1, "stopping sequence");
CurSeqStepIx = -1;
llSetTimerEvent(0.);
}
debug(integer level, string txt) {
if (Debug & level) {
llWhisper(0, llGetScriptName() + ": " + txt);
}
}
string plural(string singular, string plural, integer count) {
if (count != 1) {
return plural;
}
return singular;
}
announce()
{
integer count = llGetListLength(SeqNames);
llOwnerSay((string)count
+ plural(" sequence (", " sequences (", count)
+ llGetScriptName()
+ ": "
+ (string)llGetFreeMemory()
+ " bytes free)");
}
// Globals for reading card config
integer ConfigLineIndex;
list ConfigCards; // list of names of config cards
string ConfigCardName; // name of card being read
integer ConfigCardIndex; // index of next card to read
key ConfigQueryId;
string ConfigCardKeys; // to see if anything changed
string get_cards() {
ConfigCards = [];
string keys = "";
string item;
integer ix = llGetInventoryNumber(INVENTORY_NOTECARD);
while (ix-- > 0) {
item = llGetInventoryName(INVENTORY_NOTECARD, ix);
if (llSubStringIndex(item, ".SEQUENCES") >= 0) {
ConfigCards += (list) item;
keys += (string)llGetInventoryKey(item);
}
}
return keys;
}
integer next_card()
{
if (ConfigCardIndex >= llGetListLength(ConfigCards)) {
ConfigCards = [];
return (FALSE);
}
ConfigLineIndex = 0;
ConfigCardName = llList2String(ConfigCards, ConfigCardIndex);
ConfigCardIndex++;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex);
llOwnerSay("Reading " + ConfigCardName);
return (TRUE);
}
default {
state_entry() {
ConfigCardKeys = get_cards();
ConfigCardIndex = 0;
ConfigCards = llListSort(ConfigCards, 1, TRUE);
if (! next_card()) {
state on;
}
}
dataserver(key query_id, string data) {
if (query_id != ConfigQueryId) {
return;
}
if (data == EOF) {
if (next_card()) {
return;
}
state on;
}
parse_config_line(llStringTrim(data, STRING_TRIM));
++ConfigLineIndex;
ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex); //read next line of positions notecard
}
state_exit() {
config_done();
announce();
}
}
state re_on
{
state_entry() {
state on;
}
}
state on {
state_entry() {
Avnames = [];
integer ix;
for (ix = 0; ix < MAX_AVS; ++ix) {
Avnames += (list)"";
}
}
on_rez(integer arg) {
state re_on;
}
link_message(integer from, integer num, string str, key dkey) {
if (str == "PRIMTOUCH") {
return;
}
if (num == 0 && str == "POSEB") {
if ((string)dkey != CurPose) {
seq_stop();
}
return;
}
if (num == 1 && str == "STOP") {
seq_stop();
return;
}
if (num == -11000) {
// av hopped on
list parms = llParseStringKeepNulls(str, ["|"], []);
integer ballnum = (integer)llList2String(parms, 0);
// string anim = llList2String(parms, 1); // anim name parameter, if desired
debug(4, llKey2Name(dkey) + ": on ball " + (string)ballnum);
addAv(llKey2Name(dkey), ballnum);
return;
} else if (num == -11001) {
// av hopped off
debug(4, llKey2Name(dkey) + ": off ball " + str);
removeAv((integer)str);
return;
} else if (num != -12001) {
return;
}
list ldata = llParseString2List(str, [" "], []);
string cmd = llList2String(ldata, 0);
if (cmd == "SEQUENCE") {
seq_start(llList2String(ldata, 1));
} else if (cmd == "PAUSE") {
debug(1, "pausing");
llSetTimerEvent(0.);
} else if (cmd == "RESUME") {
debug(1, "resuming");
llSetTimerEvent(.1);
}
}
timer() {
seq_execute();
}
changed(integer change) {
if (change & CHANGED_INVENTORY) {
if (get_cards() != ConfigCardKeys) {
llResetScript();
}
}
}
}

39
TGLM/~timeout.lsl Normal file
View File

@@ -0,0 +1,39 @@
float Timeout = 3600.;
key Owner;
default
{
state_entry() {
Owner = llGetOwner();
}
link_message(integer sender, integer num, string str, key id) {
if (str == "PRIMTOUCH") {
return;
}
if (num == 0 && str == "POSEB") {
llSetTimerEvent(Timeout);
return;
}
if (num == 1 && str == "STOP") {
llSetTimerEvent(0.);
return;
}
}
timer() {
llMessageLinked(LINK_THIS, -12002, "STOP", (key)"");
llSetTimerEvent(0.);
}
changed(integer change) {
if ((change & CHANGED_OWNER) && llGetOwner() != Owner) {
Owner = llGetOwner();
llSetScriptState(llGetScriptName(), FALSE);
}
}
}

380
WETV/WETV v1.3HT.lsl Normal file
View File

@@ -0,0 +1,380 @@
// Wholearth Television Control Engine v1.0
// Created by Tech Guy 2015
// Configuration
// Constants
string MediaURL = "http://api.orbitsystems.ca/wetv.html";
string ScreenFaceKey = "03d8e823-c9b6-49f1-bc72-a9b3e4cf83c5";
integer ScreenLinkID = 11;
integer ScreenFace = 5;
integer MenuButtonID = 13;
integer FramePrimID = 12;
list TVParts = [];
integer WETVMenuChannel = -4201;
float MenuTimeOut = 30.0;
string HelpCardName = "Wholearth TV Manual";
// Variables
integer ISON = FALSE; // State of Television (ie: Is Media Prim ON);
integer WETVMenuHandle; // Hold Handle for Main Menu
string MFLAG = ""; // Holds Name of Parent Menu
key ActiveUser = NULL_KEY;
integer SameGroup; // Hold Boolean Value Representing wether user has same group as object
string AuthCard = ".whitelist"; // Contains Name of NC containing authorized people to use the tv
list AuthedUsers = []; // List Containing Authorized Users as read from Config File.
key notecardQueryId;
integer TVShown = FALSE;
// script-wise, the first notecard line is line 0, the second line is line 1, etc.
integer notecardLine;
//Menu
list MainMenu = ["Power", "Help", "Exit Menu"]; // All Users Menu
list AdminMenuOption = ["Admin"]; // Admin Menu Option
list AdminMenu = ["List Users", "Add User", "Del User", "Admin Access", "TV Access", "Reset TV", "Main Menu", "Exit Menu"]; // Admin Menu
list PermissionTypesTV = ["Owner", "Anyone", "Group", "Main Menu", "Exit Menu"];
list PermissionTypesAdmin = ["Owner", "List", "Anyone", "Group", "Main Menu", "Exit Menu"];
// Menu Security Switches
string AdminMenuAccessMode = "Owner"; // Who do we include the Admin Menu on the Main menu for? (Anyone/Owner/List)
string TVMenuAccessMode = "Owner"; // Who is allowed to access the TV Menu
// Switches
integer AutoPlay = TRUE; // Should we Auto Play the Media on the Face
// Functions
SetMediaFace(integer FaceState){
if(FaceState){
llSetLinkTexture(ScreenLinkID, ScreenFaceKey, ScreenFace);
integer TVAccessMode;
if(TVMenuAccessMode=="Owner"){ TVAccessMode = PRIM_MEDIA_PERM_OWNER; }
if(TVMenuAccessMode=="Group"){ TVAccessMode = PRIM_MEDIA_PERM_GROUP; }
if(TVMenuAccessMode=="Anyone"){ TVAccessMode = PRIM_MEDIA_PERM_ANYONE; }
llSetLinkMedia(ScreenLinkID, ScreenFace, [
PRIM_MEDIA_ALT_IMAGE_ENABLE, TRUE,
PRIM_MEDIA_CONTROLS, PRIM_MEDIA_CONTROLS_MINI,
PRIM_MEDIA_HOME_URL, MediaURL,
PRIM_MEDIA_CURRENT_URL, MediaURL,
PRIM_MEDIA_AUTO_PLAY, AutoPlay,
PRIM_MEDIA_AUTO_ZOOM, TRUE,
PRIM_MEDIA_PERMS_INTERACT, TVAccessMode,
PRIM_MEDIA_PERMS_CONTROL, TVAccessMode
]);
}else if(!FaceState){
llClearLinkMedia(ScreenLinkID, ScreenFace);
llSetLinkTexture(ScreenLinkID, ScreenFaceKey, ScreenFace);
}
}
ToggleMediaFace(){
if(!ISON){
SetMediaFace(TRUE);
SendMessage("User", "Powering On...");
ISON = TRUE;
}else{
SetMediaFace(FALSE);
SendMessage("User", "Powering Off...");
ISON = FALSE;
}
}
Initialize(){
llSay(0, "Initializing...");
TVParts = [ ScreenLinkID, FramePrimID, MenuButtonID ];
WETVMenuChannel = (integer)llFrand(DEBUG_CHANNEL)*-1; // Set Random MenuComChannel
if(ISON){ // Check and Set Default Media Prim Face Parameters
SetMediaFace(TRUE);
}else{
SetMediaFace(FALSE);
}
llListenRemove(WETVMenuHandle);
llSleep(0.1);
WETVMenuHandle = llListen(WETVMenuChannel, "", "", "");
llSay(0, "TV Ready! Touch Power Button for Menu.");
}
ProcessWhiteList(string inputSTR){
if(inputSTR=="get"){
if (llGetInventoryKey(AuthCard) == NULL_KEY)
{
llSay(0, "Notecard '" + AuthCard + "' missing or unwritten");
state broken;
}
llSay(0, "Reading Authorized Users from '" + AuthCard + "'.");
notecardQueryId = llGetNotecardLine(AuthCard, notecardLine);
}else{
integer spaceIndex = llSubStringIndex(inputSTR, " ");
string firstName = llGetSubString(inputSTR, 0, spaceIndex - 1);
string lastName = llGetSubString(inputSTR, spaceIndex + 1, -1);
string AuthedID = osAvatarName2Key(firstName, lastName);
if(AuthedID!=""){
AuthedUsers = AuthedUsers + [AuthedID];
}else{
llSay(0, "Invalid Username in WhiteList NoteCard.");
}
}
}
ShowMenu(string MenuToShow){
list CurMenu = [];
string DialogMsg = "";
// Check if Touching User Has TV Access
if(TVMenuAccessMode=="Owner" && ActiveUser!=llGetOwner()){ // If TVMenuAccess Mode is Owner Only and It is not the Owner touching
SendMessage("User","You do not have access to the Main Menu. Please contact Owner.");
ResetMenu(FALSE);
return;
}else if(TVMenuAccessMode=="List" && llListFindList(AuthedUsers, [ActiveUser])==-1){ // If TVMenuAccess Mode is List and Touching User is not in the List
if(ActiveUser != llGetOwner()){
SendMessage("User","You do not have access to the Main Menu. Please contact Owner.");
ResetMenu(FALSE);
return;
}
}else if(TVMenuAccessMode=="Group" && !SameGroup){
SendMessage("User","You do not have access to the Main Menu. Please activate your group tag or contact Owner.");
ResetMenu(FALSE);
return;
}
if(MenuToShow=="Main"){
// Check if Touching User has Admin Menu Access
if(AdminMenuAccessMode=="Owner" && ActiveUser==llGetOwner()){ // Admin Access Mode is Owner and Owner is Clicking Menu Button (Include Admin Menu)
DialogMsg = "Main Menu (Admin Access)";
CurMenu = AdminMenuOption + MainMenu;
}else if(AdminMenuAccessMode=="List" && llListFindList(AuthedUsers, [ActiveUser])!=-1){ // Admin Access Mode is List and Active User is found in Authed List (Include Admin Menu)
DialogMsg = "Main Menu (Admin Access)";
CurMenu = AdminMenuOption + MainMenu;
}else if(AdminMenuAccessMode=="Anyone"){ // Admin Access Mode is Anyone (Include Admin Menu)
DialogMsg = "Main Menu (Admin Access)";
CurMenu = AdminMenuOption + MainMenu;
}else if(AdminMenuAccessMode=="Group" && SameGroup){
DialogMsg = "Main Menu (Admin Access)";
CurMenu = AdminMenuOption + MainMenu;
}else{
DialogMsg = "Main Menu";
CurMenu = MainMenu;
}
}else if(MenuToShow=="Admin"){
DialogMsg = "Admin Menu";
CurMenu = AdminMenu;
}else if(MenuToShow=="AdminAccess"){
CurMenu = PermissionTypesAdmin;
}else if(MenuToShow=="TVAcess"){
CurMenu = PermissionTypesTV;
}
llDialog(ActiveUser, DialogMsg, CurMenu, WETVMenuChannel);
llSetTimerEvent(MenuTimeOut);
}
SendMessage(string Type, string Message){
if(Type=="Debug"){
}else if(Type=="User"){
llRegionSayTo(ActiveUser, 0, Message);
}
}
ResetMenu(integer ISTIMER){
if(ISTIMER){
SendMessage("User", "Menu Response TimeOut. Please Re-Open Menu...");
}else{
SendMessage("User", "Menu Closed.");
}
llSetTimerEvent(0);
ActiveUser = NULL_KEY;
MFLAG = "";
SameGroup = 0;
llListenRemove(WETVMenuHandle);
}
UserManager(string Action, string User){
if(Action=="List"){
integer i;
string OutputString = "Authorized Users List:\n";
for(i=0;i<llGetListLength(AuthedUsers);i++){
string Name = osKey2Name(llList2Key(AuthedUsers, i));
OutputString = OutputString + "User "+(string)i+": "+Name+"\n";
}
SendMessage("User", OutputString);
}else if(Action=="Add"){
integer spaceIndex = llSubStringIndex(User, " ");
string firstName = llGetSubString(User, 0, spaceIndex - 1);
string lastName = llGetSubString(User, spaceIndex + 1, -1);
string AuthedID = osAvatarName2Key(firstName, lastName);
if(AuthedID!=""){
AuthedUsers = AuthedUsers + [AuthedID];
SendMessage("User", "User "+firstName+" "+lastName+" Added to List!");
UserManager("List", "");
ResetMenu(FALSE);
}else{
SendMessage("User", "Invalid Legacy Username Supplied!");
ResetMenu(FALSE);
}
}else if(Action=="Del"){
integer spaceIndex = llSubStringIndex(User, " ");
string firstName = llGetSubString(User, 0, spaceIndex - 1);
string lastName = llGetSubString(User, spaceIndex + 1, -1);
string AuthedID = osAvatarName2Key(firstName, lastName);
if(AuthedID!=""){
integer KeyIndex = llListFindList(AuthedUsers, [AuthedID]);
AuthedUsers = llDeleteSubList(AuthedUsers, KeyIndex, KeyIndex);
SendMessage("User", "User "+firstName+" "+lastName+" Removed from List!");
UserManager("List", "");
ResetMenu(FALSE);
}else{
SendMessage("User", "Invalid Legacy Username Supplied!");
ResetMenu(FALSE);
}
}
}
// Toggle Displaying the TV from Behind the HotTub
ToggleShowTV(integer Mode){
vector LocPos = ZERO_VECTOR;
integer i;
for(i=0;i<llGetListLength(TVParts);i++){
list Properties = llGetLinkPrimitiveParams(llList2Integer(TVParts, i), [
PRIM_POS_LOCAL
]);
//llOwnerSay(llDumpList2String(Properties, "||"));
LocPos = llList2Vector(Properties, 0);
if(Mode){
LocPos = LocPos + <1.85,0,0>;
}else{
LocPos = LocPos + <-1.85,0,0>;
}
llSetLinkPrimitiveParamsFast(llList2Integer(TVParts, i), [
PRIM_POS_LOCAL, LocPos
]);
}
TVShown = Mode;
}
// Main Program Code
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
ProcessWhiteList("get");
integer WETVMenuChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
}
touch_start(integer num){
ActiveUser = llDetectedKey(0);
integer WhatTouched = llDetectedLinkNumber(0);
SameGroup = llDetectedGroup(0);
//llOwnerSay((string)WhatTouched);
if(WhatTouched==MenuButtonID){
WETVMenuHandle = llListen(WETVMenuChannel, "", "", "");
ShowMenu("Main");
}else if(WhatTouched==FramePrimID){
ToggleShowTV(!TVShown);
}
}
listen(integer InChannel, string Name, key UserID, string Message){
if(Message=="Exit Menu"){ // Exit Menu (Catch regardless of Parent Menu)
ResetMenu(FALSE);
}else if(Message=="Main Menu"){
MFLAG = "";
llSetTimerEvent(0);
ShowMenu("Main");
}
if(MFLAG==""){ // We have a return from the Main Menu
if(Message=="Power"){ // Toggle TV Power
ToggleMediaFace();
llSetTimerEvent(0);
}else if(Message=="Admin"){ // Enter Admin Menu
MFLAG = "Admin";
ShowMenu("Admin");
}else if(Message=="Help"){ // Give TV Manual If there is One
integer i;
for(i=0;i<llGetInventoryNumber(INVENTORY_NOTECARD);i++){
//llOwnerSay("TEST");
if(llGetInventoryName(INVENTORY_NOTECARD, i)==HelpCardName){
SendMessage("User", "Please take TV Manual...");
llGiveInventory(ActiveUser, llGetInventoryName(INVENTORY_NOTECARD, i));
ResetMenu(FALSE);
}
}
}
}else if(MFLAG=="Admin"){ // Admin Menu was Shown as we are processing button response
if(Message=="List Users"){ // List Authorized Users
UserManager("List", "");
ResetMenu(FALSE);
}else if(Message=="Add User"){ // Add User to Authorized User List (Prompt User with TextBox)
MFLAG = "AddUser";
llTextBox(ActiveUser, "Add User\nPlease Enter Legacy Name:", WETVMenuChannel);
}else if(Message=="Del User"){
MFLAG = "DelUser";
UserManager("List", "");
llTextBox(ActiveUser, "Del User\nPlease Enter Legacy Name:", WETVMenuChannel);
}else if(Message=="TV Access"){
MFLAG = "TVAcess";
ShowMenu(MFLAG);
}else if(Message=="Admin Access"){
MFLAG = "AdminAccess";
ShowMenu(MFLAG);
}else if(Message=="Reset TV"){
SendMessage("User", "Resetting TV...");
llResetScript();
}
}else if(MFLAG=="AddUser"){ // We received a response from TextBox about Who to Add to Authorized Users List
UserManager("Add", Message);
}else if(MFLAG=="DelUser"){
UserManager("Del", Message);
}else if(MFLAG=="AdminAccess"){
AdminMenuAccessMode = Message;
SendMessage("User", "Admin Menu Access Mode: "+Message);
ResetMenu(FALSE);
}else if(MFLAG=="TVAcess"){
TVMenuAccessMode = Message;
SendMessage("User", "TV Menu Access Mode: "+Message);
ResetMenu(FALSE);
}
}
dataserver(key query_id, string data){
if (query_id == notecardQueryId){
if (data == EOF){
llOwnerSay("Done reading whitelist notecard, added " + (string) notecardLine + " authorized users.");
Initialize();
}else{
// bump line number for reporting purposes and in preparation for reading next line
ProcessWhiteList(data);
++notecardLine;
llOwnerSay("Authorized User: " + (string) notecardLine + " " + data);
notecardQueryId = llGetNotecardLine(AuthCard, notecardLine);
}
}
}
timer(){
ResetMenu(TRUE);
}
changed(integer change){
if(change & CHANGED_INVENTORY){
llSay(0, "Rebooting...");
llResetScript();
}
}
}
state broken{
state_entry(){
llOwnerSay("TV Broken, Please correct for previously displayed error.");
}
changed(integer change){
if(change & CHANGED_INVENTORY){
llSay(0, "Rebooting...");
llResetScript();
}
}
}

12
XyText/XyText Changer.lsl Normal file
View File

@@ -0,0 +1,12 @@
default
{
on_rez(integer y)
{
llMessageLinked(LINK_SET, 281000, "", "''''");
}
state_entry()
{
llMessageLinked(LINK_SET, 281000, "", "''''");
}
}

311
XyText/XyText Main.lsl Normal file
View File

@@ -0,0 +1,311 @@
/////////////// CONSTANTS ///////////////////
// XyText Message Map.
integer DISPLAY_STRING = 281000;
integer DISPLAY_EXTENDED = 281001;
integer REMAP_INDICES = 281002;
integer RESET_INDICES = 281003;
integer SET_CELL_INFO = 281004;
// This is an extended character escape sequence.
string ESCAPE_SEQUENCE = "\\e";
// This is used to get an index for the extended character.
string EXTENDED_INDEX = "123456789abcdef";
// Face numbers.
integer LEFT_FACE = 4;
integer MIDDLE_FACE = 0;
integer RIGHT_FACE = 2;
// This is a list of textures for all 2-character combinations.
list CHARACTER_GRID = [
"e1adcf74-b678-46f5-ab85-a3b03d221e7e",
"0f72d0a2-928a-435a-90a6-0c6fc3f6bfe5",
"c45d9b9e-2c7c-4704-9f0f-06e3fda13732",
"150c4bfe-f38d-472f-b0c4-51f0f16080ad",
"62be6f91-e631-494f-a78c-9512ab0778e0",
"330428c9-eb69-4e27-8104-964930a8032f",
"3d4f54dd-4bc1-497f-9099-a4763f8ed4ab",
"2695c77f-207c-49d6-89fa-8ebbaaa1599a",
"6cb2ee7c-afec-4792-8c5f-07957ea0e520",
"1a255b88-bbdc-4a21-af32-6c126c7d50fd",
"86692870-a2de-411e-bc78-68938237e0ef",
"f7aa79e8-4e9b-4547-8076-b143f4f9d4bb",
"9b8d9e38-4a35-43f1-8301-d83734ed4d36",
"94855b9d-3f5b-4827-986e-8d10fdce0f1a",
"18a7cd1c-7676-4dfb-a28e-a6b25afa9446",
"4e44033f-e631-4836-93c8-cd6d5b0c86cd",
"7c1d0854-6bc7-4e1e-b612-6fb0c573224a",
"0c7a5f72-6635-4edd-9004-6293b00d19d5",
"e68c90d3-1ba9-4bc1-84e6-d7a807ac1b5f",
"a094d717-3e81-42d4-be30-6ef612cf21ba",
"6d496c5b-d69b-4f30-b896-7e0fc11ba09b",
"fcefb20d-b260-434c-8b66-2ae57ba84682",
"e95cb97d-d73d-4baf-a5d7-27dc906a95cd",
"1cba70f9-7e2b-4dcf-aeea-89f2157488f6",
"4ee7726b-410a-406c-bbda-1bc8464ff884",
"5c47176e-7d66-4e43-bf58-d513b6ad5859",
"f2a7efea-63c9-4738-b51a-501d41feac08",
"3b6fa4d0-35b4-4be5-96eb-6a08eb712b2c",
"ed1472b4-00c5-420d-81d6-bf417ade3ac9",
"250671b1-afd1-4b37-9abb-ac6eb8d38929",
"061974d5-2cc4-4974-8297-6a296087059b",
"6d9522dc-11dc-49aa-994a-d1d2e3eb9117",
"d7adc248-6c78-4faf-bcd4-628f42223ef1",
"d728fdc7-648b-47c8-9121-b094d5d4429a",
"a9fa907c-70f3-4a15-b57c-f55b907861c6",
"875b9c0e-ccf6-4bf6-87bb-05d916441dd5",
"357a341d-afed-4584-b5bd-45a931c1bae7",
"20c0394e-2930-4cf1-9fda-20d7d5cbb9c1",
"bf7ec147-6460-46bf-af4d-ea890eac583d",
"eee00eff-a5e5-4338-bda9-ffbf5658752a",
"a18b6a59-34f8-428f-bcb4-678416b6c378",
"f5833f71-25b0-4be5-a9c8-7550faca1b30",
"890456ad-103a-495a-9ec7-cdd9da71028f",
"721563ff-7019-4445-a183-6dc08f6e363a",
"aa67b329-cd4e-4c04-8bec-9e477dab2f56",
"3ab607b1-c2b7-4e08-83cf-3bb6204d8de9",
"da071c8e-e187-4c73-9647-352a4b772c40",
"45bf87a8-8102-41ec-a7d5-0ad5150dd764",
"aab84719-d8b3-4f89-bd2c-0fce1d049d25",
"24cf75a8-768d-4b9c-8588-9acfbeeb85c9",
"bd7b187f-83d7-4e30-a126-69ef13ebd5a7",
"e0951d46-30f7-4bc6-a66f-6a9bb492bdb4",
"d4e44008-ba97-49cc-9ad7-2c71d834493b",
"6437b969-5807-49b2-b6ef-cbcfefd44864",
"df3b5a0b-65d4-42a9-a408-92e770ad2e7a",
"a35b4b7e-dbc4-4cc1-bb0c-73331f268a9b",
"1fb8ca6c-eb6e-46fc-a294-283d6ed3c102",
"b0afff79-48fd-4b6d-8a73-1a628dc07556",
"8377fc50-c138-428b-910d-69f5373ba935",
"d7a1085f-b181-468b-9804-ab0ac127dcb6",
"43736d8b-8ebb-48c8-aca8-5c2dc13a38b0",
"1b5588c9-87a5-4a13-9270-e38e8c7a3117",
"7465a761-4aa2-4654-b4f9-577cb211bfc2",
"6eac5302-40dc-40bf-9ad6-8bda00e34814",
"410c41fc-eece-43ef-8efb-cf069a06fd25",
"28bb8a52-3062-435d-81dd-052b8cdb88f9"
];
///////////// END CONSTANTS ////////////////
///////////// GLOBAL VARIABLES ///////////////
// All displayable characters. Default to ASCII order.
string gCharIndex;
// This is the channel to listen on while acting
// as a cell in a larger display.
integer gCellChannel = -1;
// This is the starting character position in the cell channel message
// to render.
integer gCellCharPosition = 0;
/////////// END GLOBAL VARIABLES ////////////
ResetCharIndex() {
gCharIndex = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`";
// \" <-- Fixes LSL syntax highlighting bug.
gCharIndex += "abcdefghijklmnopqrstuvwxyz{|}~";
gCharIndex += "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
}
vector GetGridPos(integer index1, integer index2) {
// There are two ways to use the lookup table...
integer Col;
integer Row;
if (index1 >= index2) {
// In this case, the row is the index of the first character:
Row = index1;
// And the col is the index of the second character (x2)
Col = index2 * 2;
}
else { // Index1 < Index2
// In this case, the row is the index of the second character:
Row = index2;
// And the col is the index of the first character, x2, offset by 1.
Col = index1 * 2 + 1;
}
return < Col, Row, 0>;
}
string GetGridTexture(vector grid_pos) {
// Calculate the texture in the grid to use.
integer GridCol = llRound(grid_pos.x) / 20;
integer GridRow = llRound(grid_pos.y) / 10;
// Lookup the texture.
key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol);
return Texture;
}
vector GetGridOffset(vector grid_pos) {
// Zoom in on the texture showing our character pair.
integer Col = llRound(grid_pos.x) % 20;
integer Row = llRound(grid_pos.y) % 10;
// Return the offset in the texture.
return <-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0>;
}
ShowChars(vector grid_pos1, vector grid_pos2, vector grid_pos3) {
// Set the primitive textures directly.
llSetPrimitiveParams( [
PRIM_TEXTURE, LEFT_FACE, GetGridTexture(grid_pos1), <0.1, 0.1, 0>, GetGridOffset(grid_pos1), PI_BY_TWO,
PRIM_TEXTURE, MIDDLE_FACE, GetGridTexture(grid_pos2), <0.1, 0.1, 0>, GetGridOffset(grid_pos2), 0.0,
PRIM_TEXTURE, RIGHT_FACE, GetGridTexture(grid_pos3), <0.1, 0.1, 0>, GetGridOffset(grid_pos3), -PI_BY_TWO
]);
}
RenderString(string str) {
// Get the grid positions for each pair of characters.
vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) );
vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)),
llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) );
vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)),
llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) );
// Use these grid positions to display the correct textures/offsets.
ShowChars(GridPos1, GridPos2, GridPos3);
}
RenderExtended(string str) {
// Look for escape sequences.
list Parsed = llParseString2List(str, [], [ESCAPE_SEQUENCE]);
integer ParsedLen = llGetListLength(Parsed);
// Create a list of index values to work with.
list Indices;
// We start with room for 6 indices.
integer IndicesLeft = 6;
integer i;
string Token;
integer Clipped;
integer LastWasEscapeSequence = FALSE;
// Work from left to right.
for (i = 0; i < ParsedLen && IndicesLeft > 0; i++) {
Token = llList2String(Parsed, i);
// If this is an escape sequence, just set the flag and move on.
if (Token == ESCAPE_SEQUENCE) {
LastWasEscapeSequence = TRUE;
}
else { // Token != ESCAPE_SEQUENCE
// Otherwise this is a normal token. Check its length.
Clipped = FALSE;
integer TokenLength = llStringLength(Token);
// Clip if necessary.
if (TokenLength > IndicesLeft) {
Token = llGetSubString(Token, 0, IndicesLeft - 1);
TokenLength = llStringLength(Token);
IndicesLeft = 0;
Clipped = TRUE;
}
else
IndicesLeft -= TokenLength;
// Was the previous token an escape sequence?
if (LastWasEscapeSequence) {
// Yes, the first character is an escape character, the rest are normal.
// This is the extended character.
Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];
// These are the normal characters.
integer j;
for (j = 1; j < TokenLength; j++)
Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
}
else { // Normal string.
// Just add the characters normally.
integer j;
for (j = 0; j < TokenLength; j++)
Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
}
// Unset this flag, since this was not an escape sequence.
LastWasEscapeSequence = FALSE;
}
}
// Use the indices to create grid positions.
vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );
vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );
vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );
// Use these grid positions to display the correct textures/offsets.
ShowChars(GridPos1, GridPos2, GridPos3);
}
integer ConvertIndex(integer index) {
// This converts from an ASCII based index to our indexing scheme.
if (index >= 32) // ' ' or higher
index -= 32;
else { // index < 32
// Quick bounds check.
if (index > 15)
index = 15;
index += 94; // extended characters
}
return index;
}
default {
state_entry() {
// Initialize the character index.
ResetCharIndex();
//llSay(0, "Free Memory: " + (string) llGetFreeMemory());
}
link_message(integer sender, integer channel, string data, key id) {
if (channel == DISPLAY_STRING) {
RenderString(data);
return;
}
if (channel == DISPLAY_EXTENDED) {
RenderExtended(data);
return;
}
if (channel == gCellChannel) {
// Extract the characters we are interested in, and use those to render.
RenderString( llGetSubString(data, gCellCharPosition, gCellCharPosition + 5) );
return;
}
if (channel == REMAP_INDICES) {
// Parse the message, splitting it up into index values.
list Parsed = llCSV2List(data);
integer i;
// Go through the list and swap each pair of indices.
for (i = 0; i < llGetListLength(Parsed); i += 2) {
integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );
integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );
// Swap these index values.
string Value1 = llGetSubString(gCharIndex, Index1, Index1);
string Value2 = llGetSubString(gCharIndex, Index2, Index2);
gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);
gCharIndex = llInsertString(gCharIndex, Index1, Value2);
gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);
gCharIndex = llInsertString(gCharIndex, Index2, Value1);
}
return;
}
if (channel == RESET_INDICES) {
// Restore the character index back to default settings.
ResetCharIndex();
return;
}
if (channel == SET_CELL_INFO) {
// Change the channel we listen to for cell commands, and the
// starting character position to extract from.
list Parsed = llCSV2List(data);
gCellChannel = (integer) llList2String(Parsed, 0);;
gCellCharPosition = (integer) llList2String(Parsed, 1);
return;
}
}
}

View File

@@ -0,0 +1,131 @@
// Avatar Scanner Engine v1.0
// Created by Tech Guy (Zachary Williams) 2015
/*
* This Script Listens for Calls from any JackPot Servers, who provide a list of Avatar Ids to check for
* and return a list on the same channel, but speaking only to the primitive from which the call came.
*
* Call Format is SecurityKey||CMD||LISTITEM||LISTITEM
*/
// Configuration
// Constants
integer ComChannel = -19000;
integer DBComChannel = -270000;
string EMPTY = "";
string SecurityKey = "UseYourOwnKey";
key GameEventDBServer = "b007f16b-5658-4595-91d1-17dcaa75ed28";
string HoverTextString = "Avatar Scanner";
// Incoming Field Ids
integer SECKEY = 0;
integer CMD = 1;
// Variables
list FoundUsers = [];
string CallingServer = "";
integer GListLength;
integer SFired;
// Switches
integer DebugMode = TRUE;
// Handles
integer ComHandle;
// Custom Functions
Initialize(){
llListenRemove(ComHandle);
llSleep(0.1);
ComHandle = llListen(ComChannel, EMPTY, EMPTY, EMPTY);
llOwnerSay("Scanner Online!");
}
// Check key if any incoming request and validate against Security Key
integer SecurityCheck(key CheckID){
if(CheckID!=SecurityKey){
return FALSE;
}else{
return TRUE;
}
}
integer ScanForUser(string userid){
if(DebugMode){
llOwnerSay("Scanner Received UserID String: "+userid);
}
if(userid!=""){
llSensor("", (key)userid, AGENT, 64.0, PI);
}
return FALSE;
}
// Main Program
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
// Bring Scanner Online
Initialize();
}
sensor (integer num_detected)
{
SFired++;
//if(llListFindList(FoundUsers, [llDetectedKey(0)])==-1){
FoundUsers = FoundUsers + (string)llDetectedKey(0);
if(DebugMode){
llOwnerSay("Found User: "+llDetectedKey(0));
}
//}
if(SFired==GListLength-1){
string ResponseString = SecurityKey+"||ACTIVEUSERS||"+llDumpList2String(FoundUsers, "||");
if(DebugMode){
llOwnerSay("Calling Server ID: "+CallingServer+"\rChannel: "+(string)ComChannel+"\rResponse Sent!\r"+ResponseString);
}
llRegionSayTo(CallingServer, ComChannel, ResponseString);
llResetScript();
}
}
no_sensor()
{
SFired++;
}
listen(integer chan, string cmd, key id, string data){
FoundUsers = [];
if(DebugMode){
llOwnerSay("Listen Event Fired:\nCommand: "+cmd+"\n"+"Data: "+data);
}
if(SecurityCheck(llList2Key(llParseString2List(data, "||", []), 0))==FALSE){ // If Device did not Send Security Key
if(DebugMode){
llOwnerSay("Un-Authorized Accept Attempt of "+HoverTextString+"!\rEvent Logged!");
}
list SendList = [] + [SecurityKey] + ["INSERT"] + ["Un-Authd Access to User DB"] + ["Un-Authorized Access attempt made to "+HoverTextString+"."] + [data];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
return;
}
if(chan==ComChannel ){
cmd = llList2String(llParseStringKeepNulls(data, ["||"], []), CMD);
if(DebugMode){
llOwnerSay("CMD: "+cmd);
}
if(cmd=="SCANFOR"){
list UserIDS = llList2List(llParseStringKeepNulls(data, ["||"], []), 2, -1);
integer i;
CallingServer = id;
if(DebugMode){
llOwnerSay("UserIDS: "+llDumpList2String(UserIDS, "||"));
}
for(i=0;i<llGetListLength(UserIDS);i++){
if(llList2String(UserIDS, i)!="UPPOT"){
GListLength = llGetListLength(UserIDS);
ScanForUser(llList2String(UserIDS, i));
}else{ // If Input is equal to UPPOT
}
}
}
}
}
}

View File

@@ -0,0 +1,604 @@
//Very Keynes - 2008 - 2009
//
// Version: OpenSimulator Server 0.6.1.7935 (interface version 2)
//
// 2009-01-06, 19:30 GMT
//
//------------------Begin VK-DBMS-VM----------------------------\\
//--------------------Introduction------------------------------\\
//
// Very Keynes - DBMS - Virtual Machine
//
// Implements a core set of registers and root functions
// to create and manage multi-table database structures as
// an LSL list. Although intended to under pin higher level
// database management tools such as VK-SQL it is usable as
// a small footprint database facility for system level
// applications.
//
//
// Naming Conventions and Code Style
//
// This Code is intended to be included as a header to user generated
// code. As such it's naming convention was selected so that it would
// minimise the possibility of duplicate names in the user code portion
// of the application. Exposed Functions and Variables are prefixed db.
//
// A full User Guide and Tutorial is availible at this URL:
//
// http://docs.google.com/Doc?id=d79kx35_26df2pbbd8
//
//
// Table Control Registers
//
integer th_; // Table Handle / Index Pointer
integer tc_; // Columns in Active Table
integer tr_; // Rows in Active Table
integer ts_; // Active Table Start Address
//
list _d_ = []; // Database File
list _i_ = [0]; // Index File
//
// Exposed Variables
//
integer dbIndex; // Active Row Table Pointer
list dbRow; // User Scratch List
string dbError; // System Error String
//
// Temporary / Working Variables
//
integer t_i;
string t_s;
float t_f;
list t_l;
//
// System Functions
//
string dbCreate(string tab, list col)
{
if(dbOpen(tab))
{
dbError = tab + " already exists";
return "";
}
tc_ = llGetListLength(col);
_i_ += [tab, tc_, 0, 0, 0];
th_= 0;
dbOpen(tab);
dbInsert(col);
return tab;
}
integer dbCol(string col)
{
return llListFindList(dbGet(0), [_trm(col)]);
}
integer dbDelete(integer ptr)
{
if(ptr > 0 && ptr < tr_)
{
t_i = ts_ + tc_ * ptr;
_d_ = llDeleteSubList(_d_, t_i, t_i + tc_ - 1);
--tr_;
return tr_ - 1;
}
else
{
dbError = (string)ptr + " is outside the Table Bounds";
return FALSE;
}
}
integer dbDrop(string tab)
{
t_i = llListFindList(_i_, [tab]);
if(-1 != t_i)
{
dbOpen(tab);
_d_ = llDeleteSubList(_d_, ts_, ts_ + tc_ * tr_ - 1);
_i_ = llDeleteSubList(_i_, th_, th_ + 4);
th_= 0;
return TRUE;
}
else
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
}
integer dbExists(list cnd)
{
for(dbIndex = tr_ - 1 ; dbIndex > 0 ; --dbIndex)
{
if(dbTest(cnd)) return dbIndex;
}
return FALSE;
}
list dbGet(integer ptr)
{
if(ptr < tr_ && ptr >= 0)
{
t_i = ts_ + tc_ * ptr;
return llList2List(_d_, t_i, t_i + tc_ - 1);
}
else
{
dbError = (string) ptr + " is outside the Table Bounds";
return [];
}
}
integer _idx(integer hdl)
{
return (integer)llListStatistics(6, llList2ListStrided(_i_, 0, hdl, 5));
}
integer dbInsert(list val)
{
if(llGetListLength(val) == tc_)
{
dbIndex = tr_++;
_d_ = llListInsertList(_d_, val, ts_ + tc_ * dbIndex);
return dbIndex;
}
else
{
dbError = "Insert Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbOpen(string tab)
{
if(th_)
{
_i_ = llListReplaceList(_i_, [tr_, dbIndex, tc_ * tr_], th_ + 2, th_ + 4);
}
t_i = llListFindList(_i_, [tab]);
if(-1 == t_i) //if tab does not exist abort
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
else if(th_ != t_i)
{
th_ = t_i++;
ts_ = _idx(th_);
tc_ = llList2Integer(_i_, t_i++);
tr_ = llList2Integer(_i_, t_i++);
dbIndex = llList2Integer(_i_, t_i);
}
return tr_ - 1;
}
integer dbPut(list val)
{
if(llGetListLength(val) == tc_)
{
t_i = ts_ + tc_ * dbIndex;
_d_ = llListReplaceList(_d_, val, t_i, t_i + tc_ - 1);
return dbIndex;
}
else
{
dbError = "Update Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbTest(list cnd)
{
if(llGetListEntryType(cnd,2) >= 3)
{
t_s = llList2String(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
if ("==" == llList2String(cnd, 1)){t_i = t_s == _trm(llList2String(cnd, 2));}
else if("!=" == llList2String(cnd, 1)){t_i = t_s != _trm(llList2String(cnd, 2));}
else if("~=" == llList2String(cnd, 1))
{t_i = !(llSubStringIndex(llToLower(t_s), llToLower(_trm(llList2String(cnd, 2)))));}
}
else
{
t_f = llList2Float(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
t_s = llList2String(cnd, 1);
if ("==" == t_s){t_i = t_f == llList2Float(cnd, 2);}
else if("!=" == t_s){t_i = t_f != llList2Float(cnd, 2);}
else if("<=" == t_s){t_i = t_f <= llList2Float(cnd, 2);}
else if(">=" == t_s){t_i = t_f >= llList2Float(cnd, 2);}
else if("<" == t_s){t_i = t_f < llList2Float(cnd, 2);}
else if(">" == t_s){t_i = t_f > llList2Float(cnd, 2);}
}
if(t_i) return dbIndex;
else return FALSE;
}
string _trm(string val)
{
return llStringTrim(val, STRING_TRIM);
}
dbTruncate(string tab)
{
dbIndex = dbOpen(tab);
while(dbIndex > 0) dbDelete(dbIndex--);
}
dbSort(integer dir)
{
t_i = ts_ + tc_;
_d_ = llListReplaceList(_d_, llListSort(llList2List(_d_, t_i, t_i + tc_ * tr_ - 2), tc_, dir), t_i, t_i + tc_ * tr_ - 2);
}
float dbFn(string fn, string col)
{
t_i = ts_ + tc_;
t_l = llList2List(_d_, t_i, t_i + tc_ * tr_ - 2);
if(dbCol(col) != 0) t_l = llDeleteSubList(t_l, 0, dbCol(col) - 1);
return llListStatistics(llSubStringIndex("ramimaavmedesusqcoge", llGetSubString(llToLower(fn),0,1)) / 2,
llList2ListStrided(t_l, 0, -1, tc_));
}
//
//--------------------------- End VK-DBMS-VM ---------------------------\\
//
// Configuration
// Constants
integer DBComChannel = -260046;
string DBName = "HeavenAndHellEvents"; // Database for Heaven and Hell Player Info
string HoverTextString = "Heaven And Hell\n Event Database"; // Base String Name of Databse Engine
string EMPTY = "";
key SecurityKey = "UserYourOwnKey";
integer BasePotAmt = 100;
float LightHoldLength = 0.1;
float UploadTimer = 1800;
string ServerType = "EVENT"; // Defines to Remote Server what type of table to build. Send as header in register request. (USERDB, EVENT, JACKPOT, Main)
// Off-World Data Communication Constants
key HTTPRequestHandle; // Handle for HTTP Request
string URLBase = "http://orbitsystems.ca";
list HTTPRequestParams = [
HTTP_METHOD, "POST",
HTTP_MIMETYPE, "application/x-www-form-urlencoded",
HTTP_BODY_MAXLENGTH, 16384,
HTTP_CUSTOM_HEADER, "CUSKEY", "(Mq=h/c2)"
];
// Indicator Light Config
float GlowOn = 0.10;
float GlowOff = 0.0;
list ONColorVectors = [<0.0,1.0,0.0>,<1.0,0.5,0.0>,<1.0,0.0,0.0>];
list ColorNames = ["Green", "Orange", "Red"];
list OFFColorVectors = [<0.0,0.5,0.0>,<0.5,0.25,0.0>,<0.5,0.0,0.0>];
integer PWRLIGHT = 2;
integer ACTLIGHT = 3;
// Incoming Field Ids
integer UUID = 0;
integer NAME = 1;
integer EVENTTYPE = 2;
integer MESSAGE = 3;
integer DATA = 4;
// Switches
integer DebugMode = FALSE; // Should we say Debug Messages to Owner?
// Variables
integer DBComHandle; // Database Communication Handle
integer DBEntries = 0; // NUmber of Database Entries
integer TotalTouched = 0;
string HTTPFLAG = "";
// NoteCard Reader
key nrofnamesoncard;
integer nrofnames;
list names;
list keynameoncard;
string nameoncard;
string storedname;
// Menus
// Functions
Initialize(){
if(DebugMode){
llOwnerSay("Initializing "+DBName+"...");
}
nrofnamesoncard = llGetNumberOfNotecardLines("whitelist");
llListenRemove(DBComHandle);
llSleep(0.1);
DBComHandle = llListen(DBComChannel, EMPTY, EMPTY, EMPTY);
string CreatedDB = dbCreate(DBName, ["uuid", "theirip", "name", "eventtype", "message", "data"]);
if(CreatedDB==DBName && DebugMode){
llOwnerSay("Database "+DBName+" Created...");
}
LightToggle(PWRLIGHT, TRUE, "Red");
LightToggle(ACTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
llSetTimerEvent(UploadTimer);
RegisterServer("CheckReg");
// llOwnerSay(DBName+" Server Online!");
}
// Check key if any incoming request and validate against Security Key
integer SecurityCheck(key CheckID){
if(CheckID!=SecurityKey){
// Send Access Log Entry to Security Logging Server
return FALSE;
}else{
return TRUE;
}
}
DumpRecentEvents(string uuid){
integer i;
for(i=1;i<=DBEntries;i++){
list CurrentLine = dbGet(i);
llRegionSayTo(uuid, 0,
"Event ID: "+(string)i+"\n
UUID: "+llList2String(CurrentLine, 0)+"\n
Name: "+llList2String(CurrentLine, 2)+"\n
Event Type: "+llList2String(CurrentLine, 3)+"\n
Message: "+llList2String(CurrentLine, 4)+"\n
Data: "+llList2String(CurrentLine, 5)
);
}
}
ToggleDebug(){
DebugMode = !DebugMode;
if(DebugMode){
llOwnerSay("Debug Mode ON!");
}else{
llOwnerSay("Debug Mode OFF!");
}
}
LightToggle(integer LinkID, integer ISON, string Color){
if(ISON){
vector ColorVector = llList2Vector(ONColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOn,
PRIM_FULLBRIGHT, ALL_SIDES, TRUE
]);
}else{
vector ColorVector = llList2Vector(OFFColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOff,
PRIM_FULLBRIGHT, ALL_SIDES, FALSE
]);
}
}
string GetEventData(){
dbIndex = 1;
string ReturnString = "";
for(dbIndex=1;dbIndex<=DBEntries;dbIndex++){
list CurrentLine = dbGet(dbIndex);
if(llList2String(CurrentLine, 0)==""){ return ReturnString; }
string CompiledString = llList2String(CurrentLine, 0)+"||"+llList2String(CurrentLine, 1)+"||"+llList2String(CurrentLine, 2)+"||"+llList2String(CurrentLine, 3)+"||"+llList2String(CurrentLine, 4)+"||"+llList2String(CurrentLine, 5)+"||"+llList2String(CurrentLine, 6)+",";
ReturnString = ReturnString + CompiledString;
}
return ReturnString;
}
RegisterServer(string cmd){
if(cmd=="CheckReg"){
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("CheckReg")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", ServerType];
HTTPFLAG = "CheckReg";
HTTPRequestHandle = llHTTPRequest(URL, SendParams, ""); // Send Request to Server to Check and/or Register this Server
}
}
// Main Program
default
{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
touch(integer num){
LightToggle(ACTLIGHT, TRUE, "Green");
TotalTouched = TotalTouched + num;
if(TotalTouched>1){
return;
}
ToggleDebug();
key WhoTouched = llDetectedKey(0);
if(llListFindList(names, [osKey2Name(WhoTouched)])==-1){
llRegionSayTo(WhoTouched, 0, "Un-Authorized Access Attempted Logged!");
dbInsert([WhoTouched, "", osKey2Name(WhoTouched), "Un-Authed Touch!", "Somebody tried to touch the server who was not authorized", ""]);
return;
}
llRegionSayTo(WhoTouched, 0, "Dumping Events to Local Chat...");
DumpRecentEvents(WhoTouched);
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
}
touch_end(integer num){
TotalTouched = 0;
}
listen(integer chan, string cmd, key id, string data){
LightToggle(ACTLIGHT, TRUE, "Green");
list InputData = llParseStringKeepNulls(data, ["||"], []);
if(DebugMode){
llOwnerSay("Listen Event Fired:\nCommand: "+cmd+"\n"+"Data: "+data);
}
if(SecurityCheck(llList2Key(InputData, 0))==FALSE && data != ""){ // If Device did not Send Security Key
dbInsert(["THISOBJ", "", llGetObjectName(), "Invalid Security Key!", "External Caller '"+cmd+"' did not provide valid Security Key.", data]);
if(DebugMode){
llOwnerSay("Security Error writing to User Database!");
}
return;
}
if(chan==DBComChannel ){
cmd = llList2String(InputData, 1);
if(cmd=="INSERT"){
if(DebugMode){ // If Debug Mode is TRUE
llOwnerSay(cmd+" Command Received!");
integer i; // Integer for Counting
for(i=0;i<=llGetListLength(InputData)-1;i++){ // Loop Based on List Length (Adjusted for 0 Offset)
llOwnerSay("Processed Input Line: "+llList2String(InputData, i)+" "+osKey2Name(llList2Key(InputData, i))); // Print Each Value in the list
}
}
// Insert New Data
list InsertList = llList2List(InputData, 2, -1);
if(DebugMode){
llOwnerSay("Attempting to Insert New Event...");
}
integer Inserted = dbInsert([
llList2String(InsertList, 0),
"",
osKey2Name(llList2String(InsertList, 0)),
llList2String(InsertList, 1),
llList2String(InsertList, 2),
llList2String(InsertList, 3)
]);
if(Inserted && DebugMode){
llOwnerSay("Record Inserted!");
}else if(!Inserted && DebugMode){
llOwnerSay("Error Inserting New Event Record!");
}
DBEntries++;
}
}
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
}
// Read Security Notecard
dataserver (key queryid, string data){
if (queryid == nrofnamesoncard)
{
nrofnames = (integer) data;
integer i;
for (i=0;i < nrofnames;i++){
keynameoncard = keynameoncard + llGetNotecardLine("whitelist", i);
}
} else
{
integer listlength;
listlength = llGetListLength(keynameoncard);
integer j;
for(j=0;j<listlength;j++) {
if (queryid == (key) llList2String(keynameoncard,j))
{
if(data!=""){
if(DebugMode){
llOwnerSay("Authorized User: "+data);
}
names += data;
}else{
llOwnerSay("Security Turned Off.");
}
}
}
}
}
// Server Response Catcher for Dumps and Initial Reg
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id != HTTPRequestHandle) return;// exit if unknown
vector COLOR_BLUE = <0.0, 0.0, 1.0>;
float OPAQUE = 1.0;
llSetTimerEvent(UploadTimer);
list OutputData = llCSV2List(body); // Parse Response into List
string InputKey = llBase64ToString(llList2String(OutputData, 1));
string InputCMD = llBase64ToString(llList2String(OutputData, 0));
if(DebugMode){
llOwnerSay("Key: "+InputKey+"\nCMD: "+InputCMD);
}
if(InputKey!=SecurityKey){
llOwnerSay("Invalid Security Key Received from RL Server!\r"+InputKey);
}else if(HTTPFLAG=="CheckReg"){
HTTPFLAG = "";
if(InputCMD=="ALRDYREGOK"){ // Server Already Registered
if(DebugMode){
llOwnerSay("Server Already Registered!");
}
llOwnerSay(DBName+" Server Online!");
}else if(InputCMD=="REGOK"){ // Server Successfully Registered
if(DebugMode){
llOwnerSay("Server Successfully Registered!");
llOwnerSay(DBName+" Server Online!");
}
}else if(InputCMD=="REGERR"){ // Error Registering Server with Off-World Database
llOwnerSay("Error Registering Server with Database!");
}else if(InputCMD=="CHECKERR"){ // Error Checking Database for Server Registration
llOwnerSay("Error Checking Database for Server Registration");
}else{
llOwnerSay("Response from server not reconignized!");
}
}else if(HTTPFLAG=="EventDump"){
HTTPFLAG = "";
if(InputCMD=="DUMPEMPTY"){
if(DebugMode){
llOwnerSay("Server says Event Dump was EMPTY!");
}
llSetTimerEvent(UploadTimer);
}else if(InputCMD=="DUMPOK"){
if(DebugMode){
llOwnerSay("Server Dump OK!");
}
if(DebugMode){
llOwnerSay("Truncating Database...");
}
dbIndex = 1;
dbTruncate(DBName);
DBEntries = 1;
llSetTimerEvent(UploadTimer);
}
}
}
timer(){
llSetTimerEvent(UploadTimer);
LightToggle(ACTLIGHT, TRUE, "Green");
string DumpString = GetEventData();
string EncodedDumpString = llStringToBase64(DumpString);
string MessageBody = "data="+EncodedDumpString;
integer MessageBodyLength = llStringLength(MessageBody);
if(MessageBodyLength>15000){
// Adjust Timer to make next Call Quicker
UploadTimer = UploadTimer - 60; // Reduce Cycle Timer by 1 Minute
dbInsert(["THISOBJ", "", "Excess Dump Length", "Event Dump String Exceeded 15KB, Some upload data has been lost in this dump. Reducing Upload Timer by 60 Seconds. Timer Now: "+(string)UploadTimer, ""]);
llSetTimerEvent(UploadTimer);
}
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("EventDump")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["Servertype", ServerType];
string PostBody = MessageBody;
HTTPFLAG = "UserDump";
HTTPRequestHandle = llHTTPRequest(URL, SendParams, PostBody); // Send Request to Server to Check and/or Register this Server
LightToggle(ACTLIGHT, FALSE, "Green");
}
}

View File

@@ -0,0 +1,90 @@
# Game Server Configuration File
#
# Created by Tech Guy 2014
# Server Configuration
#Are we in Debug Mode?
DebugMode=FALSE
# Server Communication Channel
ServerComChannel=-13546788
# Common Communication Channel (ie DBComChannel)
CommonComChannel=-260046
# Avatar Scanner Communication Channel
ScannerComChannel=-18006
#Security Key (Used for Inter-Device Communication)
SecurityKey=3d7b1a28-f547-4d10-8924-7a2b771739f4
# NETWORK KEYS (Given during Machines Initial Call to tell it about DB Servers and Self)
# DO NOT CHANGE THE ORDER OF THESE 3 CONFIG DIRECTIVES
GameServer=5b8c8de4-e142-4905-a28f-d4d00607d3e9
GameDBServer=b9dbc6a4-2ac3-4313-9a7f-7bd1e11edf78
GameEventDBServer=dbfa0843-7f7f-4ced-83f6-33223ae57639
# Game Configuration
# Game Name
gamename=Heaven and Hell
# HighScores for User to Beat
highscores=11000||15000||20000||30000||40000||45000||75000||95000||125000||150000
# Win Values. Any Given gamevalue (Gv), Multiplied by the associated multiplier (M), the Associated Pot Value(Pv) is (Pv=Gv*M)
pots=10||25||75||150||300||400||1250||2500||3750||5000
# Game Values
gamevalues=P$5||P$10||P$25||P$50||P$75||P$100||P$250||P$500||P$750||P$1000
# Win Multipliers
multipliers=2||2.5||3||3||4||4||5||5||5||5
# Length of Round for Given Game Value
roundlengths=5||5||6||8||8||10||10||15||15||20
# Admin Menu Users
user=Tech Guy
user=Sebastian Viper
# Game Points Configuration
#JackPot Percentage
PotPercent=10
#List Of Possible Deduction Percentages
Mummy=0.20||0.30||0.40||0.50
# How Long should each Round Last
roundTime=25
# Points Awarded for a Single Number Match
pointsSingleField=200
# Points Awarded for a Line Made
pointsLine=1000
# Points Awarded for Pattern Fill
pointsPattern=5000
# Points Awarded for Fill Board
pointsAll=10000
# Points Awarded for Diamond
pointsCash=1000
# Points Awarded for
pointsPlus=1000
# Diagnostic Mode
DiagMode=FALSE
# JackPot Server Configuration Directives
# Maximum # of Jackpots Before Server Reset
MaxJackPots=6
# JackPot Timer (in seconds). The Time inbetween awarding jackpots. (3600=1hr)*6=21600(6hrs)
JackPotTimer=3600
# Initial Jackpot Value (NOTE: Stored in User DB Server)
InitialJackPot=100
# User Database Server Configuration Directives
# Upload Timer. Time Between Backing Up to Offworld Server (in seconds). Database is Truncated at this same interval.
UserUploadTimer=3720

View File

@@ -0,0 +1,451 @@
// Game Server Relay Engine v1.0
// Created by Tech Guy
// Configuration
// Constants
integer ServerComChannel = -13546788; // Secret Negative Channel for Server Communication
list KEYS = [ "5b8c8de4-e142-4905-a28f-d4d00607d3e9", "b9dbc6a4-2ac3-4313-9a7f-7bd1e11edf78", "dbfa0843-7f7f-4ced-83f6-33223ae57639" ];
list AuthedUsers = [];
string EMPTY = "";
key SecurityKey = "useyourownkey";
float LightHoldLength = 0.1;
string SecureRequest = "(Mq=h/c2)";
string cName = ".gameconfig"; // Name of Configuration NoteCard
// Off-World Data Communication Constants
key HTTPRequestHandle; // Handle for HTTP Request
string URLBase = "http://orbitsystems.ca/";
list HTTPRequestParams = [
HTTP_METHOD, "POST",
HTTP_MIMETYPE, "application/x-www-form-urlencoded",
HTTP_BODY_MAXLENGTH, 16384,
HTTP_CUSTOM_HEADER, "CUSKEY", "(Mq=h/c2)"
];
// Indicator Light Config
float GlowOn = 0.10;
float GlowOff = 0.0;
list ONColorVectors = [<0.0,1.0,0.0>,<1.0,0.5,0.0>,<1.0,0.0,0.0>];
list ColorNames = ["Green", "Orange", "Red"];
list OFFColorVectors = [<0.0,0.5,0.0>,<0.5,0.25,0.0>,<0.5,0.0,0.0>];
integer PWRLIGHT = 2;
integer CFGLIGHT = 3;
integer INLIGHT = 4;
integer OUTLIGHT = 5;
// Variables
integer ServerComHandle; // Hold Handle to Control Server Com Channel
integer cLine; // Holds Configuration Line Index for Loading Config Loop
key cQueryID; // Holds Current Configuration File Line during Loading Loop
string GameName = "";
// Switches
integer DebugMode = FALSE; // Are we running in with Debug Messages ON?
// Flags
list highscores = ["11000", "15000", "20000", "30000", "40000", "45000", "75000", "95000", "125000", "150000"];
list pots = ["10", "25", "75", "150", "300", "400", "1250", "2500", "3750", "5000"];
list gameValues = ["P$5", "P$10", "P$25", "P$50", "P$75", "P$100", "P$250", "P$500", "P$750", "P$1000"];
list Multipliers = ["2", "2.5", "3", "3", "4", "4", "5", "5", "5", "5"];
list RoundLengths = ["5", "5", "6", "8", "8", "10", "10", "15", "15", "20"];
list lMummy = [];
string roundTime;
string pointsSingleField;
string pointsLine;
string pointsPattern;
string pointsAll;
string pointsCash;
string pointsPlus;
string PotPercent;
string DiagMode;
// JackPot Configuration Directives
string MaxJackPots;
string JackPotTimer;
string InitialJackPot;
string CommonComChannel;
string AvatarScannerChannel;
// User Database Configuration Directives
string UserUploadTimer;
// Functions
Initialize(){
llListenRemove(ServerComHandle);
llSleep(LightHoldLength);
llListen(ServerComChannel, EMPTY, EMPTY, EMPTY);
if(DebugMode){
llOwnerSay(llGetObjectName()+" Server Online");
}
llOwnerSay("Configuring...");
cQueryID = llGetNotecardLine(cName, cLine);
}
LightToggle(integer LinkID, integer ISON, string Color){
if(ISON){
vector ColorVector = llList2Vector(ONColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOn,
PRIM_FULLBRIGHT, ALL_SIDES, TRUE
]);
}else{
vector ColorVector = llList2Vector(OFFColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOff,
PRIM_FULLBRIGHT, ALL_SIDES, FALSE
]);
}
}
LoadConfig(string data){
LightToggle(CFGLIGHT, TRUE, "Orange");
if(data!=""){ // If Line is not Empty
// if the line does not begin with a comment
if(llSubStringIndex(data, "#") != 0)
{
// find first equal sign
integer i = llSubStringIndex(data, "=");
// if line contains equal sign
if(i != -1){
// get name of name/value pair
string name = llGetSubString(data, 0, i - 1);
// get value of name/value pair
string value = llGetSubString(data, i + 1, -1);
// trim name
list temp = llParseString2List(name, [" "], []);
name = llDumpList2String(temp, " ");
// make name lowercase
name = llToLower(name);
// trim value
temp = llParseString2List(value, [" "], []);
value = llDumpList2String(temp, " ");
// Check Key/Value Pairs and Set Switches and Lists
if(name=="debugmode"){
if(value=="TRUE" || value=="true"){
DebugMode = TRUE;
llOwnerSay("Debug Mode: Enabled!");
}else if(value=="FALSE" || value=="false"){
DebugMode = FALSE;
llOwnerSay("Debug Mode: Disabled!");
}
}else if(name=="highscores"){
if(DebugMode){
llOwnerSay("Parsing HighScore Data...");
}
highscores = llParseString2List(value, "||", "");
if(llGetListLength(highscores)==10){
if(DebugMode){
llOwnerSay("HighScore Data Configured!");
}
}
}else if(name=="pots"){
if(DebugMode){
llOwnerSay("Parsing JackPot Data...");
}
pots = llParseString2List(value, "||", "");
if(llGetListLength(pots)==10){
if(DebugMode){
llOwnerSay("JackPot Data Configured!");
}
}
}else if(name=="gamevalues"){
if(DebugMode){
llOwnerSay("Parsing GameValue Data...");
}
gameValues = llParseString2List(value, "||", "");
if(llGetListLength(gameValues)==10){
if(DebugMode){
llOwnerSay("GameValue Data Configured!");
}
}
}else if(name=="multipliers"){
if(DebugMode){
llOwnerSay("Parsing Multipliers Data...");
}
Multipliers = llParseString2List(value, "||", "");
if(llGetListLength(Multipliers)==10){
if(DebugMode){
llOwnerSay("Multipliers Data Configured!");
}
}
}else if(name=="roundlengths"){
if(DebugMode){
llOwnerSay("Parsing RoundLengths Data...");
}
RoundLengths = llParseString2List(value, "||", "");
if(llGetListLength(RoundLengths)==10){
if(DebugMode){
llOwnerSay("RoundLengths Data Configured!");
}
}
}else if(name=="servercomchannel"){
ServerComChannel = (integer)value;
if(DebugMode){
llOwnerSay("Server Com Channel: "+(string)ServerComChannel);
}
}else if(name=="securitykey"){
SecurityKey = value;
if(DebugMode){
llOwnerSay("Security Key: "+SecurityKey);
}
}else if(name=="gameserver"){
KEYS = [] + [value];
if(DebugMode){
llOwnerSay("Game Server(Self): "+llKey2Name(llList2String(KEYS, 0)));
}
}else if(name=="gamedbserver"){
KEYS = KEYS + [value];
if(DebugMode){
llOwnerSay("Game User DB: "+llKey2Name(llList2String(KEYS, 1)));
}
}else if(name=="gameeventdbserver"){
KEYS = KEYS + [value];
if(DebugMode){
llOwnerSay("Game Event DB: "+llKey2Name(llList2String(KEYS, 2)));
}
}else if(name=="user"){
AuthedUsers = AuthedUsers + [value];
if(DebugMode){
llOwnerSay("New Machine Authed User: "+value);
}
}else if(name=="mummy"){
lMummy = llParseString2List(value, "||", "");
if(llGetListLength(lMummy)>0 && DebugMode){
llOwnerSay("Negative Percentages Configured!");
}
}else if(name=="roundtime"){
roundTime = value;
if(roundTime!="" && DebugMode){
llOwnerSay("Round Time Configured!");
}
}else if(name=="pointssinglefield"){
pointsSingleField = value;
if(pointsSingleField!="" && DebugMode){
llOwnerSay("Points Single Field Configured!");
}
}else if(name=="pointsline"){
pointsLine = value;
if(pointsLine!="" && DebugMode){
llOwnerSay("Points Line Configured!");
}
}else if(name=="pointspattern"){
pointsPattern = value;
if(pointsPattern!="" && DebugMode){
llOwnerSay("Points Pattern Configured!");
}
}else if(name=="pointsall"){
pointsAll = value;
if(pointsAll!="" && DebugMode){
llOwnerSay("Points All Configured!");
}
}else if(name=="pointscash"){
pointsCash = value;
if(pointsCash!="" && DebugMode){
llOwnerSay("Points Cash Configured!");
}
}else if(name=="pointsplus"){
pointsPlus = value;
if(pointsPlus!="" && DebugMode){
llOwnerSay("Round Time Configured!");
}
}else if(name=="potpercent"){
PotPercent = value;
if(PotPercent!="" && DebugMode){
llOwnerSay("JackPot Takes: "+value+"%");
}
}else if(name=="gamename"){
GameName = value;
if(GameName!="" && DebugMode){
llOwnerSay("Game Name: "+GameName);
}
}else if(name=="diagmode"){
DiagMode = value;
if(DebugMode){
llOwnerSay("Diagnostic Mode: "+DiagMode);
}
}else if(name=="maxjackpots"){
MaxJackPots = value;
if(DebugMode){
llOwnerSay("Max JackPots per Cycle: "+MaxJackPots);
}
}else if(name=="jackpottimer"){
JackPotTimer = value;
if(DebugMode){
llOwnerSay("JackPot Timer: "+JackPotTimer);
}
}else if(name=="initialjackpot"){
InitialJackPot = value;
if(DebugMode){
llOwnerSay("Initial JackPot Value: "+InitialJackPot);
}
}else if(name=="useruploadtimer"){
UserUploadTimer = value;
if(DebugMode){
llOwnerSay("User DB Backup Timer: "+UserUploadTimer);
}
}else if(name=="commoncomchannel"){
CommonComChannel = value;
if(DebugMode){
llOwnerSay("Common Com Channel: "+CommonComChannel);
}
}else if(name=="scannercomchannel"){
AvatarScannerChannel = value;
if(DebugMode){
llOwnerSay("Scanner Com Channel: "+AvatarScannerChannel);
}
}
LightToggle(CFGLIGHT, FALSE, "Orange");
}else{ // line does not contain equal sign
llOwnerSay("Configuration could not be read on line " + (string)cLine);
}
}
}
}
RegisterServer(string cmd){
if(cmd=="CheckReg"){
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("CheckReg")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", "Main"];
HTTPRequestHandle = llHTTPRequest(URL, SendParams, ""); // Send Request to Server to Check and/or Register this Server
}
}
// Main Program
default{
on_rez(integer params){
llGiveInventory(llGetOwner(), llGetInventoryName(INVENTORY_NOTECARD, 1));
llResetScript();
}
state_entry(){
LightToggle(PWRLIGHT, TRUE, "Red");
llSleep(LightHoldLength);
LightToggle(CFGLIGHT, TRUE, "Orange");
llSleep(LightHoldLength);
LightToggle(CFGLIGHT, FALSE, "Orange");
LightToggle(INLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(OUTLIGHT, FALSE, "Green");
Initialize();
}
dataserver(key query_id, string data){ // Config Notecard Read Function Needs to be Finished
if (query_id == cQueryID){
if (data != EOF){
LoadConfig(data); // Process Current Line
++cLine; // Incrment Line Index
cQueryID = llGetNotecardLine(cName, cLine); // Attempt to Read Next Config Line (Re-Calls DataServer Event)
}else{ // IF EOF (End of Config loop, and on Blank File)
LightToggle(CFGLIGHT, TRUE, "Orange");
// Check if Server is Registered with Website
RegisterServer("CheckReg");
}
}
}
changed(integer c){
if(c & CHANGED_INVENTORY){
llResetScript();
}
}
listen(integer chan, string cmd, key id, string data){
if(DebugMode){
llOwnerSay("GS Listen Event Fired!\r"+data);
}
LightToggle(INLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
if(data=="GetHighScores"){ // External Call for Game Configuration Information
list SendList = [] + SecurityKey + highscores + gameValues + pots + Multipliers; // Compile Lists
string SendString = llDumpList2String(SendList, "||"); // Dump to String
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
llRegionSayTo(id, ServerComChannel, SendString); // Send Back to Requesting Machine.
LightToggle(OUTLIGHT, FALSE, "Green");
return;
}else if(data=="GetRoundLengths"){
list SendList = [] + SecurityKey + RoundLengths; // Compile Lists
string SendString = llDumpList2String(SendList, "||"); // Dump to String
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
if(DebugMode){
llOwnerSay("Sent: "+SendString);
}
llRegionSayTo(id, ServerComChannel, SendString); // Send Back to Requesting Machine.
LightToggle(OUTLIGHT, FALSE, "Green");
return;
}else if(data=="GetPotTimeOut"){
list SendList = [] + SecurityKey + JackPotTimer; // Compile Lists
string SendString = llDumpList2String(SendList, "||"); // Dump to String
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
llRegionSayTo(id, ServerComChannel, SendString); // Send Back to Requesting Machine.
LightToggle(OUTLIGHT, FALSE, "Green");
return;
}else if(data==SecureRequest){
list GameConfig = [] + lMummy + [roundTime] + [pointsSingleField] + [pointsLine] + [pointsPattern] + [pointsAll] + [pointsCash] + [pointsPlus] + [PotPercent] + [DiagMode] + [MaxJackPots] + [JackPotTimer] + [InitialJackPot] + [UserUploadTimer] + [CommonComChannel] + [AvatarScannerChannel];
list SendList = [SecurityKey] + [SecureRequest] + KEYS + GameConfig + AuthedUsers;
string SendString = llDumpList2String(SendList, "||");
if(DebugMode){
llOwnerSay("Secure Response Send String: "+SendString);
}
LightToggle(INLIGHT, FALSE, "Green");
LightToggle(OUTLIGHT, TRUE, "Green");
llRegionSayTo(id, ServerComChannel, SendString);
llSleep(LightHoldLength);
LightToggle(OUTLIGHT, FALSE, "Green");
}
}
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id != HTTPRequestHandle) return;// exit if unknown
vector COLOR_BLUE = <0.0, 0.0, 1.0>;
float OPAQUE = 1.0;
list OutputData = llCSV2List(body); // Parse Response into List
string InputKey = llBase64ToString(llList2String(OutputData, 1));
string InputCMD = llBase64ToString(llList2String(OutputData, 0));
if(InputKey!=SecurityKey){
llOwnerSay("Invalid Security Key Received from RL Server!\r"+body);
}else{
if(InputCMD=="ALRDYREGOK"){ // Server Already Registered
if(DebugMode){
llOwnerSay("Server Already Registered!");
}
}else if(InputCMD=="REGOK"){ // Server Successfully Registered
if(DebugMode){
llOwnerSay("Server Successfully Registered!");
}
}else if(InputCMD=="REGERR"){ // Error Registering Server with Off-World Database
llOwnerSay("Error Registering Server with Database!");
}else if(InputCMD=="CHECKERR"){ // Error Checking Database for Server Registration
llOwnerSay("Error Checking Database for Server Registration");
}else{
llOwnerSay("Response from server not reconignized!");
}
}
llOwnerSay(llGetObjectName()+" Server Online");
LightToggle(CFGLIGHT, FALSE, "Orange");
}
}

View File

@@ -0,0 +1,759 @@
//Very Keynes - 2008 - 2009
//
// Version: OpenSimulator Server 0.6.1.7935 (interface version 2)
//
// 2009-01-06, 19:30 GMT
//
//------------------Begin VK-DBMS-VM----------------------------\\
//--------------------Introduction------------------------------\\
//
// Very Keynes - DBMS - Virtual Machine
//
// Implements a core set of registers and root functions
// to create and manage multi-table database structures as
// an LSL list. Although intended to under pin higher level
// database management tools such as VK-SQL it is usable as
// a small footprint database facility for system level
// applications.
//
//
// Naming Conventions and Code Style
//
// This Code is intended to be included as a header to user generated
// code. As such it's naming convention was selected so that it would
// minimise the possibility of duplicate names in the user code portion
// of the application. Exposed Functions and Variables are prefixed db.
//
// A full User Guide and Tutorial is availible at this URL:
//
// http://docs.google.com/Doc?id=d79kx35_26df2pbbd8
//
//
// Table Control Registers
//
integer th_; // Table Handle / Index Pointer
integer tc_; // Columns in Active Table
integer tr_; // Rows in Active Table
integer ts_; // Active Table Start Address
//
list _d_ = []; // Database File
list _i_ = [0]; // Index File
//
// Exposed Variables
//
integer dbIndex; // Active Row Table Pointer
list dbRow; // User Scratch List
string dbError; // System Error String
//
// Temporary / Working Variables
//
integer t_i;
string t_s;
float t_f;
list t_l;
//
// System Functions
//
string dbCreate(string tab, list col)
{
if(dbOpen(tab))
{
dbError = tab + " already exists";
return "";
}
tc_ = llGetListLength(col);
_i_ += [tab, tc_, 0, 0, 0];
th_= 0;
dbOpen(tab);
dbInsert(col);
return tab;
}
integer dbCol(string col)
{
return llListFindList(dbGet(0), [_trm(col)]);
}
integer dbDelete(integer ptr)
{
if(ptr > 0 && ptr < tr_)
{
t_i = ts_ + tc_ * ptr;
_d_ = llDeleteSubList(_d_, t_i, t_i + tc_ - 1);
--tr_;
return tr_ - 1;
}
else
{
dbError = (string)ptr + " is outside the Table Bounds";
return FALSE;
}
}
integer dbDrop(string tab)
{
t_i = llListFindList(_i_, [tab]);
if(-1 != t_i)
{
dbOpen(tab);
_d_ = llDeleteSubList(_d_, ts_, ts_ + tc_ * tr_ - 1);
_i_ = llDeleteSubList(_i_, th_, th_ + 4);
th_= 0;
return TRUE;
}
else
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
}
integer dbExists(list cnd)
{
for(dbIndex = tr_ - 1 ; dbIndex > 0 ; --dbIndex)
{
if(dbTest(cnd)) return dbIndex;
}
return FALSE;
}
list dbGet(integer ptr)
{
if(ptr < tr_ && ptr >= 0)
{
t_i = ts_ + tc_ * ptr;
return llList2List(_d_, t_i, t_i + tc_ - 1);
}
else
{
dbError = (string) ptr + " is outside the Table Bounds";
return [];
}
}
integer _idx(integer hdl)
{
return (integer)llListStatistics(6, llList2ListStrided(_i_, 0, hdl, 5));
}
integer dbInsert(list val)
{
if(llGetListLength(val) == tc_)
{
dbIndex = tr_++;
_d_ = llListInsertList(_d_, val, ts_ + tc_ * dbIndex);
return dbIndex;
}
else
{
dbError = "Insert Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbOpen(string tab)
{
if(th_)
{
_i_ = llListReplaceList(_i_, [tr_, dbIndex, tc_ * tr_], th_ + 2, th_ + 4);
}
t_i = llListFindList(_i_, [tab]);
if(-1 == t_i) //if tab does not exist abort
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
else if(th_ != t_i)
{
th_ = t_i++;
ts_ = _idx(th_);
tc_ = llList2Integer(_i_, t_i++);
tr_ = llList2Integer(_i_, t_i++);
dbIndex = llList2Integer(_i_, t_i);
}
return tr_ - 1;
}
integer dbPut(list val)
{
if(llGetListLength(val) == tc_)
{
t_i = ts_ + tc_ * dbIndex;
_d_ = llListReplaceList(_d_, val, t_i, t_i + tc_ - 1);
return dbIndex;
}
else
{
dbError = "Update Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbTest(list cnd)
{
if(llGetListEntryType(cnd,2) >= 3)
{
t_s = llList2String(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
if ("==" == llList2String(cnd, 1)){t_i = t_s == _trm(llList2String(cnd, 2));}
else if("!=" == llList2String(cnd, 1)){t_i = t_s != _trm(llList2String(cnd, 2));}
else if("~=" == llList2String(cnd, 1))
{t_i = !(llSubStringIndex(llToLower(t_s), llToLower(_trm(llList2String(cnd, 2)))));}
}
else
{
t_f = llList2Float(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
t_s = llList2String(cnd, 1);
if ("==" == t_s){t_i = t_f == llList2Float(cnd, 2);}
else if("!=" == t_s){t_i = t_f != llList2Float(cnd, 2);}
else if("<=" == t_s){t_i = t_f <= llList2Float(cnd, 2);}
else if(">=" == t_s){t_i = t_f >= llList2Float(cnd, 2);}
else if("<" == t_s){t_i = t_f < llList2Float(cnd, 2);}
else if(">" == t_s){t_i = t_f > llList2Float(cnd, 2);}
}
if(t_i) return dbIndex;
else return FALSE;
}
string _trm(string val)
{
return llStringTrim(val, STRING_TRIM);
}
dbTruncate(string tab)
{
dbIndex = dbOpen(tab);
while(dbIndex > 0) dbDelete(dbIndex--);
}
dbSort(integer dir)
{
t_i = ts_ + tc_;
_d_ = llListReplaceList(_d_, llListSort(llList2List(_d_, t_i, t_i + tc_ * tr_ - 2), tc_, dir), t_i, t_i + tc_ * tr_ - 2);
}
float dbFn(string fn, string col)
{
t_i = ts_ + tc_;
t_l = llList2List(_d_, t_i, t_i + tc_ * tr_ - 2);
if(dbCol(col) != 0) t_l = llDeleteSubList(t_l, 0, dbCol(col) - 1);
return llListStatistics(llSubStringIndex("ramimaavmedesusqcoge", llGetSubString(llToLower(fn),0,1)) / 2,
llList2ListStrided(t_l, 0, -1, tc_));
}
//
//--------------------------- End VK-DBMS-VM ---------------------------\\
//
// Configuration
// Constants
integer DBComChannel = -260046;
integer ServerComChannel = -13546788;
integer ScannerComChannel = -18006;
integer ServerComHandle;
integer ScannerComHandle;
string DBName = "HeavenAndHellHourlyJackPot"; // Database for Heaven and Hell Player Info
string HoverTextString = "Heaven And Hell\n Hourly Jackpot Server"; // Base String Name of Databse Engine
string EMPTY = "";
key SecurityKey = "UseYourOwnKey";
key GameServer = "";
key GameEventDBServer = "";
key GameUserDBServer = "";
integer BasePotAmt = 100;
float LightHoldLength = 0.1;
string AskForKeys = "(Mq=h/c2)";
string ServerType = "JACKPOT";
integer UploadTimer = 45; // Frequency in Seconds of User Database Upload
string TimerMode = "JackPot"; // Hold TimerMode State (either JackPot or Dump)
// Off-World Data Communication Constants
key HTTPRequestHandle; // Handle for HTTP Request
string URLBase = "http://orbitsystems.ca";
list HTTPRequestParams = [
HTTP_METHOD, "POST",
HTTP_MIMETYPE, "application/x-www-form-urlencoded",
HTTP_BODY_MAXLENGTH, 16384,
HTTP_CUSTOM_HEADER, "CUSKEY", "(Mq=h/c2)"
];
// Indicator Light Config
float GlowOn = 0.10;
float GlowOff = 0.0;
list ONColorVectors = [<0.0,1.0,0.0>,<1.0,0.5,0.0>,<1.0,0.0,0.0>];
list ColorNames = ["Green", "Orange", "Red"];
list OFFColorVectors = [<0.0,0.5,0.0>,<0.5,0.25,0.0>,<0.5,0.0,0.0>];
integer PWRLIGHT = 2;
integer ACTLIGHT = 3;
// Incoming Field Ids
integer SECKEY = 0;
integer CMD = 1;
integer UUID = 2;
integer PLAYED = 4;
integer WON = 5;
integer SPENT = 6;
integer WINS = 7;
integer LOSES = 8;
// Switches
integer HoverText = TRUE; // Should we show hoverText
integer DebugMode = FALSE; // Should we say De bug Messages to Owner?
// Variables
integer DBComHandle; // Database Communication Handle
integer DBEntries; // NUmber of Database Entries
integer DBEMPTY = 1;
integer TotalTouched = 0;
string HTTPFLAG = ""; // Hold Flag to know what last HTTP Resquest was for
string DiagMode; // Holds String Flag for Diagnostics Mode (ie Return all payments upon being made, and do not payout winers, ONLY LOG DATA!)
// NoteCard Reader
key nrofnamesoncard;
integer nrofnames;
list names;
list keynameoncard;
string nameoncard;
string storedname;
// Jackpot Server Type Configuration
integer PotSize;
integer PotPercentage; // Hold Percentage of JackPot to RollOver
integer JackPotCounter; // Hold Incrementally increasing JackPot Count (Increased every time a JackPot Routine is run)
integer MaxJackPots = 6; // Max number of JackPots before Off-World DB Dump and DB Truncate (HrsBeforeReset = MaxJackPots * UploadTimer)
// Menus
// Functions
Initialize(){
if(DebugMode){
llOwnerSay("Initializing "+DBName+"...\n\t\t\t\t\t\t\t Starting System...");
}
if(HoverText){
llSetText(HoverTextString, <1.0,1.0,1.0>, 0.2);
}
llListenRemove(DBComHandle);
llListenRemove(ServerComHandle);
llListenRemove(ScannerComHandle);
llSleep(0.1);
DBComHandle = llListen(DBComChannel, EMPTY, EMPTY, EMPTY);
ServerComHandle = llListen(ServerComChannel, EMPTY, EMPTY, EMPTY);
ScannerComHandle = llListen(ScannerComChannel, EMPTY, EMPTY, EMPTY);
string CreatedDB = dbCreate(DBName, ["uuid", "name", "jackpot"]);
if(CreatedDB==DBName && DebugMode){
llOwnerSay("Database "+DBName+" Created...");
llOwnerSay("Creating Pot Entry...");
}
//dbInsert(["uuid", "name", "spent", "won", "jackpot"]);
DBEntries = DBEMPTY;
LightToggle(PWRLIGHT, FALSE, "Red");
llSleep(LightHoldLength);
LightToggle(PWRLIGHT, TRUE, "Red");
LightToggle(ACTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
FindKeys(){
llRegionSay(ServerComChannel, AskForKeys);
}
RegisterServer(string cmd){
if(cmd=="CheckReg"){
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("CheckReg")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", ServerType];
HTTPFLAG = "CheckReg";
HTTPRequestHandle = llHTTPRequest(URL, SendParams, ""); // Send Request to Server to Check and/or Register this Server
}
}
// Check key if any incoming request and validate against Security Key
integer SecurityCheck(key CheckID){
if(CheckID!=SecurityKey){
return FALSE;
}else{
return TRUE;
}
}
ToggleDebug(){
DebugMode = !DebugMode;
if(DebugMode){
llOwnerSay("Debug Mode ON!");
}else{
llOwnerSay("Debug Mode OFF!");
}
}
LightToggle(integer LinkID, integer ISON, string Color){
if(ISON){
vector ColorVector = llList2Vector(ONColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOn,
PRIM_FULLBRIGHT, ALL_SIDES, TRUE
]);
}else{
vector ColorVector = llList2Vector(OFFColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOff,
PRIM_FULLBRIGHT, ALL_SIDES, FALSE
]);
}
}
string GetUserData(){
dbIndex = 1;
string ReturnString = "";
for(dbIndex=1;dbIndex<=DBEntries;dbIndex++){
list CurrentLine = dbGet(dbIndex);
if(llList2String(CurrentLine, 0)==""){ return ReturnString; }
string CompiledString = llList2String(CurrentLine, 0)+"||"+llList2String(CurrentLine, 1)+"||"+llList2String(CurrentLine, 2)+"||"+llList2String(CurrentLine, 3)+"||"+llList2String(CurrentLine, 4)+"||"+llList2String(CurrentLine, 5)+"||"+llList2String(CurrentLine, 6)+",";
ReturnString = ReturnString + CompiledString;
}
return ReturnString;
}
PrintJackPotWinners(string uuid){
dbIndex = 1;
for(dbIndex=1;dbIndex<=DBEntries;dbIndex++){
list CurrentLine = dbGet(dbIndex);
llRegionSayTo(uuid, 0, "\nJackPot Winners:\n" +
"UUID: " + llList2String(CurrentLine, 0) + "\n" +
"Name: " + llList2String(CurrentLine, 1) + "\n" +
"JackPot: " + llList2String(CurrentLine, 2));
}
}
// Scan for Users Function
// Ask Scanner for List of Users on Sim
ScanforUsers(list UsersToCheck){
integer i;
list UserIDS = [];
for(i=0;i<llGetListLength(UsersToCheck);i++){
UserIDS = UserIDS + llList2Key(llParseString2List(llList2String(UsersToCheck, i), ["~"], ""), 1);
if(DebugMode){
llOwnerSay("Key to scan for: "+llList2String(UserIDS, i));
}
}
string ComMessage = SecurityKey+"||SCANFOR||"+llDumpList2String(UserIDS, "||");
if(DebugMode){
llOwnerSay("JP Server-Avatar Scanner String: "+ComMessage);
}
llRegionSay(ScannerComChannel, ComMessage);
}
// Log Error Event to Games Event DB Server
//Database LayOut = ["uuid", "theirip", "name", "eventtype", "message", "data"]
LogEvent(string ErrType, string userid, string name, string EventType, string Message, string Data){
string SendString = ""; // Define Send String
if(ErrType=="Security"){
list SendList = [] + [SecurityKey] + ["INSERT"] + [userid, name, EventType, Message, Data];
SendString = llDumpList2String(SendList, "||");
}
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
}
// Pay Active Users Their JackPot Share
JackPotPayOut(list ActiveUsers){
float JackPotRollOver = (float)PotSize * (float)((float)PotPercentage / 100.0); // Determine JackPot Amount to Roll Over
if(DebugMode){
llOwnerSay("JPRO: "+(string)JackPotRollOver);
}
integer JackPotToGive = PotSize - (integer)JackPotRollOver; // Determine JackPot Amount to Give Away
integer i;
integer NumActiveUsers = llGetListLength(ActiveUsers);
if(NumActiveUsers>5){
NumActiveUsers = 5;
}
for(i=0;i<NumActiveUsers;i++){
integer AmtToGive = (integer)llFrand(JackPotToGive/2);
integer Remain = JackPotToGive - AmtToGive;
JackPotToGive = Remain;
if(DebugMode){
llOwnerSay("AmtToGive: "+(string)AmtToGive+"\rSize of Remaining JackPot: "+JackPotToGive);
}
if(AmtToGive>0){
if(DiagMode=="FALSE" || DiagMode==""){ // If we are not in Diagnostic Mode
llGiveMoney(llList2String(ActiveUsers, i), AmtToGive); // Give Money to User (Award JackPot)
}else{ // If we are in Diagnostic Mode, Notify the User, If in Debug Mode!
if(DebugMode){
llRegionSayTo(llList2String(ActiveUsers, i), 0, "Diagnostic Mode Enabled! No JackPot will be Awarded!");
}
}
list DBInsert = [llList2String(ActiveUsers, i), osKey2Name(llList2String(ActiveUsers, i)), (string)AmtToGive ];
dbInsert(DBInsert);
}
}
}
// Main Program
default
{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
touch(integer num){
LightToggle(ACTLIGHT, TRUE, "Green");
TotalTouched = TotalTouched + num;
key WhoTouched = llDetectedKey(0);
if(TotalTouched>1){
return;
}
if(llListFindList(names, [osKey2Name(WhoTouched)])!= -1){
ToggleDebug();
llRegionSayTo(WhoTouched, 0, "Outputting DB Contents...");
PrintJackPotWinners(WhoTouched);
}else{
llRegionSayTo(WhoTouched, 0, "You are not authorized!\nThis attempted violation has been reported!");
list SendList = [] + [SecurityKey] + ["INSERT"] + [(string)WhoTouched] + ["Un-Authd Touch of User DB"] + ["Un-Authorized Access attempt made to "+HoverTextString+"."];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
}
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
llSetTimerEvent(UploadTimer);
}
touch_end(integer num){
TotalTouched = 0;
}
listen(integer chan, string cmd, key id, string data){
LightToggle(ACTLIGHT, TRUE, "Green");
if(DebugMode){
llOwnerSay("Listen Event Fired:\nCommand: "+cmd+"\n"+"Data: "+data);
}
if(SecurityCheck(llList2Key(llParseString2List(data, "||", []), 0))==FALSE){ // If Device did not Send Security Key
if(DebugMode){
llOwnerSay("Un-Authorized Accept Attempt of "+HoverTextString+"!\rEvent Logged!");
}
list SendList = [] + [SecurityKey] + ["INSERT"] + ["Un-Authd Access to User DB"] + ["Un-Authorized Access attempt made to "+HoverTextString+"."] + [data];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
return;
}
if(chan==ServerComChannel){
cmd = llList2String(llParseStringKeepNulls(data, ["||"], []), CMD);
if(llList2String(llParseString2List(data, "||", ""), 0)==AskForKeys){
return;
}else if(cmd==AskForKeys){
GameServer = llList2String(llParseString2List(data, "||", ""), 2);
GameUserDBServer = llList2String(llParseString2List(data, "||", ""), 3);
GameEventDBServer = llList2String(llParseString2List(data, "||", ""), 4);
PotPercentage = llList2Integer(llParseString2List(data, "||", ""), 16);
DiagMode = llList2String(llParseString2List(data, "||", ""), 17);
MaxJackPots = llList2Integer(llParseString2List(data, "||", ""), 18);
UploadTimer = llList2Integer(llParseString2List(data, "||", ""), 19);
if(DebugMode){
llOwnerSay("Server UUID To Name Resolutions:\nGame Server: "+llKey2Name(GameServer)+"\nGame Event DB Server: "+llKey2Name(GameEventDBServer)+"\nPot Percentage: "+(string)PotPercentage+"%\nMax # JackPots per Cycle: "+(string)MaxJackPots+"\nJackPot Timer: "+(string)UploadTimer);
}
// Get Authed Users from NC
nrofnamesoncard = llGetNumberOfNotecardLines("whitelist");
}
llListenRemove(ServerComHandle);
}
if(chan==DBComChannel ){
cmd = llList2String(llParseStringKeepNulls(data, ["||"], []), CMD);
if(DebugMode){
llOwnerSay("CMD: "+cmd);
}
//Test cmd
if(cmd=="TOPLIST"){
list InList = llParseStringKeepNulls(data, ["||"], []);
integer i;
if(DebugMode){
for(i=0;i<llGetListLength(InList);i++){
llOwnerSay("Entry "+i+" :"+llList2String(InList, i)+"\r");
}
}
// Determine Current Pot Size
for(i=0;i<llGetListLength(InList);i++){
list CurList = [] + llParseString2List(llList2String(InList, i), ["~"], []);
if(llList2String(CurList, 1)=="UPPOT"){
PotSize = llList2Integer(CurList, 0);
}
}
if(DebugMode){
llOwnerSay("Pot Size: "+(string)PotSize);
}
list TopList = llListSort(llList2List(InList, 2, -1), -1, TRUE);
if(DebugMode){
for(i=0;i<llGetListLength(TopList);i++){
llOwnerSay("Sorted Entry "+i+" :"+llList2String(TopList, i)+"\r");
}
}
// Ask Scanner Prim for List of Users that are Active in Range
ScanforUsers(TopList);
}
}
if(chan==ScannerComChannel){ // Response From Scanner
if(DebugMode){
llOwnerSay("Data String: "+data);
}
list ActiveUserList = llList2List(llParseString2List(data, ["||"], []), 2, -1);
JackPotPayOut(ActiveUserList); // Pay Active Users, Update DB E.T.C
}
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
}
// Read Security Notecard
dataserver (key queryid, string data){
if (queryid == nrofnamesoncard) {
nrofnames = (integer) data;
integer i;
for (i=0;i < nrofnames;i++){
keynameoncard = keynameoncard + llGetNotecardLine("whitelist", i);
}
} else {
integer listlength;
listlength = llGetListLength(keynameoncard);
integer j = 0;
for(j=0;j<=listlength;j++) {
if(queryid == (key)llList2String(keynameoncard,j)){
if(data!=""){
if(DebugMode){
llOwnerSay("Authorized User: "+data);
}
names += data;
}else{
llOwnerSay("Security Turned Off.");
}
}
}
if(listlength==llGetListLength(names)){
llOwnerSay(DBName+" Server Online!");
llSetTimerEvent(UploadTimer);
}
}
}
// Server Response Catcher for Dumps and Initial Reg
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id != HTTPRequestHandle) return;// exit if unknown
LightToggle(ACTLIGHT, TRUE, "Green");
vector COLOR_BLUE = <0.0, 0.0, 1.0>;
float OPAQUE = 1.0;
llSetTimerEvent(UploadTimer);
list OutputData = llCSV2List(body); // Parse Response into List
string InputKey = llBase64ToString(llList2String(OutputData, 1));
string InputCMD = llBase64ToString(llList2String(OutputData, 0));
if(DebugMode){
llOwnerSay("Key: "+InputKey+"\nCMD: "+InputCMD+"\nMsg: "+body);
}
if(InputKey!=SecurityKey){
llOwnerSay("Invalid Security Key Received from RL Server!\r"+InputKey);
}else if(HTTPFLAG=="CheckReg"){
HTTPFLAG = "";
if(InputCMD=="ALRDYREGOK"){ // Server Already Registered
if(DebugMode){
llOwnerSay("Server Already Registered!");
}
}else if(InputCMD=="REGOK"){ // Server Successfully Registered
if(DebugMode){
llOwnerSay("Server Successfully Registered!");
}
}else if(InputCMD=="REGERR"){ // Error Registering Server with Off-World Database
llOwnerSay("Error Registering Server with Database!");
}else if(InputCMD=="CHECKERR"){ // Error Checking Database for Server Registration
llOwnerSay("Error Checking Database for Server Registration");
}else{
llOwnerSay("Response from server not reconignized!");
}
FindKeys(); // Call to Config Server for Configuration Information
}else if(HTTPFLAG=="UserDump"){
HTTPFLAG = "";
if(InputCMD=="DUMPEMPTY"){
if(DebugMode){
llOwnerSay("Server says Data dump was EMPTY!");
}
string message = "Server Reponse Says Database dump was empty for DB: "+HoverTextString;
LogEvent("General", EMPTY, EMPTY, "User DB Dump Was Empty!", message, EMPTY);
TimerMode = "JackPot";
llSetTimerEvent(UploadTimer);
}else if(InputCMD=="DUMPOK"){
if(DebugMode){
llOwnerSay("Server Dump OK!");
}
list SendList = [] + [SecurityKey] + ["INSERT"] + ["User Database Dump Successfull!"] + ["Database dump successfull for DB: "+HoverTextString+"."];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
if(DebugMode){
llOwnerSay("Truncating Database...");
}
dbTruncate(DBName);
DBEntries = DBEMPTY;
TimerMode = "JackPot";
llSetTimerEvent(UploadTimer);
}
}
LightToggle(ACTLIGHT, FALSE, "Green");
}
timer(){
LightToggle(ACTLIGHT, TRUE, "Green");
llSetTimerEvent(UploadTimer);
if(TimerMode=="JackPot"){
JackPotCounter++;
if(JackPotCounter==MaxJackPots){
JackPotCounter = 0;
TimerMode = "Dump";
llSetTimerEvent(30.0); // Wait 30 Seconds until calling Timer Again with Dump Flag Set. This gives time for the JackPot Round to Complete.
}
llRegionSayTo(GameUserDBServer, DBComChannel, SecurityKey+"||"+"HRPOT");
}else if(TimerMode=="Dump"){
string DumpString = GetUserData();
if(DebugMode){
llOwnerSay("Dump String: "+DumpString);
}
string EncodedDumpString = llStringToBase64(DumpString);
string MessageBody = "data="+EncodedDumpString;
integer MessageBodyLength = llStringLength(MessageBody);
if(MessageBodyLength>15000){
// Send to Event Server that we missed Data on Upload due to Body OverSize.
// Adjust Timer to make next Call Quicker
UploadTimer = UploadTimer - 60; // Reduce Cycle Timer by 1 Minute
llSetTimerEvent(UploadTimer);
}
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("JackPotDump")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
if(DebugMode){
llOwnerSay("Send String: "+CmdString);
}
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", ServerType];
string PostBody = MessageBody;
HTTPFLAG = "UserDump";
HTTPRequestHandle = llHTTPRequest(URL, SendParams, PostBody); // Send Request to Server to Check and/or Register this Server
LightToggle(ACTLIGHT, FALSE, "Green");
}
}
run_time_permissions(integer perm){
if(PERMISSION_DEBIT & perm){
RegisterServer("CheckReg");
}
}
}

View File

@@ -0,0 +1,750 @@
//Very Keynes - 2008 - 2009
//
// Version: OpenSimulator Server 0.6.1.7935 (interface version 2)
//
// 2009-01-06, 19:30 GMT
//
//------------------Begin VK-DBMS-VM----------------------------\\
//--------------------Introduction------------------------------\\
//
// Very Keynes - DBMS - Virtual Machine
//
// Implements a core set of registers and root functions
// to create and manage multi-table database structures as
// an LSL list. Although intended to under pin higher level
// database management tools such as VK-SQL it is usable as
// a small footprint database facility for system level
// applications.
//
//
// Naming Conventions and Code Style
//
// This Code is intended to be included as a header to user generated
// code. As such it's naming convention was selected so that it would
// minimise the possibility of duplicate names in the user code portion
// of the application. Exposed Functions and Variables are prefixed db.
//
// A full User Guide and Tutorial is availible at this URL:
//
// http://docs.google.com/Doc?id=d79kx35_26df2pbbd8
//
//
// Table Control Registers
//
integer th_; // Table Handle / Index Pointer
integer tc_; // Columns in Active Table
integer tr_; // Rows in Active Table
integer ts_; // Active Table Start Address
//
list _d_ = []; // Database File
list _i_ = [0]; // Index File
//
// Exposed Variables
//
integer dbIndex; // Active Row Table Pointer
list dbRow; // User Scratch List
string dbError; // System Error String
//
// Temporary / Working Variables
//
integer t_i;
string t_s;
float t_f;
list t_l;
//
// System Functions
//
string dbCreate(string tab, list col)
{
if(dbOpen(tab))
{
dbError = tab + " already exists";
return "";
}
tc_ = llGetListLength(col);
_i_ += [tab, tc_, 0, 0, 0];
th_= 0;
dbOpen(tab);
dbInsert(col);
return tab;
}
integer dbCol(string col)
{
return llListFindList(dbGet(0), [_trm(col)]);
}
integer dbDelete(integer ptr)
{
if(ptr > 0 && ptr < tr_)
{
t_i = ts_ + tc_ * ptr;
_d_ = llDeleteSubList(_d_, t_i, t_i + tc_ - 1);
--tr_;
return tr_ - 1;
}
else
{
dbError = (string)ptr + " is outside the Table Bounds";
return FALSE;
}
}
integer dbDrop(string tab)
{
t_i = llListFindList(_i_, [tab]);
if(-1 != t_i)
{
dbOpen(tab);
_d_ = llDeleteSubList(_d_, ts_, ts_ + tc_ * tr_ - 1);
_i_ = llDeleteSubList(_i_, th_, th_ + 4);
th_= 0;
return TRUE;
}
else
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
}
integer dbExists(list cnd)
{
for(dbIndex = tr_ - 1 ; dbIndex > 0 ; --dbIndex)
{
if(dbTest(cnd)) return dbIndex;
}
return FALSE;
}
list dbGet(integer ptr)
{
if(ptr < tr_ && ptr >= 0)
{
t_i = ts_ + tc_ * ptr;
return llList2List(_d_, t_i, t_i + tc_ - 1);
}
else
{
dbError = (string) ptr + " is outside the Table Bounds";
return [];
}
}
integer _idx(integer hdl)
{
return (integer)llListStatistics(6, llList2ListStrided(_i_, 0, hdl, 5));
}
integer dbInsert(list val)
{
if(llGetListLength(val) == tc_)
{
dbIndex = tr_++;
_d_ = llListInsertList(_d_, val, ts_ + tc_ * dbIndex);
return dbIndex;
}
else
{
dbError = "Insert Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbOpen(string tab)
{
if(th_)
{
_i_ = llListReplaceList(_i_, [tr_, dbIndex, tc_ * tr_], th_ + 2, th_ + 4);
}
t_i = llListFindList(_i_, [tab]);
if(-1 == t_i) //if tab does not exist abort
{
dbError = tab + " : Table name not recognised";
return FALSE;
}
else if(th_ != t_i)
{
th_ = t_i++;
ts_ = _idx(th_);
tc_ = llList2Integer(_i_, t_i++);
tr_ = llList2Integer(_i_, t_i++);
dbIndex = llList2Integer(_i_, t_i);
}
return tr_ - 1;
}
integer dbPut(list val)
{
if(llGetListLength(val) == tc_)
{
t_i = ts_ + tc_ * dbIndex;
_d_ = llListReplaceList(_d_, val, t_i, t_i + tc_ - 1);
return dbIndex;
}
else
{
dbError = "Update Failed - too many or too few Columns specified";
return FALSE;
}
}
integer dbTest(list cnd)
{
if(llGetListEntryType(cnd,2) >= 3)
{
t_s = llList2String(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
if ("==" == llList2String(cnd, 1)){t_i = t_s == _trm(llList2String(cnd, 2));}
else if("!=" == llList2String(cnd, 1)){t_i = t_s != _trm(llList2String(cnd, 2));}
else if("~=" == llList2String(cnd, 1))
{t_i = !(llSubStringIndex(llToLower(t_s), llToLower(_trm(llList2String(cnd, 2)))));}
}
else
{
t_f = llList2Float(dbGet(dbIndex), dbCol(llList2String(cnd, 0)));
t_s = llList2String(cnd, 1);
if ("==" == t_s){t_i = t_f == llList2Float(cnd, 2);}
else if("!=" == t_s){t_i = t_f != llList2Float(cnd, 2);}
else if("<=" == t_s){t_i = t_f <= llList2Float(cnd, 2);}
else if(">=" == t_s){t_i = t_f >= llList2Float(cnd, 2);}
else if("<" == t_s){t_i = t_f < llList2Float(cnd, 2);}
else if(">" == t_s){t_i = t_f > llList2Float(cnd, 2);}
}
if(t_i) return dbIndex;
else return FALSE;
}
string _trm(string val)
{
return llStringTrim(val, STRING_TRIM);
}
dbTruncate(string tab)
{
dbIndex = dbOpen(tab);
while(dbIndex > 0) dbDelete(dbIndex--);
}
dbSort(integer dir)
{
t_i = ts_ + tc_;
_d_ = llListReplaceList(_d_, llListSort(llList2List(_d_, t_i, t_i + tc_ * tr_ - 2), tc_, dir), t_i, t_i + tc_ * tr_ - 2);
}
float dbFn(string fn, string col)
{
t_i = ts_ + tc_;
t_l = llList2List(_d_, t_i, t_i + tc_ * tr_ - 2);
if(dbCol(col) != 0) t_l = llDeleteSubList(t_l, 0, dbCol(col) - 1);
return llListStatistics(llSubStringIndex("ramimaavmedesusqcoge", llGetSubString(llToLower(fn),0,1)) / 2,
llList2ListStrided(t_l, 0, -1, tc_));
}
//
//--------------------------- End VK-DBMS-VM ---------------------------\\
//
// Configuration
// Constants
integer DBComChannel = -260002;
integer ServerComChannel = -63473672;
integer ServerComHandle;
string DBName = "GunsCarsAndGirlsUserDatabase"; // Database for Heaven and Hell Player Info
string HoverTextString = "Guns Cars and Girls\n User Database"; // Base String Name of Databse Engine
string EMPTY = "";
key SecurityKey = "3d7b1a28-f547-4d10-8924-7a2b771739f4";
key GameServer = "";
key GameEventDBServer = "";
integer BasePotAmt = 100;
float LightHoldLength = 0.1;
string AskForKeys = "TheKeyIs(Mq=h/c2)";
integer UploadTimer = 3720; // Frequency in Seconds of User Database Upload
integer DBEMPTY = 1;
// Off-World Data Communication Constants
key HTTPRequestHandle; // Handle for HTTP Request
string URLBase = "http://api.orbitsystems.ca/api.php";
list HTTPRequestParams = [
HTTP_METHOD, "POST",
HTTP_MIMETYPE, "application/x-www-form-urlencoded",
HTTP_BODY_MAXLENGTH, 16384,
HTTP_CUSTOM_HEADER, "CUSKEY", "TheKeyIs(Mq=h/c2)"
];
// Indicator Light Config
float GlowOn = 0.10;
float GlowOff = 0.0;
list ONColorVectors = [<0.0,1.0,0.0>,<1.0,0.5,0.0>,<1.0,0.0,0.0>];
list ColorNames = ["Green", "Orange", "Red"];
list OFFColorVectors = [<0.0,0.5,0.0>,<0.5,0.25,0.0>,<0.5,0.0,0.0>];
integer PWRLIGHT = 2;
integer ACTLIGHT = 3;
// Incoming Field Ids
integer SECKEY = 0;
integer CMD = 1;
integer UUID = 2;
integer PLAYED = 4;
integer WON = 5;
integer SPENT = 6;
integer WINS = 7;
integer LOSES = 8;
// Switches
integer HoverText = TRUE; // Should we show hoverText
integer DebugMode = TRUE; // Should we say De bug Messages to Owner?
// Variables
integer DBComHandle; // Database Communication Handle
integer DBEntries = 1; // NUmber of Database Entries
integer TotalTouched = 0;
string HTTPFLAG = ""; // Hold Flag to know what last HTTP Resquest was for
// NoteCard Reader
key nrofnamesoncard;
integer nrofnames;
list names;
list keynameoncard;
string nameoncard;
string storedname;
// Menus
// Functions
Initialize(){
if(DebugMode){
llOwnerSay("Initializing "+DBName+"...\n\t\t\t\t\t\t\t Starting System...");
}
if(HoverText){
llSetText(HoverTextString, <1.0,1.0,1.0>, 0.2);
}
llListenRemove(DBComHandle);
llListenRemove(ServerComHandle);
llSleep(0.1);
DBComHandle = llListen(DBComChannel, EMPTY, EMPTY, EMPTY);
ServerComHandle = llListen(ServerComChannel, EMPTY, EMPTY, EMPTY);
string CreatedDB = dbCreate(DBName, ["uuid", "name", "played", "won", "spent", "wins", "loses"]);
if(CreatedDB==DBName && DebugMode){
llOwnerSay("Database "+DBName+" Created...");
llOwnerSay("Creating Pot Entry...");
}
dbInsert(["UPPOT", "100", "0", "0", "0", "0", "0"]);
// dbInsert(["3d7b1a28-f547-4d10-8924-7a2b771739f4", "0", "0", "0", "5", "0", "0"]);
// dbInsert(["3d7b1a28-f547-4d10-8924-7a2b771739f4", "0", "0", "0", "12", "0", "0"]);
// dbInsert(["3d7b1a28-f547-4d10-8924-7a2b771739f4", "0", "0", "0", "32", "0", "0"]);
DBEntries = 1;
LightToggle(PWRLIGHT, FALSE, "Red");
llSleep(LightHoldLength);
LightToggle(PWRLIGHT, TRUE, "Red");
LightToggle(ACTLIGHT, TRUE, "Green");
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
RegisterServer("CheckReg");
}
FindKeys(){
llOwnerSay("Finding Keys...");
llRegionSay(ServerComChannel, AskForKeys);
}
RegisterServer(string cmd){
if(cmd=="CheckReg"){
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("CheckReg")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", "USERDB"];
HTTPFLAG = "CheckReg";
HTTPRequestHandle = llHTTPRequest(URL, SendParams, ""); // Send Request to Server to Check and/or Register this Server
}
}
// Check key if any incoming request and validate against Security Key
integer SecurityCheck(key CheckID){
if(CheckID!=SecurityKey){
return FALSE;
}else{
return TRUE;
}
}
ToggleDebug(){
DebugMode = !DebugMode;
if(DebugMode){
llOwnerSay("Debug Mode ON!");
}else{
llOwnerSay("Debug Mode OFF!");
}
}
LightToggle(integer LinkID, integer ISON, string Color){
if(ISON){
vector ColorVector = llList2Vector(ONColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOn,
PRIM_FULLBRIGHT, ALL_SIDES, TRUE
]);
}else{
vector ColorVector = llList2Vector(OFFColorVectors, llListFindList(ColorNames, [Color]));
llSetLinkPrimitiveParamsFast(LinkID, [
PRIM_COLOR, ALL_SIDES, ColorVector, 1.0,
PRIM_GLOW, ALL_SIDES, GlowOff,
PRIM_FULLBRIGHT, ALL_SIDES, FALSE
]);
}
}
string GetUserData(){
dbIndex = 2;
string ReturnString = "";
for(dbIndex=2;dbIndex<=DBEntries;dbIndex++){
list CurrentLine = dbGet(dbIndex);
if(llList2String(CurrentLine, 0)==""){ return ReturnString; }
string CompiledString = llList2String(CurrentLine, 0)+"||"+llList2String(CurrentLine, 1)+"||"+llList2String(CurrentLine, 2)+"||"+llList2String(CurrentLine, 3)+"||"+llList2String(CurrentLine, 4)+"||"+llList2String(CurrentLine, 5)+"||"+llList2String(CurrentLine, 6)+",";
ReturnString = ReturnString + CompiledString;
}
return ReturnString;
}
// Main Program
default
{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
touch(integer num){
LightToggle(ACTLIGHT, TRUE, "Green");
TotalTouched = TotalTouched + num;
key WhoTouched = llDetectedKey(0);
if(TotalTouched>1){
return;
}
if(llListFindList(names, [osKey2Name(WhoTouched)])!= -1){
ToggleDebug();
llRegionSayTo(WhoTouched, 0, "Outputting DB Contents...");
dbIndex = 1;
for(dbIndex=1;dbIndex<=DBEntries;dbIndex++){
list CurrentLine = dbGet(dbIndex);
llRegionSayTo(WhoTouched, 0, "Played Users:\n" +
"UUID: " + llList2String(CurrentLine, 0) + "\n" +
"Name: " + llList2String(CurrentLine, 1) + "\n" +
"Played: " + llList2String(CurrentLine, 2) + "\n" +
"Won: " + llList2String(CurrentLine, 3) + "\n" +
"Spent: " + llList2String(CurrentLine, 4) + "\n" +
"Wins: " + llList2String(CurrentLine, 5) + "\n" +
"Loses: " + llList2String(CurrentLine, 6) + "\n");
}
}else{
llRegionSayTo(WhoTouched, 0, "You are not authorized!\nThis attempted violation has been reported!");
list SendList = [] + [SecurityKey] + ["INSERT"] + [(string)WhoTouched] + ["Un-Authd Touch of User DB"] + ["Un-Authorized Access attempt made to "+HoverTextString+"."];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
}
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
llSetTimerEvent(UploadTimer);
}
touch_end(integer num){
TotalTouched = 0;
}
listen(integer chan, string cmd, key id, string data){
LightToggle(ACTLIGHT, TRUE, "Green");
if(DebugMode){
llOwnerSay("Listen Event Fired:\nCommand: "+cmd+"\n"+"Data: "+data);
}
if(SecurityCheck(llList2Key(llParseString2List(data, "||", []), 0))==FALSE){ // If Device did not Send Security Key
if(DebugMode){
llOwnerSay("Un-Authorized Accept Attempt of "+HoverTextString+"!\rEvent Logged!");
}
list SendList = [] + [SecurityKey] + ["INSERT"] + ["Un-Authd Access to User DB"] + ["Un-Authorized Access attempt made to "+HoverTextString+"."] + [data];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
return;
}
if(chan==ServerComChannel){
cmd = llList2String(llParseStringKeepNulls(data, ["||"], []), CMD);
if(llList2String(llParseString2List(data, "||", ""), 0)==AskForKeys){
return;
}else if(cmd==AskForKeys){ // Read Configuration Data and Configure Script Parameters
GameServer = llList2String(llParseString2List(data, "||", ""), 2);
GameEventDBServer = llList2String(llParseString2List(data, "||", ""), 4);
BasePotAmt = llList2Integer(llParseString2List(data, "||", ""), 20);
UploadTimer = llList2Integer(llParseString2List(data, "||", ""), 21);
if(DebugMode){
llOwnerSay("Server UUID To Name Resolutions:\nGame Server: "+llKey2Name(GameServer)+"\nGame Event DB Server: "+llKey2Name(GameEventDBServer)+"\nBase JackPot Amount: "+(string)BasePotAmt+"\nUpload Timer: "+(string)UploadTimer);
}
// Get Authed Users from NC
nrofnamesoncard = llGetNumberOfNotecardLines("whitelist");
}
llListenRemove(ServerComHandle);
}
if(chan==DBComChannel ){
cmd = llList2String(llParseStringKeepNulls(data, ["||"], []), CMD);
if(DebugMode){
llOwnerSay("CMD: "+cmd);
}
if(cmd=="UPDATE"){
list InputData = llParseStringKeepNulls(data, ["||"], []);
if(DebugMode){ // If Debug Mode is TRUE
integer i; // Integer for Counting
for(i=0;i<=llGetListLength(InputData)-1;i++){ // Loop Based on List Length (Adjusted for 0 Offset)
llOwnerSay("Processed Input Line: "+(string)i+" "+llList2String(InputData, i)); // Print Each Value in the list
}
}
if(dbExists(["uuid", "==", llList2String(InputData, UUID)])){ // UUID Already Exists in DB so we Need to Extract Info and Update
if(DebugMode){ // IF Debug Mode output
llOwnerSay("User Found, Extracting Info for Update...");
}
list dbRow = dbGet(dbIndex); // Get Current Entry
string uuid = llList2String(dbRow, 0); // Extract UUID From Entry
string name = llList2String(dbRow, 1); // Extract Name From Entry
integer played = llList2Integer(dbRow, 2); // Extract Number of Times Played
played = played + llList2Integer(InputData, PLAYED); // Adjust Value by Input Amount
integer won = llList2Integer(dbRow, 3); // Extract Amount of P$ Won
won = won + llList2Integer(InputData, WON); // Adjust Value by Input Amount
integer spent = llList2Integer(dbRow, 4); // Extract Amount of P$ Spent
spent = spent + llList2Integer(InputData, SPENT); // Adjust Value by Input Amount
integer wins = llList2Integer(dbRow, 5); // Extract Number of Times Won
wins = wins + llList2Integer(InputData, WINS); // Adjust Value by Input Amount
integer loses = llList2Integer(dbRow, 6); // Extract Number of Times Lost
loses = loses + llList2Integer(InputData, LOSES); // Adjust Value by Input Amount
dbPut([uuid, name, played, won, spent, wins, loses]); // Update Entry
if(DebugMode){ // If Debug Output
llOwnerSay("Update Performed for UUID: "+uuid);
list newRow = dbGet(dbIndex);
llOwnerSay("New Record:\r
UUID: "+llList2String(newRow, 0)+"\r
Username: "+llList2String(newRow, 1)+"\r
Times Played: "+llList2String(newRow, 2)+"\r
P$ WON: "+llList2String(newRow, 3)+"\r
P$ SPENT: "+llList2String(newRow, 4)+"\r
Times Won: "+llList2String(newRow, 5)+"\r
Times Lost: "+llList2String(newRow, 6));
}
}else{ // User has not played since last off-world backup. Just Insert New Record
if(DebugMode){
llOwnerSay("Inserting New Record for UUID: "+llList2String(InputData, UUID));
}
dbInsert([
llList2String(InputData, UUID),
osKey2Name(llList2Key(InputData, UUID)),
llList2Integer(InputData, PLAYED),
llList2Integer(InputData, WON),
llList2Integer(InputData, SPENT),
llList2Integer(InputData, WINS),
llList2Integer(InputData, LOSES)
]);
DBEntries = DBEntries + 1;
}
}else if(cmd=="UPPOT"){
list InputData = llParseStringKeepNulls(data, ["||"], []);
if(dbExists(["uuid", "==", "UPPOT"])){ // Check for and Move Pointer to Pot Index (If DB Line Exists)
list dbRow = dbGet(dbIndex); // Get Row
integer NewPot = llList2Integer(dbRow, CMD) + llList2Integer(InputData, 2); // AdjustPot
dbPut(["UPPOT", (integer)NewPot, "0", "0", "0", "0", "0"]); // Place back into DB
if(DebugMode){
llOwnerSay("Pot Updated...");
list NewList = dbGet(dbIndex);
llOwnerSay(llDumpList2String(NewList, "||"));
return;
}
}
}else if(cmd=="CLRPOT"){
if(dbExists(["uuid", "==", "UPPOT"])){ // Check for and Move Pointer to Pot Index
list InputData = llParseStringKeepNulls(data, ["||"], []);
if(llList2Integer(InputData, 2)<BasePotAmt){
dbPut(["UPPOT", BasePotAmt, "0", "0", "0", "0", "0"]);
}else{
dbPut(["UPPOT", llList2Integer(InputData, 2), "0", "0", "0", "0", "0"]);
}
if(DebugMode){
llOwnerSay("Cleared pot by adjustment.");
}
}else{
dbInsert(["UPPOT", BasePotAmt, "0", "0", "0", "0", "0"]);
if(DebugMode){
llOwnerSay("Cleared pot by Insert");
}
}
}else if(cmd=="GetPot"){
integer dbIndexBKP = dbIndex;
dbIndex = DBEMPTY;
list JackPot = dbGet(dbIndex);
dbIndex = dbIndexBKP;
string SendString = "CurPot||"+llList2String(JackPot, 1);
if(DebugMode){
llOwnerSay("Sending GETPOT Response: "+SendString);
}
llRegionSayTo(id, chan, SendString);
}else if(cmd=="HRPOT"){ // If Hourly JackPot Server is Calling (Give i s List of Sorted Top Spenders and JackPot Total)
dbIndex = 1; // Set Database Inquiry Start Point
list UnSortedOutPut = []; // Prepare Output List
for(dbIndex=1;dbIndex<=DBEntries;dbIndex++){ // Loop for all DB Entires
list CurrentLine = dbGet(dbIndex); // Extract Current DB Entry into List
if(llList2String(CurrentLine, 0)!="UPPOT"){
UnSortedOutPut = UnSortedOutPut + [llList2String(CurrentLine, 4) + "~" + llList2String(CurrentLine, 0)]; // Extract Spent and UUID and Place into List
}else{
UnSortedOutPut = UnSortedOutPut + [llList2String(CurrentLine, 1) + "~" + llList2String(CurrentLine, 0)]; // Extract Spent and UUID and Place into List
}
}
list SortedOutPut = llListSort(UnSortedOutPut, 1, FALSE); // Sort the UnSortedOutPut and place into SortedOutPut
if(DebugMode){
llOwnerSay("\n\t\tList of Top Spenders:\r"+llDumpList2String(SortedOutPut, "||"));
}
string FormattedOutPut = llDumpList2String(SortedOutPut, "||");
llRegionSayTo(id, DBComChannel, SecurityKey+"||TOPLIST||"+FormattedOutPut);
dbIndex = DBEMPTY;
list JackPot = dbGet(dbIndex);
dbTruncate(DBName);
dbInsert(JackPot);
DBEntries = DBEMPTY;
}
}
llSleep(LightHoldLength);
LightToggle(ACTLIGHT, FALSE, "Green");
}
// Read Security Notecard
dataserver (key queryid, string data){
if (queryid == nrofnamesoncard) {
nrofnames = (integer) data;
integer i;
for (i=0;i < nrofnames;i++){
keynameoncard = keynameoncard + llGetNotecardLine("whitelist", i);
}
} else {
integer listlength;
listlength = llGetListLength(keynameoncard);
integer j = 0;
for(j=0;j<=listlength;j++) {
if(queryid == (key)llList2String(keynameoncard,j)){
if(data!=""){
if(DebugMode){
llOwnerSay("Authorized User: "+data);
}
names = names + data;
}else{
llOwnerSay("Security Turned Off.");
}
}
}
if(listlength==llGetListLength(names)){
llOwnerSay(DBName+" Server Online!");
llSetTimerEvent(UploadTimer);
}
}
}
// Server Response Catcher for Dumps and Initial Reg
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id != HTTPRequestHandle) return;// exit if unknown
LightToggle(ACTLIGHT, TRUE, "Green");
vector COLOR_BLUE = <0.0, 0.0, 1.0>;
float OPAQUE = 1.0;
llSetTimerEvent(UploadTimer);
list OutputData = llCSV2List(body); // Parse Response into List
string InputKey = llBase64ToString(llList2String(OutputData, 1));
string InputCMD = llBase64ToString(llList2String(OutputData, 0));
if(DebugMode){
llOwnerSay("Key: "+InputKey+"\nCMD: "+InputCMD+"\nMsg: "+body);
}
if(InputKey!=SecurityKey){
llOwnerSay("Invalid Security Key Received from RL Server!\r"+InputKey);
}else if(HTTPFLAG=="CheckReg"){
HTTPFLAG = "";
if(InputCMD=="ALRDYREGOK"){ // Server Already Registered
if(DebugMode){
llOwnerSay("Server Already Registered!");
}
}else if(InputCMD=="REGOK"){ // Server Successfully Registered
if(DebugMode){
llOwnerSay("Server Successfully Registered!");
}
}else if(InputCMD=="REGERR"){ // Error Registering Server with Off-World Database
llOwnerSay("Error Registering Server with Database!");
}else if(InputCMD=="CHECKERR"){ // Error Checking Database for Server Registration
llOwnerSay("Error Checking Database for Server Registration");
}else{
llOwnerSay("Response from server not reconignized!");
}
FindKeys();
}else if(HTTPFLAG=="UserDump"){
HTTPFLAG = "";
if(InputCMD=="DUMPEMPTY"){
if(DebugMode){
llOwnerSay("Server says Data dump was EMPTY!");
}
list SendList = [] + [SecurityKey] + ["INSERT"] + ["User DB Dump Was Empty!"] + ["Server Reponse Says Database dump was empty for DB: "+HoverTextString+"."];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
llSetTimerEvent(UploadTimer);
}else if(InputCMD=="DUMPOK"){
if(DebugMode){
llOwnerSay("Server Dump OK!");
}
list SendList = [] + [SecurityKey] + ["INSERT"] + ["User Database Dump Successfull!"] + ["Database dump successfull for DB: "+HoverTextString+"."];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, DBComChannel, SendString);
if(DebugMode){
llOwnerSay("Truncating Database...");
}
dbIndex = 1;
list JackPot = dbGet(dbIndex);
if(DebugMode){
llOwnerSay("JackPot Dump: "+llDumpList2String(JackPot, "||"));
}
dbTruncate(DBName);
dbInsert(JackPot);
DBEntries = 1;
llSetTimerEvent(UploadTimer);
}
}
LightToggle(ACTLIGHT, FALSE, "Green");
}
timer(){
LightToggle(ACTLIGHT, TRUE, "Green");
llSetTimerEvent(UploadTimer);
string DumpString = GetUserData();
string EncodedDumpString = llStringToBase64(DumpString);
string MessageBody = "data="+EncodedDumpString;
integer MessageBodyLength = llStringLength(MessageBody);
if(MessageBodyLength>15000){
// Send to Event Server that we missed Data on Upload due to Body OverSize.
// Adjust Timer to make next Call Quicker
UploadTimer = UploadTimer - 60; // Reduce Cycle Timer by 1 Minute
llSetTimerEvent(UploadTimer);
}
string CmdString = "?"+llStringToBase64("cmd")+"="+llStringToBase64("UserDump")+"&"+llStringToBase64("Key")+"="+llStringToBase64(SecurityKey);
if(DebugMode){
llOwnerSay("Send String: "+CmdString);
}
string URL = URLBase + CmdString;
list SendParams = HTTPRequestParams + ["ServerType", "USERDB"];
string PostBody = MessageBody;
HTTPFLAG = "UserDump";
HTTPRequestHandle = llHTTPRequest(URL, SendParams, PostBody); // Send Request to Server to Check and/or Register this Server
LightToggle(ACTLIGHT, FALSE, "Green");
}
}

601
Zuingo/Game Engine-v1.0.lsl Normal file
View File

@@ -0,0 +1,601 @@
// Number Grid Texture UUID
key texture = "fa16bd77-af56-4149-b9d4-75f6ceda8448";
key creatorKey;
float PotPercentage = 0.10;
float creatorPercentage = 0.01;
list lPay = ["P$5", "P$10", "P$25", "P$50", "P$75", "P$100", "P$250", "P$500", "P$750", "P$1000"];
vector lineColor = <1.0, 0.0, 0.0>;
list lMummy = [0.20, 0.30, 0.40, 0.50];
integer TotalNumbers = 25;
integer totalRounds = 5;
integer roundTime = 25;
integer pointsSingleField = 200;
integer pointsLine = 1000;
integer pointsBlues = 5000;
integer pointsAll = 10000;
integer pointsCash = 1000;
integer pointsPharao = 1000;
integer EMPTY = 1;
integer FILLED = 2;
integer CASH = 4;
integer DOUBLE = 8;
integer BLUE = 16;
//string cmdFloatText = "FloatText";
string cmdConfig = "Admin";
string cmdFloatOn = "Float ON";
string cmdFloatOff = "Float OFF";
string cmdTimeOn = "Time ON";
string cmdCurrentOn = "Current ON";
string cmdCurrentOff = "Current OFF";
string cmdTimeOff = "Time OFF";
string cmdPrevOn = "Prev ON";
string cmdPrevOff = "Prev OFF";
string cmdFreeYes = "Free YES";
string cmdFreeNo = "Free NO";
string cmdFreeOnly = "Free Only";
string cmdOn = "ON";
string cmdOff = "OFF";
string cmdDebug = "Debug Toggle";
//string cmdStatistics = "Statistics";
string cmdResetStats = "Reset Machine";
string cmdFreePlay = "FreePlay";
string cmdNote = "Help";
list lNumbers;
list lFields;
integer iBlues;
integer bCheckAll;
integer bCheckBlues;
integer iPoints = 0;
integer bCash = TRUE;
integer bDouble = FALSE;
integer bGame = TRUE;
integer freePlay = 0;
integer dialogChannel;
integer playing = FALSE;
key player;
string gameValueName;
key GameServer = "f77c9eb4-4d0a-48a3-8157-613b9f8342a7"; // UUID of Game Server Prim in Server Cabinet
key SecurityKey = "3d7b1a28-f547-4d10-8924-7a2b771739f4"; // Security Key for Secure Communication. Currently my UUID
key GameEventDBServer = "508e0211-5cfe-4bda-acbe-8576b02dc00e"; // UUID of Game Event Logger Database Server
key GameDBServer = "5d9b8231-ed73-4aa5-b3c8-a7b0a88b1aa6"; // UUID of Game Database Server in Server Cabinet
integer ServerComChannel = -63473672; // Game Server Communication Channel
integer EventDBServerComChannel = -260002; // Game Event Database Server Communication Channel
integer ServerComHandle;
list RoundLengthList = [];
integer DebugMode = FALSE;
string AskForKeys = "TheKeyIs(Mq=h/c2)";
list AdminMenuUsers = [];
string DiagMode;
list ssCreateMenu(string menu) {
if (menu == "main") return [cmdConfig];
//if (menu == cmdFloatText) return [cmdFloatOn, cmdFloatOff, cmdTimeOn, cmdCurrentOn, cmdCurrentOff, cmdTimeOff, cmdPrevOn, cmdPrevOff];
if (menu == cmdConfig) return [cmdFreeYes, cmdFreeNo, cmdFreeOnly, cmdOff, cmdDebug, cmdResetStats];
if (menu == "pay") {
if (freePlay == 0) return order_buttons(lPay + [cmdNote]);
if (freePlay == 1) return order_buttons([cmdFreePlay] + lPay + [cmdNote]);
if (freePlay == 2) return [cmdFreePlay, cmdNote];
}
return [];
}
list order_buttons(list buttons) { //From the wiki By Redux
integer offset;
list fixt;
while((offset = llGetListLength(buttons))) {
offset = -3 * (offset > 3);
fixt = fixt + llList2List(buttons, offset, -1);
// fixt += llList2List(buttons, offset = -3 * (offset > 3), -1);
buttons = llDeleteSubList(buttons, offset, -1);
}
return fixt;
}
integer ssRandomChannel() {
integer n = llRound(llFrand(-1 * (DEBUG_CHANNEL - 1)));
if (n > -1000)
return ssRandomChannel();
else
return n;
}
ssGenerateNumbers() {
bDouble = FALSE;
llMessageLinked(LINK_ALL_OTHERS, totalRounds, "totalRounds", NULL_KEY);
llSleep(0.1);
llMessageLinked(LINK_ALL_OTHERS, roundTime, "roundTime", NULL_KEY);
bCheckBlues = bCheckAll = TRUE;
iPoints = 0;
integer num;
lNumbers = lFields = [];
integer blue = 1;
integer double;
integer cash;
// find 2x
double = (integer)llFrand(TotalNumbers);
if (bCash = !bCash) { // find cash
do {
cash = (integer)llFrand(TotalNumbers);
} while (cash == double);
}
while (num < 25) {
integer fieldValue = EMPTY;
vector offset = ZERO_VECTOR;
integer random;
integer isBlue = FALSE;
integer extra = (num / 5) * 15;
if (iBlues & blue) {
fieldValue = fieldValue + BLUE;
isBlue = TRUE;
}
blue = blue << 1;
do {
random = extra + (integer)llFrand(DEBUG_CHANNEL) % 15;
} while (llListFindList(lNumbers, (list)random) != -1);
lNumbers = lNumbers + random;
llMessageLinked(
LINK_ALL_OTHERS
, num
, llDumpList2String(["startGame", (string)random, (string)isBlue], "~~")
, player
);
if (num == double) fieldValue += DOUBLE;
if (bCash && num == cash) fieldValue += CASH;
lFields += fieldValue;
++num;
}
llMessageLinked(LINK_ALL_OTHERS, -1, "startGame", player);
}
integer ssCheckLines(integer num) {
integer i;
integer points = 0;
integer n = 0;
list lined = [];
string say;
//Horizontal check
while (n < 5) {
i = (num % 5) + n * 5;
if (llList2Integer(lFields, i) & EMPTY) jump away1;
++n;
}
n = -1;
while(++n < 5) {
integer x = ((num % 5) + n * 5);
if (llListFindList(lined, (list)x) == -1) lined += x;
}
points = points + pointsLine;
@away1;
//Vertical check
n = 0;
while (n < 5) {
i = (num / 5) * 5 + n;
if (llList2Integer(lFields, i) & EMPTY) jump away2;
++n;
}
n = -1;
while(++n < 5) {
integer x = ((num / 5) * 5 + n);
if (llListFindList(lined, (list)x) == -1) lined += x;
}
points = points + pointsLine;
@away2;
//Diagonal -> \
n = 0;
if (num % 6 == 0) {
while (n < 5) {
i = 6 * n;
if (llList2Integer(lFields, i) & EMPTY) jump away3;
++n;
}
n = -1;
while(++n < 5) {
integer x = (6 * n);
if (llListFindList(lined, (list)x) == -1) lined += x;
}
points = points + pointsLine;
}
@away3;
//Diagonal -> /
n = 0;
if (num && num % 4 == 0 && num < 24) {
while (n < 5) {
++n;
i = 4 * n;
if (llList2Integer(lFields, i) & EMPTY) jump away4;
}
n = -1;
while(++n < 5) {
integer x = (4 * n + 4);
if (llListFindList(lined, (list)x) == -1) lined += x;
}
points = points + pointsLine;
}
@away4;
//check blue fields
n = 0;
if (bCheckBlues) {
while(n < 25) {
integer test = llList2Integer(lFields, n);
if ((test & BLUE) && (test & EMPTY)) jump away5;
++n;
}
bCheckBlues = FALSE;
points = points + pointsBlues;
say = "Hurray! You filled the pattern! " + (string)pointsBlues + " extra points!";
if (bDouble) say = "Hurray! You filled the pattern! " + (string)(pointsBlues * 2) + " extra points!";
llWhisper(0, say);
}
@away5;
//check if all numbers are filled
n = 0;
if (bCheckAll) {
while(n < 25) {
if (llList2Integer(lFields, n) & EMPTY) jump away6;
++n;
}
bCheckAll = FALSE;
points = points + pointsAll;
say = "Hurray! You found all numbers! " + (string)pointsAll + " extra points!";
if (bDouble) say = "Hurray! You found all numbers! " +(string)(pointsAll * 2) + " extra points!";
llWhisper(0, say);
llMessageLinked(LINK_THIS, 0, "gameOver", "");
}
@away6;
integer total = lined != [];
n = -1;
while(++n < total)
llMessageLinked(LINK_SET, llList2Integer(lined, n), "line", (string)lineColor);
return points;
}
default {
state_entry() {
creatorKey = llGetCreator();
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
llListenRemove(ServerComHandle);
ServerComHandle = llListen(ServerComChannel, "", "", "");
if(DebugMode){
llOwnerSay("Booted Main Script");
}
//llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
run_time_permissions(integer perm){
if(PERMISSION_DEBIT & perm){
llRegionSay(ServerComChannel, AskForKeys);
}
}
listen(integer chan, string name, key id, string msg){
if(DebugMode){
llOwnerSay("Listen Msg: "+msg);
}
if(llList2String(llParseString2List(msg, "||", ""), 1)==AskForKeys){
list NewKeys = llParseString2List(msg, "||", "");
if(llList2String(NewKeys, 0)!=SecurityKey){
if(DebugMode){
llOwnerSay("Invalid Security Key Received during SERVER Key Update!");
}
return;
}
// UUIDS of Game Servers
GameServer = llList2Key(NewKeys, 2);
GameDBServer = llList2Key(NewKeys, 3);
GameEventDBServer = llList2Key(NewKeys, 4);
// Game Configuration Directives
lMummy = llList2List(NewKeys, 5, 8);
roundTime = llList2Integer(NewKeys, 9);
pointsSingleField = llList2Integer(NewKeys, 10);
pointsLine = llList2Integer(NewKeys, 11);
pointsBlues = llList2Integer(NewKeys, 12);
pointsAll = llList2Integer(NewKeys, 13);
pointsCash = llList2Integer(NewKeys, 14);
pointsPharao = llList2Integer(NewKeys, 15);
PotPercentage = llList2Float(NewKeys, 16) / 100;
DiagMode = llList2String(NewKeys, 17);
if(
llGetListLength(lMummy)>0 &&
roundTime>0 &&
pointsSingleField>0 &&
pointsLine>0 &&
pointsBlues>0 &&
pointsAll>0 &&
pointsCash>0 &&
pointsPharao>0 &&
PotPercentage>0
){
llOwnerSay("Game Configured!");
if(DiagMode=="TRUE"){
llOwnerSay("Diagnostic Mode Active!");
}
}else{
llOwnerSay("Game Configureation ERROR!");
}
integer i;
list TempList = llList2List(NewKeys, 24, -1);
if(DebugMode){
llOwnerSay("Loading Admin Menu Users...");
}
for(i=0;i<llGetListLength(TempList);i++){ // For all Keys in string beyond 4 include as Authd Users
integer SpaceIndex = llSubStringIndex(llList2String(TempList, i), " ");
string FName = llGetSubString(llList2String(TempList, i), 0, SpaceIndex-1);
string LName = llGetSubString(llList2String(TempList, i), SpaceIndex+1, -1);
key theirkey = osAvatarName2Key(FName, LName);
AdminMenuUsers = AdminMenuUsers + [theirkey];
if(DebugMode){
llOwnerSay("\nFirst Name: "+FName+"\nLast Name: "+LName+"\nTheir Key: "+theirkey);
}
}
if(DebugMode){
llOwnerSay("Server Key Update Complete!\rGame Server: "+(string)GameServer+"\rGameDBServer: "+(string)GameDBServer+"\rGameEventDBServer: "+(string)GameEventDBServer);
}
llRegionSayTo(GameServer, ServerComChannel, "GetRoundLengths");
return;
}else if(llList2String(llParseString2List(msg, "||", ""), 0)==AskForKeys){
return;
}
list Inputs = llParseString2List(msg, "||", "");
if(llList2Key(Inputs, 0)!=SecurityKey){
list SendList = [SecurityKey, "INSERT", id, "Un-Authorized Access Attempt!", "Machine ID: "+llGetObjectDesc(), msg];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, EventDBServerComChannel, SendString);
return;
}
if(llList2Integer(Inputs, 1)<50){
llSetText("Configured!\n Waiting for Stats...", <1.0,1.0,1.0>, 1.0);
RoundLengthList = [] + [llList2Integer(Inputs, 1), llList2Integer(Inputs, 2), llList2Integer(Inputs, 3), llList2Integer(Inputs, 4), llList2Integer(Inputs, 5), llList2Integer(Inputs, 6), llList2Integer(Inputs, 7), llList2Integer(Inputs, 8), llList2Integer(Inputs, 9), llList2Integer(Inputs, 10)];
state Ready;
}
}
state_exit(){
llListenRemove(ServerComHandle);
}
}
state Ready {
state_entry() {
llOwnerSay("State Ready");
//llSetText("", <1,1,1>, 0.0);
llSetClickAction(CLICK_ACTION_TOUCH);
llMessageLinked(LINK_SET, -1, "setTexture", texture);
dialogChannel = ssRandomChannel();
llListen(dialogChannel, "", NULL_KEY, "");
llSetPayPrice(PAY_HIDE, [PAY_HIDE, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
}
touch_start(integer n) {
if (!playing) {
key id = llDetectedKey(0);
// Calls User Menu to Select Game Cost
if (bGame) llDialog(id, "Game price:", ssCreateMenu("pay"), dialogChannel);
// Calls Admin Menu
if (llListFindList(AdminMenuUsers, [id])!=-1) {
llSleep(2.0);
llDialog(id, "Admin menu:", ssCreateMenu("main"), dialogChannel);
}
}
}
listen(integer channel, string name, key id, string message) {
if (channel == dialogChannel) { // Listen for Dialog Response
if (id == llGetOwner()) { // If Owner is using Menu
if (message == cmdConfig) {llDialog(id, "Config menu:", ssCreateMenu(message), dialogChannel); return;} // Show Config Menu
//if (message == cmdFloatText) {llDialog(id, "Floating Text menu:", ssCreateMenu(message), dialogChannel); return;} // Show FloatText Menu
if (message == cmdFreeNo) { // Disables Free Play Option
freePlay = 0;
llOwnerSay("FreePlay disabled.");
return;
}
if (message == cmdFreeYes) { // Enables Free Play Option
freePlay = 1;
llOwnerSay("FreePlay enabled.");
return;
}
if (message == cmdFreeOnly) { // Makes game ONLY Free to Play
freePlay = 2;
llOwnerSay("FreePlay only.");
return;
}
if (message == cmdOn) { // Turns System On
bGame = TRUE;
llSetText("Game Ready!\nClick MENU to select Price!", <1.0, 1.0, 1.0>, 1.0);
return;
}
if (message == cmdOff) { // Turns System Off
bGame = FALSE;
llSetText("Game Offline!", <1.0, 0,0>, 1.0);
llMessageLinked(LINK_SET, -1, "stopGame", NULL_KEY);
return;
}
if(message == cmdDebug) {
if(DebugMode){
DebugMode = FALSE;
llMessageLinked(LINK_THIS, -34, "debugOFF", NULL_KEY);
}else{
DebugMode = TRUE;
llMessageLinked(LINK_THIS, -34, "debugON", NULL_KEY);
}
}
if(message==cmdResetStats){
bGame = FALSE;
if(DebugMode){
llOwnerSay("Rebooting Machine...");
}
llMessageLinked(LINK_SET, -420, "stopGame", NULL_KEY);
llSleep(1.0);
llMessageLinked(LINK_SET, -420, "Reboot", NULL_KEY);
string ScriptName = llGetScriptName(); // Get Current Script
integer ScriptTotal = llGetInventoryNumber(INVENTORY_SCRIPT); // Get Total Number of Scripts in Inventory
integer i;
for(i=0;i<ScriptTotal;i++){
if(llGetInventoryName(INVENTORY_SCRIPT, i)!=ScriptName){
llResetOtherScript(llGetInventoryName(INVENTORY_SCRIPT, i));
}
}
llResetScript();
}
}
// GAME START POINT!!!!
if (!playing) { // If No Game is in Session
if (message == cmdNote) {llGiveInventory(id, llGetInventoryName(INVENTORY_NOTECARD, 0)); return;} // Send First Notecard in Object
if (message == cmdFreePlay) { // If we received a request to start a FreePlayGame
player = id;
llSetPayPrice(PAY_HIDE, [PAY_HIDE, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
llSetClickAction(CLICK_ACTION_TOUCH);
gameValueName = message; // gameValueName Now Equals "FreePlay"
llMessageLinked(LINK_ALL_OTHERS, -1, "setPicture", gameValueName);
llMessageLinked(LINK_SET, -1, "gameValue", gameValueName);
llMessageLinked(LINK_THIS, 0, "getblues", id);
playing = TRUE; // Set game to Playing True State
llWhisper(0, gameValueName + " game starts now."); // Tell User Game is Starting
return;
}
if (llListFindList(lPay, (list)message) != -1) { // If Price of Game Requested is an Option in the lPay List
llSetClickAction(CLICK_ACTION_PAY);
integer GameTypeIndex = llListFindList(lPay, (list)message);
totalRounds = llList2Integer(RoundLengthList, GameTypeIndex);
if(DebugMode){
llOwnerSay("Total Rounds: "+(string)totalRounds);
}
llMessageLinked(LINK_ALL_OTHERS, -1, "setPicture", message);
llSetPayPrice(PAY_HIDE, [(integer)llGetSubString(message, 2, -1), PAY_HIDE, PAY_HIDE, PAY_HIDE]);
llWhisper(0, "You have 10 seconds to pay the game!");
gameValueName = message; // gameValueName Now Equals P$ 5 (Or What ever was selected from menu)
llSetTimerEvent(10.0); // Increased from 5.0 to 10.0 By Tech Guy (Time to Pay Machine TimeOut)
return;
}
}
}
}
money(key id, integer amount) { // Money Paid Into Game
if (!playing) { // We are not playing the game
if(DiagMode=="TRUE"){ // If we are in Diagnostic Mode (Give Any Paid Money Back Right Away)
llRegionSayTo(id, 0, "Diagnostic Mode Enabled! Returning your money, You can NOT win any money either!");
llSleep(0.5);
llSay(0, "Returning...");
llGiveMoney(id, amount);
}
player = id;
llSetPayPrice(PAY_HIDE, [PAY_HIDE, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
llSetClickAction(CLICK_ACTION_TOUCH);
llWhisper(0, gameValueName + " game starts now.");
llMessageLinked(LINK_SET, -1, "gameValue", gameValueName);
llMessageLinked(LINK_THIS, 0, "getblues", id);
playing = TRUE;
integer ToPot = (integer)(amount * PotPercentage);
// Update Pot Amount in Local Game Server DB
list SendList = [] + SecurityKey + ["UPPOT"] + (list)ToPot; // Create List to be Parsed to String
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameDBServer, EventDBServerComChannel, SendString);
}
}
link_message(integer sender, integer num, string msg, key id) {
integer iCurrentPoints;
string text = "";
if (msg == "setblues") {
iBlues = num;
ssGenerateNumbers();
} else if (msg == "useNumber") {
integer n = llList2Integer(lFields, num);
if (n & EMPTY) {
iCurrentPoints += pointsSingleField;
lFields = [] + llListReplaceList(lFields, (list)((n & ~EMPTY) | FILLED), num, num);
} if (n & CASH) {
text = "You got "+(string)pointsCash+" extra points!";
iCurrentPoints += pointsCash;
lFields = [] + llListReplaceList(lFields, (list)((n & ~EMPTY) | FILLED), num, num);
llMessageLinked(LINK_SET, num, "setTextureCash", NULL_KEY);
} if (n & DOUBLE) {
text = "Double Points!!\nAll your points will now be doubled!";
bDouble = TRUE;
lFields = [] + llListReplaceList(lFields, (list)((n & ~EMPTY) | FILLED), num, num);
llMessageLinked(LINK_SET, num, "setTexture2x", NULL_KEY);
}
iCurrentPoints = iCurrentPoints + ssCheckLines(num);
} else if (msg == "pharao") {
iCurrentPoints = iCurrentPoints + pointsPharao;
} else if (msg == "mummy") {
if (iPoints) {
integer total = lMummy != [];
float perc = llList2Float(lMummy, (integer)llFrand(total));
integer end = (integer)(iPoints * perc);
llWhisper(0, "Ouch! The you lost " + (string)((integer)(perc * 100)) + "% of your score!");
if (end) iPoints -= end;
}
} else if (msg == "gameOver") { // Received gameOver from randomBar
playing = FALSE;
llMessageLinked(LINK_THIS, -123, llDumpList2String([
"gameReview",
gameValueName,
(string)iPoints], "||"),
player);
llWhisper(0, gameValueName + " game over!");
//iPoints = 0;
gameValueName = "";
player = NULL_KEY;
}
if (bDouble) { //2x
iCurrentPoints = iCurrentPoints * 2;
}
iPoints = iPoints + iCurrentPoints;
llMessageLinked(4, iPoints, "playerPoints", NULL_KEY);
//llSetText("Points: " + (string), <1,1,1>, 1);
if (text != "") llWhisper(0, text);
}
timer() {
llSetTimerEvent(0.0);
llSetPayPrice(PAY_HIDE, [PAY_HIDE, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
llSetClickAction(CLICK_ACTION_TOUCH);
}
on_rez(integer p) {
llResetScript();
}
changed(integer c) {
if (c & CHANGED_OWNER) llResetScript();
}
}

View File

@@ -0,0 +1,191 @@
float requestTime = 60.0;
list values;
list names;
list scores;
list prizes;
list rounds;
list multipliers;
integer status;
// Key of Game Server
key GameServer = "5b8c8de4-e142-4905-a28f-d4d00607d3e9"; // UUID of Game Server Prim in Server Cabinet
key GameDBServer = "b9dbc6a4-2ac3-4313-9a7f-7bd1e11edf78"; // UUID of Game Database Server in Cabinet
key GameEventDBServer = "dbfa0843-7f7f-4ced-83f6-33223ae57639"; // UUID of Game Event Logger Database Server
key SecurityKey = "3d7b1a28-f547-4d10-8924-7a2b771739f4"; // Security Key for Secure Communication. Currently my UUID
integer ServerComChannel = -13546788; // Game Server Communication Channel
integer EventDBServerComChannel = -260046; // Game Event Database Server Communication Channel
integer ComHandle;
string EMPTY = "";
string RequestFlag = "";
string NextPot = "";
integer DebugMode = FALSE;
integer Playing = FALSE;
integer bGame = TRUE;
string AskForKeys = "TheKeyIs(Mq=h/c2)";
string DiagMode;
default {
state_entry() {
llSleep(10.0);
llSetText("Relay Loading...", <1,1,1>, 1.0);
llListenRemove(ComHandle);
llSleep(0.1);
ComHandle = llListen(ServerComChannel, EMPTY, EMPTY, EMPTY);
requestTime = 300.0 - llFrand(200.00); // How often does the Server Relay Call GS for Updates
if(DebugMode){
llOwnerSay("Request Time: "+(string)requestTime);
}
llSleep(1.0);
llRegionSay(ServerComChannel, AskForKeys);
}
timer() {
llSetTimerEvent(requestTime);
ComHandle = llListen(ServerComChannel, EMPTY, EMPTY, EMPTY);
if (status = !status) {
// Get HighScores from Server
RequestFlag = "HighScores";
if(DebugMode){
llOwnerSay("Requesting High Scores...");
}
llRegionSayTo(GameServer, ServerComChannel, "GetHighScores");
} else {
RequestFlag = "PotTimer";
if(DebugMode){
llOwnerSay("Requesting JackPot Timer...");
}
llRegionSayTo(GameServer, ServerComChannel, "GetPotTimeOut");
}
}
run_time_permissions(integer p) {
if (p & PERMISSION_DEBIT){
llSetTimerEvent(0.01);
}else{
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
}
listen(integer chan, string sender, key id, string msg){ // Listen for REsponses from REquests to Server for HighScores and Pot Timeouts
list Inputs = llParseString2List(msg, "||", "");
if(llList2Key(Inputs, 0)!=SecurityKey && llList2Key(Inputs, 0)!=AskForKeys){ // If Security Key was Not Included as For Key in String Return
list SendList = [SecurityKey, "INSERT", id, "Un-Authorized Access Attempt!", "Machine ID: "+llGetObjectDesc(), msg];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameEventDBServer, EventDBServerComChannel, SendString);
if(DebugMode){
llOwnerSay("Security Invalid for Listen Event!");
}
llListenRemove(ComHandle);
return;
}else if(llList2Key(Inputs, 0)==AskForKeys){
return;
}
if(llList2String(llParseString2List(msg, "||", ""), 1)==AskForKeys){
list NewKeys = llParseString2List(msg, "||", "");
GameServer = llList2Key(NewKeys, 2);
GameDBServer = llList2Key(NewKeys, 3);
GameEventDBServer = llList2Key(NewKeys, 4);
DiagMode = llList2String(NewKeys, 17);
if(DebugMode){
llOwnerSay("Server Key Update Complete!");
}
llListenRemove(ComHandle);
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
return;
}
if(chan==ServerComChannel){ // Coming in on Current Channel
if(RequestFlag=="HighScores"){ // If REquest we are expecting is HighScores
RequestFlag = "";
scores = [] + llList2List(Inputs, 1, 10);
values = [] + llList2List(Inputs, 11, 20);
prizes = [] + llList2List(Inputs, 21, 30);
multipliers = [] + llList2List(Inputs, 31, 40);
if(!Playing && bGame){
llSetText("Game Ready!\nClick MENU to select Price!", <1.0,1.0,1.0>, 1.0);
}
if(DebugMode){
llOwnerSay("High Scores Obtained!");
}
llListenRemove(ComHandle);
}else if(RequestFlag=="PotTimer"){
RequestFlag = "";
if(DebugMode){
llOwnerSay("Pot Timer Obtained!");
}
NextPot = llList2String(llParseString2List(msg, "||", []), 1); // Set Next Time in IOT that Pot will be given out.
llListenRemove(ComHandle);
}
}
}
// Receive and Process Link Messages
link_message(integer sender, integer num, string message, key id) {
if(message=="stopGame"){
bGame = FALSE;
llSetTimerEvent(0);
return;
}else if(message=="OFF"){
bGame = FALSE;
llSetTimerEvent(0);
return;
}
if(message=="debugON"){
DebugMode = TRUE;
llOwnerSay("Debug Mode: TRUE");
}else if(message=="debugOFF"){
DebugMode = FALSE;
llOwnerSay("Debug Mode: FALSE");
}
if (message == "gameValue") { // Received Notification of New Game Value (FreePlay or L$ 5 E.T.C)
string value = llStringTrim((string)id, STRING_TRIM); // Trim String
integer found = llListFindList(values, (list)value); // Check if it exists in Values List of Possible Game Costs
if(value=="FreePlay"){
found = 0;
}
if (found == -1) return; // If not found return (No Further Processing)
// There is as List Index Association between Scores List and Values List Both obtaind during HTTP Response in this Script Line 50
// Send Link Message to SetScoreAndPot (Including the Values for Score to Beat and Pot
Playing = TRUE;
if(DebugMode){
llOwnerSay("Setting Pot and Score to Beat!");
}
llMessageLinked(LINK_ALL_OTHERS, -1 * llList2Integer(scores, found), "setScoreAndPot", (key)llList2String(prizes, found));
return;
}
list data = llParseString2List(message, (list)"||", []);
string cmd = llList2String(data, 0);
string value1 = llList2String(data, 1);
string highscore = llList2String(data, 2);
float multiplier = llList2Float(multipliers, llListFindList(values, (list)value1));
string playerName = llKey2Name(id);
string playerKey = (string)id;
if (cmd == "gameReview") { // Game is Over we are reviewing if the person won
Playing = FALSE;
integer find = llListFindList(values, (list)value1); // Find Index of Game Value (Sent for review) in list of Valid Game Values
if (find != -1) { // If We are reviewing a valid game value type
if ((integer)highscore > llList2Integer(scores, find)) { // If user has beaten the HighScore for the current gameValue
integer MoneyPaid = (integer)llGetSubString(value1, 2, -1);
integer MoneyWon = llRound((float)MoneyPaid * multiplier);
llSay(0, "You Won!\nYou Paid: "+value1+"\nGame Multiplier: "+(string)multiplier+"\nYou Won: P$"+MoneyWon+"\nYou Have gained an entry in the JackPot\nThe Jackpot will payout in approx "+NextPot+" minutes");
if(DiagMode=="FALSE" || DiagMode==""){ // If we are not in Diagnostic Mode, Allow PayOut
llGiveMoney(playerKey, MoneyWon);
}else{ // If We are in Diag Mode, Print Message to Player
llRegionSayTo(playerKey, 0, "Diag Mode Active. Nothing Paid Out!");
}
// Log in Event Server and Update Their Entry in User Database
list SendList = [] + SecurityKey + ["UPDATE"] + [playerKey, "", "1", MoneyWon, MoneyPaid, "1", "0" ];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameDBServer, EventDBServerComChannel, SendString);
}else{
integer MoneyPaid = (integer)llGetSubString(value1, 2, -1);
llSay(0, "Game Over!!, Better Luck Next Time!\n You have gained an entry in the JackPot!\nThe Jackpot will payout in approx "+NextPot+" minutes");
// Log in Event Server and Update Their Entry in User Database
list SendList = [] + SecurityKey + ["UPDATE"] + [playerKey, "", "1", "0", MoneyPaid, "0", "1" ];
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(GameDBServer, EventDBServerComChannel, SendString);
}
}
}
}
}

433
Zuingo/Loti/LOTI Engine.lsl Normal file
View File

@@ -0,0 +1,433 @@
// Default Program FrameWork
/*
Replace this Section with Program Specific Information
*/
// Created by Tech Guy of IO
// Configuration Directives
/* This Section Contains Configuration Variables that will contain data set by reading the notecard specified by ConfigFile Variable */
// Communication Channels
integer MenuComChannel; // Menu Communications Channel for All User Dialog Communications
integer ComChannel; // General Communication Channel for Inter-Device Communication
integer ServerComChannel = -63473680;
integer DBComChannel = -270000;
integer ScannerComChannel = -19000;
// System Variables
/* This Section contains variables that will be used throughout the program. */
// Admin ACL
list Admins = []; // List of Administrator Keys Read in from ConfigFile
// Communication Handles
integer MenuComHandle; // Menu Communications Handle
integer ComHandle; // General Communications Handle
integer ServerComHandle;
integer DBComHandle;
integer ScannerComHandle;
// Config Card Reading Variables
integer cLine; // Holds Configuration Line Index for Loading Config Loop
key cQueryID; // Holds Current Configuration File Line during Loading LooP
// Server Keys
key ConfigServerKey = NULL_KEY;
key EventServerKey = NULL_KEY;
key UserDBServerKey = NULL_KEY;
key JackPotServerKey = NULL_KEY;
// Server Received Configuration Directives
string DiagMode; // Does the Game PayOut on Win? ie: Diag Mode
integer HighScore;
integer PlayCost = 50;
key Player; // Currently Playing User
integer Score = 0; // Current Score (The Running Score to be compared with HighScore)
integer RoundTimer;
float PotPercent; // Current Percent of Pay to Send to JackPot Server
integer PayOutMultiplier;
integer MaxRounds;
// System Constants
/* This Section contains constants used throughout the program */
string BootMessage = "Booting..."; // Default/Initial Boot Message
string ConfigFile = ".config"; // Name of Configuration File
key SecurityKey = "3d7b1a28-f547-4d10-8924-7a2b771739f4"; // Security Communications Key
string SecureRequest = "TheKeyIs(Mq=h/c2)";
string EMPTY = "";
string AdminMenuMessage = "Admin Menu:\n\tReboot: Re-Configure Machine.";
list AdminMenu = ["Reboot", "Exit Menu"];
// Color Vectors
list colorsVectors = [<0.000, 0.455, 0.851>, <0.498, 0.859, 1.000>, <0.224, 0.800, 0.800>, <0.239, 0.600, 0.439>, <0.180, 0.800, 0.251>, <0.004, 1.000, 0.439>, <1.000, 0.522, 0.106>, <1.000, 0.255, 0.212>, <0.522, 0.078, 0.294>, <0.941, 0.071, 0.745>, <0.694, 0.051, 0.788>, <1.000, 1.000, 1.000>];
// List of Names for Colors
list colors = ["BLUE", "AQUA", "TEAL", "OLIVE", "GREEN", "LIME", "ORANGE", "RED", "MAROON", "FUCHSIA", "PURPLE", "WHITE"];
// System Switches
/* This Section contains variables representing switches (integer(binary) yes/no) or modes (string "modename" */
// Debug Mode Swtich
integer DebugMode = FALSE; // Is Debug Mode Enabled before Reading Obtaining Configuation Information
string OPFLAG = "";
// Imported Functions
/* This section contains any functions that were not written by Tech Guy */
// Home-Brew Functions
/* This section contains any functions that were written by Tech Guy */
// Debug Message Function
DebugMessage(string msg){
if(DebugMode){
llOwnerSay(msg);
}
}
// Send Any User a Message
SendMessage(string msg, key userid){
if(userid=="NULL_KEY" || userid==""){
//llSay(0, msg);
llRegionSay(0, msg);
}else if(msg!="" && userid!=NULL_KEY){
//llInstantMessage(userid, msg);
llRegionSayTo(userid, 0, msg);
}else{
DebugMessage("Error Sending User Message: "+msg);
}
}
// Main Initialization Logic, Executed Once Upon Script Start
Initialize(){
SendMessage(BootMessage, llGetOwner()); // State Booting Message
MenuComChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0); // Randomize Dialog Com Channel
SendMessage("Configuring...", llGetOwner()); // Message Owner that we are starting the Configure Loop
cQueryID = llGetNotecardLine(ConfigFile, cLine); // Start the Read from Config Notecard
}
// System has started Function (Runs After Configuration is Loaded, as a result of EOF)
SystemStart(){
SendMessage("Connecting to Server...", llGetOwner());
OPFLAG = "MAINCONFIG";
GetConfiguration();
}
// Add Admin (Add provided Legacy Name to Admins List after extrapolating userKey)
AddAdmin(string LegacyName){
string FName = llList2String(llParseString2List(LegacyName, [" "], []), 0);
string LName = llList2String(llParseString2List(LegacyName, [" "], []), 1);
DebugMessage("First Name: "+FName+" Last Name: "+LName);
key UserKey = osAvatarName2Key(FName, LName);
if(UserKey!=NULL_KEY){
Admins = Admins + UserKey;
DebugMessage("Added Admin: "+LegacyName);
}else{
DebugMessage("Unable to Resolve: "+LegacyName);
}
}
// Configuration Directives Processor (Called Each Time a Line is Found in the config File)
LoadConfig(string data){
if(data!=""){ // If Line is not Empty
// if the line does not begin with a comment
if(llSubStringIndex(data, "#") != 0)
{
// find first equal sign
integer i = llSubStringIndex(data, "=");
// if line contains equal sign
if(i != -1){
// get name of name/value pair
string name = llGetSubString(data, 0, i - 1);
// get value of name/value pair
string value = llGetSubString(data, i + 1, -1);
// trim name
list temp = llParseString2List(name, [" "], []);
name = llDumpList2String(temp, " ");
// make name lowercase
name = llToLower(name);
// trim value
temp = llParseString2List(value, [" "], []);
value = llDumpList2String(temp, " ");
// Check Key/Value Pairs and Set Switches and Lists
if(name=="debugmode"){ // Check DeBug Mode
if(value=="TRUE" || value=="true"){
DebugMode = TRUE;
llOwnerSay("Debug Mode: Enabled!");
}else if(value=="FALSE" || value=="false"){
DebugMode = FALSE;
llOwnerSay("Debug Mode: Disabled!");
}
}
}else{ // line does not contain equal sign
SendMessage("Configuration could not be read on line " + (string)cLine, NULL_KEY);
}
}
}
}
// Call In-World Server to get Confuration Data.
GetConfiguration(){
ServerComHandle = llListen(ServerComChannel, EMPTY, EMPTY, EMPTY);
llRegionSay(ServerComChannel, SecureRequest);
}
// Process Secure Server Response (Under OPFLAG=MAINCONFIG)
ProcessServerData(string msg){
list Response = llParseString2List(msg, ["||"], []);
if(llList2String(Response, 0)!=SecurityKey){
DebugMessage("Server Response did not provide correct authorization code!");
return;
}
list TempAdmins = llList2List(Response, 19, -1);
if(DebugMode){
DebugMessage("Main Server Key: "+(ConfigServerKey = llList2Key(Response, 2)));
DebugMessage("UserDB Server Key: "+(UserDBServerKey = llList2Key(Response, 3)));
DebugMessage("Event Server Key: "+(EventServerKey = llList2Key(Response, 4)));
DebugMessage("Round Time: "+(RoundTimer = llList2Integer(Response, 5))+" seconds");
PotPercent = llList2Float(Response, 6) / 100;
DebugMessage("Pot Percent: "+(string)PotPercent+"%");
DebugMessage("Diag Mode: "+(DiagMode = llList2String(Response, 7)));
DebugMessage("Win Multiplier: "+(PayOutMultiplier = llList2Integer(Response, 8))+"x");
DebugMessage("Play Cost: P$"+(PlayCost = llList2Integer(Response, 9)));
DebugMessage("Number of Rounds: "+(MaxRounds = llList2Integer(Response, 17)));
DebugMessage("Initial Highscore: "+(HighScore = llList2Integer(Response, 18)));
}else{
ConfigServerKey = llList2Key(Response, 2);
UserDBServerKey = llList2Key(Response, 3);
EventServerKey = llList2Key(Response, 4);
RoundTimer = llList2Integer(Response, 5);
PotPercent = llList2Integer(Response, 6);
DiagMode = llList2String(Response, 7);
PayOutMultiplier = llList2Integer(Response, 8); // Positive Integer by which the pay to play amount is multiplied. The Product of which is the Amount to Pay on Win
PlayCost = llList2Integer(Response, 9);
MaxRounds = llList2Integer(Response, 17);
HighScore = llList2Integer(Response, 18); // Current High Score To Beat. Gets Basic High Score from Server. Then each use beats last high score.
}
integer i;
for(i=0;i<llGetListLength(TempAdmins);i++){
AddAdmin(llList2String(TempAdmins, i));
}
// Set Text Displays
llMessageLinked(LINK_SET, RoundTimer, "TimerConf", EMPTY); // Update Timer Script with Round Timer Length Value
llMessageLinked(LINK_SET, MaxRounds, "RoundConf", EMPTY); // Update Timer Script with Max Number of Rounds
llMessageLinked(LINK_SET, 200000, ": "+(string)PayOutMultiplier+"x", "''''");
llMessageLinked(LINK_SET, 281000, llGetSubString((string)HighScore,0,5), "''''");
llMessageLinked(LINK_SET, 291000, llGetSubString((string)HighScore,6,11), "''''");
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT );
}
// Open Up Listeners on Local Chat 0 but only for people on Admins List
ListenToAdmins(){
integer i;
for(i=0;i<llGetListLength(Admins);i++){
llListen(0, "", llList2Key(Admins, i), "");
}
}
// Update Event Server with User Play Details
UpdateEvent(string WinLoss, integer MoneyWon, integer MoneyPaid){
list SendList = [];
if(WinLoss=="Win"){
SendList = [] + SecurityKey + ["UPDATE"] + [Player, "", "1", MoneyPaid, MoneyWon, "1", "0" ];
}else if(WinLoss=="Loss"){
SendList = [] + SecurityKey + ["UPDATE"] + [Player, "", "1", "0", MoneyPaid, "0", "1" ];
}
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(UserDBServerKey, DBComChannel, SendString);
if(DebugMode){
llOwnerSay("Event DB Updated!\n"+SendString);
}
}
//Main Program Logic
/* This section contains the main program logic. (ie: Default State, and all event triggers) */
default{
on_rez(integer params){
llResetScript();
}
state_entry(){
Initialize();
}
listen(integer chan, string sender, key id, string msg){
if(OPFLAG=="MAINCONFIG"){
SendMessage("Server Connected! Processing Configuration Directives...", llGetOwner());
ProcessServerData(msg);
}
}
// DataServer Event Called for Each Line of Config NC. This Loop It was Calls LoadConfig()
dataserver(key query_id, string data){ // Config Notecard Read Function Needs to be Finished
if (query_id == cQueryID){
if(data != EOF){
LoadConfig(data); // Process Current Line
++cLine; // Increment Line Index
cQueryID = llGetNotecardLine(ConfigFile, cLine); // Attempt to Read Next Config Line (Re-Calls DataServer Event)
}else{ // IF EOF (End of Config loop, and on Blank File)
SystemStart();
}
}
}
changed(integer change){
if(change & CHANGED_INVENTORY){
llResetScript();
}
}
run_time_permissions (integer perm){
if(perm & PERMISSION_DEBIT){
state ready;
}else{
llOwnerSay("You have denied request to start games.");
llSleep(2);
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT );
}
}
}
state ready
{
on_rez(integer param){
llResetScript();
}
state_entry(){
llSay(0, "Game Ready!");
llMessageLinked(LINK_SET, 205000, "0", "''''");
ListenToAdmins();
Player = NULL_KEY;
llSetPayPrice(PAY_HIDE, [PlayCost,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
}
touch(integer num){
if(num>1){
return;
}
if(Player!=NULL_KEY){
return;
}else if(llListFindList(Admins, [llDetectedKey(0)])!=-1){
MenuComHandle = llListen(MenuComChannel, EMPTY, EMPTY, EMPTY);
llDialog(llDetectedKey(0), AdminMenuMessage, AdminMenu, MenuComChannel);
}else{
llGiveInventory(llDetectedKey(0),llGetInventoryName(INVENTORY_NOTECARD, 1));
}
}
listen(integer channel, string name, key id, string message){
if(channel==MenuComChannel){
if(message=="Reboot"){
llResetScript();
}else if(message=="Exit Menu"){
llRegionSayTo(id, 0, "Exiting Menu...");
llListenRemove(MenuComHandle);
}
}
list command = llParseString2List(message, ["."], []);
if(llList2Integer(command, 2)!=PayOutMultiplier || llList2Integer(command, 2)==""){
return;
}
if(llList2String(command, 0) == "winmulti"){
PayOutMultiplier = (integer)llList2String(command, 1);
llMessageLinked(LINK_SET, 299000, (string)PayOutMultiplier, "''''");
}
if(llList2String(command, 0) == "highscore"){
HighScore = (integer)llList2String(command, 1);
llMessageLinked(LINK_SET, 281000, llGetSubString(llList2String(command, 1),0,5), "''''");
llMessageLinked(LINK_SET, 291000, llGetSubString(llList2String(command, 1),6,11), "''''");
}
}
money(key id, integer amount){
if (amount == PlayCost){
if(DiagMode=="TRUE"){
llWhisper(0, "Game Starting...\nDiagnostic Mode Active: Returning Money!\n No Money will be paid out upon win!");
llGiveMoney(id, amount);
}else{
llWhisper(0, "Game Starting...");
}
Player = id;
integer ToPot = (integer)(amount * (PotPercent / 100));
// Update Pot Amount in Local Game Server DB
list SendList = [] + SecurityKey + ["UPPOT"] + (list)ToPot; // Create List to be Parsed to String
string SendString = llDumpList2String(SendList, "||");
llRegionSayTo(UserDBServerKey, DBComChannel, SendString);
state play;
}
}
}
state play
{
on_rez(integer param)
{
llResetScript();
}
state_entry()
{
Score = 0;
llSetPayPrice(PAY_HIDE, [PAY_HIDE,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
//llPlaySound("9f755cb9-082a-1bd0-75ac-5d404bbef76d", 1);
llMessageLinked(LINK_SET, 0, "apple", Player);
llMessageLinked(LINK_SET, 0, "Start", "");
llSleep(2);
llMessageLinked(LINK_SET, 20110, "Next Round", "");
}
link_message(integer aset, integer dd, string cc, key ddh)
{
if (dd == 5){
Score += (integer)cc;
llMessageLinked(LINK_SET, 205000, (string)Score, "''''");
}
if (cc == "Game Over"){
string PayOut = "0";
if (Score > HighScore){
llMessageLinked(LINK_SET, 281000, llGetSubString((string)Score,0,5), "''''");
llMessageLinked(LINK_SET, 291000, llGetSubString((string)Score,6,11), "''''");
if(PayOutMultiplier > 0){
PayOut = (string)(PlayCost * PayOutMultiplier);
if(DiagMode=="TRUE"){
llWhisper(0, osKey2Name(Player)+" wins P$"+(string)PayOut+"! Diagnostic Mode Active: Nothing Paid Out!");
}else{
llWhisper(0, osKey2Name(Player)+" wins P$"+(string)PayOut+"!");
llGiveMoney(Player, (integer)PayOut);
}
UpdateEvent("Win", PlayCost, (integer)PayOut);
HighScore = Score;
state ready;
}
if(PayOutMultiplier < 1){
if(DiagMode=="TRUE"){
llWhisper(0, osKey2Name(Player)+" wins!\nNothing Paid, Diagnostic Mode Active!");
UpdateEvent("Win", PlayCost, (integer)PayOut);
HighScore = Score;
state ready;
}else{
llWhisper(0, osKey2Name(Player)+" wins!\nNothing Paid, No Multiplier Set. Contact Support!");
UpdateEvent("Win", PlayCost, (integer)PayOut);
HighScore = Score;
state ready;
}
}
}
if (Score < HighScore)
{
integer short = HighScore - Score;
llWhisper(0, osKey2Name(Player)+" loss with a score of "+(string)Score);
llSleep(1);
llWhisper(0, "Fell "+(string)short+" points short.");
llOwnerSay("PlayCost: "+PlayCost+" PayOut: "+PayOut);
UpdateEvent("Loss", (integer)PayOut, (integer)PlayCost);
state ready;
}
}
}
}

49
Zuingo/New Game Setup.txt Normal file
View File

@@ -0,0 +1,49 @@
In order to Copy and setup a new game the following configuration changes must be made manually
NOTE: The Game Always Starts in Diag Mode (Free Play). That needs to be changed in the .gameconfig NC. Located inside this Server.
!!! Communication Channels
1. New Game Server Communication Channel
In Scripts:
Game Engine -> Line 75
Game Server Relay -> Line 16
Game Config Server -> Line 7
User Database Server -> Line 263
JackPot Server -> Line 263
2. New Common Communication Channel (DBComChannel, ServerComChannel)
In Scripts
Game Engine -> Line 76
Game Server Relay -> Line 17
User Database Server -> Line 262
Game Event Logger Database Server -> Line 262
JackPot Server -> Line 262
Avatar Scanner -> Line 13
3. New Avatar Scanner Communication Channel
In Scripts
JackPot Server -> Line 264
Avatar Scanner -> Line 12
!!! Device Names (DB and Remote DB names)
1. Hover Text String
In Scripts:
User Database Server -> Line 266
Game Event Logger Database Server -> Line 264
JackPot Server -> Line 268
2. Database name (DBName)
In Scripts:
User Database Server -> Line 265
Game Event Logger Database Server -> Line 263
JackPot Server -> Line 267
!!! Prim Names and Descriptions !!! (Only for Event Logging and message purposes)
!!! Server UUIDs !!!
Change Inside Game Config Servers .gameconfig NoteCard
Change inside of Game Engine (In Gambling Machine Before you Duplicate)
!!! Texture UUIDs !!!
Game Engine Script -> Line 1 Needs to be changed to the Number Grid for that specific Game Type

View File

@@ -0,0 +1,16 @@
list lBlues = [ 22730431 //E
, 32772191 //N
, 18157905 //X
, 7509183 //P
, 31119031 //S
, 1113121 //T
, 22369621 //1010101 etc...
];
default {
link_message(integer sender, integer num, string msg, key id) {
if (msg == "getblues") {
llMessageLinked(LINK_THIS, llList2Integer(lBlues, (integer)llFrand( llGetListLength(lBlues)-1 )), "setblues", id); //comment this line and uncomment next line for testing
}
}
}

69
Zuingo/field.lsl Normal file
View File

@@ -0,0 +1,69 @@
vector txtCash = <0.05, -0.25, 0.0>;
vector txt2x = <0.45, -0.25, 0.0>;
integer ID = 0;
integer iCurrentNum;
integer bTouched;
key player;
ssTouched(integer bool) {
bTouched = bool;
if (bTouched) llSetColor(<0.25, 0.25, 0.25>, ALL_SIDES); //dark
else llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);
}
default {
state_entry() {
ID = (integer)llGetObjectName();
}
link_message(integer sender, integer num, string msg, key id) {
list data = llParseString2List(msg, (list)"~~", []);
string cmd = llList2String(data, 0);
string value = llList2String(data, 1);
if (num == -1 && msg == "setTexture") llSetTexture(id, ALL_SIDES);
if (num == ID) {
if (cmd == "startGame") {
player = id;
ssTouched(FALSE);
vector offset; vector color;
if ((integer)llList2String(data, 2)) color = <0.0, 1.0, 1.0>; //is blue
else color = <1.0, 1.0, 1.0>; //not blue
llSetColor(color, ALL_SIDES);
iCurrentNum = (integer)value;
if (iCurrentNum) {
offset.x = (iCurrentNum % 10) / 10.0;
offset.y = (iCurrentNum / 10) / 10.0;
}
offset.x += -0.45;
offset.y = 0.45 - offset.y;
llOffsetTexture(offset.x, offset.y, ALL_SIDES);
} else if (cmd == "useNumber") {
ssTouched(TRUE);
} else if (msg == "setTextureCash") {
llOffsetTexture(txtCash.x, txtCash.y, ALL_SIDES);
} else if (msg == "setTexture2x") {
llOffsetTexture(txt2x.x, txt2x.y, ALL_SIDES);
} else if (msg == "line") {
llSetColor((vector)((string)id), ALL_SIDES);
llSleep(1.0);
llSetColor(<0.25, 0.25, 0.25>, ALL_SIDES);
}
}
}
touch_start(integer n) {
if (llDetectedKey(0) == player && !bTouched)
llMessageLinked(LINK_ALL_OTHERS, ID, llDumpList2String(["fieldTouched", iCurrentNum], "~~"), NULL_KEY);
}
}

6
Zuingo/gamevalue.lsl Normal file
View File

@@ -0,0 +1,6 @@
default {
link_message(integer sender, integer num, string msg, key id) {
if (num == -1 && msg == "gameOver") llSetTexture("d039e927-7457-4560-b908-7d9d02f8dec1", 3);
if (num == -1 && msg == "setPicture") llSetTexture((string)id, 3);
}
}

151
Zuingo/randombar.lsl Normal file
View File

@@ -0,0 +1,151 @@
list lSides = [3, 7, 4, 6, 1];
list lOffsets = [
<-0.375, 0.45, 0.0>,
<-0.450, 0.45, 0.0>,
<-1.112, 0.45, 0.0>,
<-0.457, 0.45, 0.0>,
<-0.530, 0.45, 0.0>
];
list lNumbers = [];
integer totalRounds;
integer roundTime;
integer currentRound;
integer gameEnd = FALSE;
integer bChanging = FALSE;
key player;
ssSetSides() {
bChanging = TRUE;
ssReset();
integer n = 0;
while(n < 5) {
integer random = (integer)llFrand(18);
float x; float y;
vector offset = (vector)llList2String(lOffsets, n);
if (random < 17) {
if (random < 15) { //numbers
random += n * 15;
} else { //if (random >= 15) -> joker
random = 76;
}
x = (random % 10) / 10.0 + offset.x;
y = offset.y - (random / 10) / 10.0;
if (x < -1.0) x += 1.0;
llOffsetTexture(x, y, llList2Integer(lSides, n));
} else { //pharao/mummy
integer rand = (integer)llFrand(10) + 4;
integer status = 0;
integer j = 0;
if (rand % 2 == 0) rand = (integer)llFrand(10) + 4;
while (j < rand) {
status = !status;
random = 77 + status;
x = (random % 10) / 10.0 + offset.x;
y = offset.y - (random / 10) / 10.0;
if (x < -1.0) x += 1.0;
llOffsetTexture(x, y, llList2Integer(lSides, n));
++j;
}
llSetColor(<0.25, 0.25, 0.25>, llList2Integer(lSides, n));
if (random == 77) {
llMessageLinked(LINK_ALL_OTHERS, -1, "mummy", NULL_KEY);
} else {
llMessageLinked(LINK_ALL_OTHERS, -1, "pharao", NULL_KEY);
}
}
lNumbers += (string)random;
++n;
}
bChanging = FALSE;
}
ssReset() {
lNumbers = [];
llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);
llOffsetTexture(-0.375, 0.650, 3);
llOffsetTexture(-0.350, 0.650, 7);
llOffsetTexture(-0.912, 0.650, 4);
llOffsetTexture(-0.157, 0.650, 6);
llOffsetTexture(-0.130, 0.650, 1);
}
default {
on_rez(integer p) {
llResetScript();
}
state_entry() {
llMessageLinked(LINK_SET, -1, "gameOver", NULL_KEY);
llSetText("", <1,1,1>, 0.0);
ssReset();
}
link_message(integer sender, integer num, string msg, key id) {
list data = llParseString2List(msg, (list)"~~", []);
string cmd = llList2String(data, 0);
string value = llList2String(data, 1);
integer find;
if (num == -1 && msg == "setTexture") llSetTexture(id, ALL_SIDES);
if (cmd == "fieldTouched") {
if ((find = llListFindList(lNumbers, (list)value)) != -1
|| llList2Integer(lNumbers, (integer)value / 15) == 76) {
llMessageLinked(LINK_ALL_OTHERS, num, "useNumber", NULL_KEY);
llSetColor(<0.25, 0.25, 0.25>, llList2Integer(lSides, (integer)value / 15));
lNumbers = [] + llListReplaceList(lNumbers, (list)"-1", (integer)value / 15, (integer)value / 15);
}
} else if (num == -1 && msg == "startGame") {
gameEnd = FALSE;
player = id;
currentRound = 0;
llSetTimerEvent(0.1);
} else if (msg == "totalRounds") {
totalRounds = num;
} else if (msg == "roundTime") {
roundTime = num;
} else if (msg == "stopGame") {
gameEnd = TRUE;
llSetTimerEvent(0.0);
llMessageLinked(LINK_ALL_OTHERS, 20, "currentround", NULL_KEY);
//llSetText("Game Over!\nTouch to Select Price Menu!", <1.0, 1.0, 1.0>, 1.0);
llMessageLinked(LINK_SET, -1, "gameOver", NULL_KEY);
ssReset();
}
}
touch_start(integer n) { // When Random Bar (Next Round Button) is Touched
if (bChanging) return; // If it is currently changing, return and wait till it changes
if (llDetectedKey(0) == player) { // If the playing user clicks the bar
llSetTimerEvent(0.0); // Clear Round Timer
if (++currentRound <= totalRounds) { // If we are still not at round end
llMessageLinked(LINK_ALL_OTHERS, currentRound, "currentround", NULL_KEY);
//llSetText("Round " + (string)currentRound + " of " + (string)totalRounds, <1.0, 1.0, 1.0>, 1.0);
ssSetSides();
llSetTimerEvent(roundTime); // Re-Instantiate Round Timer
} else { // Else If we are done all rounds.
llSetText("", <1.0, 1.0, 1.0>, 1.0);
gameEnd = TRUE;
llMessageLinked(LINK_SET, -1, "gameOver", NULL_KEY); //Send gameOver Message
ssReset();
}
}
}
timer() {
llSetTimerEvent(0.0);
if (++currentRound <= totalRounds) {
llMessageLinked(LINK_ALL_OTHERS, currentRound, "currentround", NULL_KEY);
//llSetText("Round " + (string)currentRound + " of " + (string)totalRounds, <1.0, 1.0, 1.0>, 1.0);
ssSetSides();
llSetTimerEvent(roundTime);
} else {
gameEnd = TRUE;
llMessageLinked(LINK_SET, -1, "gameOver", NULL_KEY);
ssReset();
}
}
}

48
Zuingo/rounds-points.lsl Normal file
View File

@@ -0,0 +1,48 @@
list lSides = [3, 7, 4, 6, 1];
list lOffsets = [
<-0.380, 0.45, 0.0>,
<-0.450, 0.45, 0.0>,
<-0.100, 0.45, 0.0>,
<-0.452, 0.45, 0.0>,
<-0.515, 0.45, 0.0>
];
ssSetSide(integer roundNum, integer side) {
float x; float y;
vector offset = (vector)llList2String(lOffsets, side);
roundNum;
x = (roundNum % 10) / 10.0 + offset.x;
y = offset.y - (roundNum / 10) / 10.0;
if (x < -1.0) x += 1.0;
if (y < -1.0) y += 1.0;
llOffsetTexture(x, y, llList2Integer(lSides, side));
}
default {
state_entry() {
llSetAlpha(0.0, 7);
integer n = lSides != [];
while(n--) {
vector offset = (vector)llList2String(lOffsets, n);
llOffsetTexture(offset.x, offset.y, llList2Integer(lSides, n));
}
}
link_message(integer sender, integer num, string msg, key id) {
if (msg == "currentround") ssSetSide(num, 0);
if (msg == "playerPoints") {
string points = (string)num;
while(llStringLength(points) < 6) points = "0" + points;
ssSetSide((integer)llGetSubString(points, 4, 5), -1);
ssSetSide((integer)llGetSubString(points, 2, 3), -2);
ssSetSide((integer)llGetSubString(points, 0, 1), -3);
}
}
}

View File

@@ -0,0 +1,30 @@
// llTargetOmega substitution by Dora Gustafson, Studio Dora 2014
integer P;
KeyFramedOmega( vector axis, float spinrate)
{
llSetKeyframedMotion( [], []);
if ( spinrate )
{
float v = TWO_PI/3.0;
if ( spinrate < 0 ) v = -v;
list L = [llAxisAngle2Rot( axis/llGetRot(), v), v/spinrate];
llSetKeyframedMotion( L+L+L, [KFM_DATA, KFM_ROTATION, KFM_MODE, KFM_LOOP]);
}
}
default
{
state_entry()
{
llSetPrimitiveParams([PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);
}
touch_end( integer n)
{
P = ++P%4;
if ( P == 1 ) KeyFramedOmega( <0,0,1>, 0.6); // Positive spin
else if ( P == 3 ) KeyFramedOmega( <0,0,1>, 0.6); // Negative spin
else KeyFramedOmega( <0,0,1>, 0.0); // Stop spin
}
}

View File

@@ -0,0 +1,59 @@
//To scrub child prims too
//This script also started with "The Scrubber" by Jopsy Pendragon, Feb 10 2006, Version 1
//Update Tigger Genira 27 November 2009 for self distribution
//Update WDC Voom 8 November 2010 for better child action.
//Instructions: Put this script in the root prim of a build which is giving you grief.
//It will distribute itself to all the prims in the link set and reset/unset most persistant prim settings that can only be set by scripts.
//Once it has sent the script to the child prims you MUST take the whole object into inventory.
//Re-rez the object
//Edit it and 'set all scripts to running in selection'
string Me;
integer Pin=3141;
default
{
state_entry()
{
Me = llGetScriptName();
if(llGetLinkNumber() == 1)
{
//root prim
llOwnerSay("Inserted in root, sending to child prims");
integer i;
for (i = 2; i <= llGetNumberOfPrims(); i++)
{
key prim_key = llGetLinkKey (i);
llRemoteLoadScriptPin (prim_key, Me, Pin, TRUE, 0);
}
llOwnerSay("Done");
}
llSetSitText( "" );
llSetTouchText( "" );
llParticleSystem( [ ] );
llSetText( "", ZERO_VECTOR, 1.0 );
llTargetOmega( ZERO_VECTOR, 0, 0 );
llSetCameraAtOffset( ZERO_VECTOR );
llSetCameraEyeOffset( ZERO_VECTOR );
llSitTarget( ZERO_VECTOR, ZERO_ROTATION );
llSetTextureAnim( FALSE , ALL_SIDES, 1, 1, 0, 0, 0.0 );
integer iScriptCount = llGetInventoryNumber(INVENTORY_SCRIPT)-1;
while(iScriptCount > -1)
{
if(llGetInventoryName(INVENTORY_SCRIPT,iScriptCount) != Me)
{
llRemoveInventory(llGetInventoryName(INVENTORY_SCRIPT,iScriptCount));
}
iScriptCount--;
}
llOwnerSay("This Prim is Clean... ");
llRemoveInventory( Me );
// vanish without a trace...
}
}