Scripts Library

Creating scripts
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

floating seeds

Post by Constance Peregrine »

or whatever else you wish to use...just insert your own texture and reset the script:

[tested in the grid just now]

https://drive.google.com/file/d/0B6pQoe ... sp=sharing

Code: Select all

//// "Double Helix" PARTICLE TEMPLATE v1 - by Jopsy Pendragon - 4/8/2008
//// You are free to use this script as you please, so long as you include this line:
//** The original 'free' version of this script came from THE PARTICLE LABORATORY. **//

// SETUP:  Drop one optional particle texture and this script into a prim.
// Particles should start automatically. (Reset) the script if you insert a
// particle texture later on.  Add one or more CONTROLLER TEMPLATES to any
// prims in the linked object to control when particles turn ON and OFF.

// Customize the particle_parameter values below to create your unique 
// particle effect and click SAVE.  Values are explained along with their
// min/max and default values further down in this script.


string  CONTROLLER_ID = "A"; // See comments at end regarding CONTROLLERS.
integer AUTO_START = TRUE;   // Optionally FALSE only if using CONTROLLERS.

list particle_parameters=[]; // stores your custom particle effect, defined below.
list target_parameters=[]; // remembers targets found using TARGET TEMPLATE scripts.

default {
    state_entry() {
        particle_parameters = [  // start of particle settings
           // Texture Parameters:
           PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
           PSYS_PART_START_SCALE, <.20, .20, FALSE>, PSYS_PART_END_SCALE, <1.2, 1.2, FALSE>, 
           PSYS_PART_START_COLOR, <1.00,1.00,1.00>,    PSYS_PART_END_COLOR, <1.00,1.00,1.00>, 
           PSYS_PART_START_ALPHA, (float) 1.0,         PSYS_PART_END_ALPHA, (float) 1.0,     
           
           // Production Parameters:
           PSYS_SRC_BURST_PART_COUNT, (integer)  1, 
           PSYS_SRC_BURST_RATE,         (float) 0.2,  
           PSYS_PART_MAX_AGE,           (float)  20, 
        // PSYS_SRC_MAX_AGE,            (float)  0.00, 
            
           // Placement Parameters:
           PSYS_SRC_PATTERN, (integer) 8, // 1=DROP, 2=EXPLODE, 4=ANGLE, 8=CONE,
           
           // Placement Parameters (for any non-DROP pattern):
           PSYS_SRC_BURST_SPEED_MIN, (float) 00.0,   PSYS_SRC_BURST_SPEED_MAX, (float) 00.1, 
           PSYS_SRC_BURST_RADIUS, (float) 1,
           
           // Placement Parameters (only for ANGLE & CONE patterns):
           PSYS_SRC_ANGLE_BEGIN, (float) 1 * PI,   PSYS_SRC_ANGLE_END, (float)0.50 * PI,  
           PSYS_SRC_OMEGA, <00.00, 00.00, 00.2>,  
           
           // After-Effect & Influence Parameters:
           PSYS_SRC_ACCEL, < 00.00, 00.00, 00.02>,
        // PSYS_SRC_TARGET_KEY, (key) llGetLinkKey(llGetLinkNum() + 1), 
                   
           PSYS_PART_FLAGS, (integer) ( 1                  // Texture Options:     
                                | PSYS_PART_INTERP_COLOR_MASK   
                                | PSYS_PART_INTERP_SCALE_MASK   
                                | PSYS_PART_EMISSIVE_MASK   
                             // | PSYS_PART_FOLLOW_VELOCITY_MASK
                                                  // After-effect & Influence Options:
                                | PSYS_PART_WIND_MASK            
                             // | PSYS_PART_BOUNCE_MASK          
                             // | PSYS_PART_FOLLOW_SRC_MASK     
                             // | PSYS_PART_TARGET_POS_MASK     
                             // | PSYS_PART_TARGET_LINEAR_MASK    
                            ) 
            //end of particle settings                     
        ];
        
        if ( AUTO_START ) llParticleSystem( particle_parameters );
        
    }
    
    link_message( integer sibling, integer num, string mesg, key target_key ) {
        if ( mesg != CONTROLLER_ID ) { // this message isn't for me.  Bail out.
            return;
        } else if ( num == 0 ) { // Message says to turn particles OFF:
            llParticleSystem( [ ] );
        } else if ( num == 1 ) { // Message says to turn particles ON:
            llParticleSystem( particle_parameters + target_parameters );
        } else if ( num == 2 ) { // Turn on, and remember and use the key sent us as a target:
            target_parameters = [ PSYS_SRC_TARGET_KEY, target_key ];
            llParticleSystem( particle_parameters + target_parameters );
        } else { // bad instruction number
            // do nothing.
        }            
    }
        
}


//============================= About Parameters =============================
// There are 22-ish NAMED attributes that affect a particle display.
// To customize a display you give each a VALUE.
// For example: PSYS_PART_START_COLOR is a named attribute,
// and <1.0, 0.5, 0.0> is a color VALUE (orange, in this case).
// 
// As long as your 'names' and 'values' are paired up properly, they can
// be in any order!  Any you omit a pair, it reverts to a default value.

//============================= Texture Parameters =============================
//
// TEXTURE, can be an "Asset UUID" key copied from a texture 
//          that you have full permissions to, or the name of
//          a texture in the prim's inventory.
//
// SCALE, (size) 0.0 to 4.0 meters wide, by 0.0 to 4.0 meters tall. (default 1x1)
//          Textures are FLAT, so the 'z' part of the vector is ignored.
//          Values smaller than 0.04x0.04 may not get rendered at all.
//          Tiny particles vanish if the viewer is not near them.
//
// BEGIN_SCALE sets particle start size.  
// END_SCALE (end size) is ignored, if the INTERP_SCALE_MASK option is disabled.
//
// COLOR, < RED, GREEN, BLUE > from <0.00,0.00,0.00> (black) to <1.00,1.00,1.00> (white/default)
// ALPHA, 1.0 = 100% visible(default), 0.0 = invisible.  Less than 0.1 might not get seen.
// START_COLOR and START_ALPHA set the color and transparency of newly created particles. 
// END_COLOR and END_ALPHA are ignored, if the INTERP_COLOR_MASK option is disabled.
         
         
//============================= Production Parameters =============================
//
// BURST_PART_COUNT: quantity of particles per burst, 1 to 4096 (default 1), 
//
// BURST_RATE: seconds to delay between particle bursts. 0.0 to 30.0 (default 0.1)
//
// PART_MAX_AGE: particle lifespan in seconds, 0.00 to 30.0 (default=10.0)
//               PART_MAX_AGE less than 0.5 might not be visible.
//
// The default total number of particles that can be seen is 4096, if one or more 
// emitters try to create more than that, many will not be seen, and it may cause
// viewer lag.  Use as few particles as you can for your effect:
// AGE/RATE * COUNT will tell you approximately how many particles your emitter creates.
//
// SRC_MAX_AGE: emitter auto shut-off timer. 1.0 to 60.0 seconds. 0.0 = never stop. (default)


//============================= Placement Parameters =============================
//                
// PATTERN:   
//      DROP, ignores all other placement settings.
//      EXPLODE, spray particles in all directions
//      ANGLE, sprays a flat "fan" shape defined by ANGLE_BEGIN and END values
//      CONE, sprays "ring" or "cone" shapes defined by ANGLE_BEGIN and END values
//
// RADIUS:  0.0 to 50.0?  distance from emitter to create new particles
//      (RADIUS is disabled with DROP pattern and the FOLLOW_SRC & TARGET_LINEAR options)
//        
// SPEED: 0.00 to 50.0?  Sets min/max starting velocities for non-drop patterns. (default: 1.0)
//        
// ANGLE_BEGIN & END:  0.00*PI (up) to 1.00*PI (down),  (Only for ANGLE & CONE patterns)
//       (Values work much like the Sphere-prim's DIMPLE attributes.) (defaults: 0.0)
//
// OMEGA: <x,y,z> Sets how much to rotate angle/cone spray direction after
//                every burst. 0.0 to PI?  (default: <0,0,0>)

//======================== After-Effects & Influence Parameters ================
//
// ACCEL, x,y,z 0.0 to 50.0?  sets a constant force, (affects all patterns)
//          Causes particles to drift up/down or in a compass direction.
//          Use ACCEL to create the illusion of (anti-)gravity or a directional wind.
//          (ineffective with TARGET_LINEAR option)
//       
// TARGET_KEY,  "key", (requires the TARGET option be enabled).  
//       "key" can be a variety of many different things:
         // llGetOwner()
         // llGetKey() target self 
         // llGetLinkKey(1) target parent prim
         // llGetLinkKey(llGetLinkNum() + 1) target next prim in link set 
         //
         // WARNING: New copies of objects get new keys, you can't simply paste
         // a prim's key into your script and expect it to always work.  Visit
         // the Particle Laboratory's section on TARGETS for a variety of ways
         // to dynamically find your target's key. There are different 'best ways'
         // depending on if your target is linked to your emitter or not.


//============================= About Options =============================
//    
// Each option may be ON/ENABLED (no leading // )
// or OFF/DISABLED (by putting a // in front of it.)
// Options are combined together in a special way, (using the | symbol).
// This creates one single Parameter for PSYS_PART_FLAGS.

              
//============================= Texture Options =============================
//
// EMISSIVE: identical to "full bright" setting on prims     
//   
// FOLLOW_VELOCITY: particle texture 'tilts' towards the direction it's moving
//
// INTERP_COLOR: causes particle COLOR and ALPHA(transparency) to change over it's lifespan
//
// INTERP_SCALE: causes particle SCALE(size) to change over it's lifespan


//======================== After-Effects & Influences Options ================
//
// BOUNCE:  particles bounce up from the z-altitude of emitter, and cannot fall below it.
//
// WIND: the sim's wind will push particles around
//
// FOLLOW_SRC: makes particles move (but not rotate) if their emitter moves, (disables RADIUS)
//
// TARGET_POS: causes particles to arrive at a some target at end of of their lifespan.
//
// TARGET_LINEAR: forces particles to form into an even line from emitter to target
//                and forces a DROP-like pattern and disables effects of WIND and ACCEL



//========================================================================
//======================== USING CONTROL TEMPLATES =======================
//
// Want to control when your particles turn ON and OFF?   You can!
// 
// Drop one (or more) of the CONTROL TEMPLATES from the particle laboratory
// into your object containing this script.  That's it!

// Your controls should be effective immediately.  (Some controllers can be
// adjusted and tuned, open them and read the USAGE notes to see.)
//
// One control template can control several particle templates in the
// same object.   (keep in mind that each prim can only have ONE
// particle effect active at a time).
//
// The 'particle_effect_name' value must be the same in both the control
// and particle template to work.  You can change that value and have
// a controller for one effect, and a different controller for a different
// effect in the same object.
//


//======================================== END ===============================
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

bubble fountain

Post by Constance Peregrine »

tested in kitely:

Code: Select all

default
{
    state_entry()
    {
        llParticleSystem([
            PSYS_PART_FLAGS,( 0 
                |PSYS_PART_INTERP_COLOR_MASK
                |PSYS_PART_INTERP_SCALE_MASK
                |PSYS_PART_FOLLOW_VELOCITY_MASK
                |PSYS_PART_EMISSIVE_MASK ), 
            PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE ,
            PSYS_PART_START_ALPHA,1,
            PSYS_PART_END_ALPHA,1,
            PSYS_PART_START_COLOR,<1,0.8,0.501961> ,
            PSYS_PART_END_COLOR,<1,1,1> ,
            PSYS_PART_START_SCALE,<0.375,0.375,0>,
            PSYS_PART_END_SCALE,<0.375,0.375,0>,
            PSYS_PART_MAX_AGE,5,
            PSYS_SRC_MAX_AGE,0,
            PSYS_SRC_ACCEL,<0,0,-1>,
            PSYS_SRC_BURST_PART_COUNT,10,
            PSYS_SRC_BURST_RADIUS,0,
            PSYS_SRC_BURST_RATE,0.046875,
            PSYS_SRC_BURST_SPEED_MIN,2,
            PSYS_SRC_BURST_SPEED_MAX,4,
            PSYS_SRC_ANGLE_BEGIN,0,
            PSYS_SRC_ANGLE_END,0.09375,
            PSYS_SRC_OMEGA,<0,0,0>,
            PSYS_SRC_TEXTURE, (key)"8c3d19e4-b67a-4f0f-87c2-612564581033",
            PSYS_SRC_TARGET_KEY, (key)"00000000-0000-0000-0000-000000000000"
         ]);
    }
}
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

sounds player

Post by Constance Peregrine »

Interesting little sound player script...

[tested in Kitely just now]

Code: Select all

integer on;
    default
    {
        state_entry()
        {
           // llSetText("Stopped, Click to Play!!",<1,1,1>,1);
            llWhisper(0,"booting up sound orb.");
            llWhisper(0,"bootup complete.");
        }
    touch_start(integer touches)
        {
            if (on == 0)
            {
                on = 1;
                llLoopSound("4de9093b-40ee-4a62-a176-93ff6d4221b2",1);
               // llSetText("Playing - Click to Stop!!",<1,1,1>,1);
                llWhisper(0,"playing sound");
            }
            else
            {
                on = 0;
                llStopSound();
               // llSetText("Stopped, Click to Play!!",<1,1,1>,1);
                llWhisper(0,"Stoping sound");
            }
    }
}
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

Texture Animation

Post by Constance Peregrine »

Found this in a sunbeam [tested in kitely just now]

Code: Select all

//Texture Animation Script
//from Protomas' Water Effects class

// Drop on an object to make it change colors.

// If you are interested in scripting, check out the Script Help under the help menu.

// The double slash means these lines are comments and ignored by the computer.

// All scripts have a default state, this will be the first code executed.
default 
{ 
    // state_entry() is an event (or more exactly an event handler), this one executes whenever default is entered.
    state_entry() 
    { 
        // llSetTextureAnim() is a function that animates a            //texture on a face.
        // animate the script to scroll across all the faces.
        llSetTextureAnim(ANIM_ON | ROTATE |SMOOTH | LOOP, ALL_SIDES,0,0,0.0, TWO_PI, 0.1);
    } 
} 
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

notecard giver sensor

Post by Constance Peregrine »

get close to it and it offers the included nc:

Code: Select all

// Script Name: NotecardGiver.lsl
// CATEGORY: Inventory Giver
// CREATED: 2010-01-10 05:20:56.000
// EDITED: 2010-01-10 05:20:56.000
// AUTHOR: Encog Dod
// COMPATIBILITY: Second Life 

// NotecardGiver

// Downloaded from : http://www.free-lsl-scripts.com/cgi/freescripts.plx?ID=565

// This program is free software; you can redistribute it and/or modify it.
// Additional Licenes may apply that prevent you from selling this code
// You must leave any author credits and any headers intact in any script you use or publish.

// If you don't like these restrictions and licenses, then don't use these scripts.

//////////////////////// ORIGINAL AUTHORS CODE BEGINS ////////////////////////////////////////////


// NotecardGiver
// From the book:
//
// Scripting Recipes for Second Life
// by Jeff Heaton (Encog Dod in SL)
// ISBN: 160439000X
// Copyright 2007 by Heaton Research, Inc.
//
// This script may be freely copied and modified so long as this header
// remains unmodified.
//
// For more information about this book visit the following web site:
//
// http://www.heatonresearch.com/articles/series/22/

string notecard = "Uberflux Region Info";
integer freq = 1;
integer maxList = 100;
list given;


default
{
    state_entry()
    {
        llSensorRepeat("", "",AGENT, 20, PI, freq);
        llSetText("", <1.0, 1.0, 1.0>, 1.0);
    }
    
    sensor(integer num_detected)
    {
        integer i;
        key detected;
        
        for(i=0;i<num_detected;i++)
        {
            detected = llDetectedKey(i);
            
            if( llListFindList(given, [detected]) < 0 )
            {
                given += llDetectedKey(i);
                
                llGiveInventory(detected, notecard);
                if (llGetListLength(given) >= maxList)
                {
                    given = llDeleteSubList(given,0,10);
                }                                
            }
        }                
    }
}
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

deluxe visitor log

Post by Constance Peregrine »

very nice visitor log counter:

Code: Select all

// Deluxe Visitor Log - keeps track of visitors to the region, storing the information in a notecard to preserve
// the data between script resets, region restarts and the like. When touched by the owner,
// produces a notecard containing the visitor list sorted by number of visits, alphabetically
// by visitor name, and by date of first visit. (If anyone other than the owner touches it,
// they are simply told the number of visitors the region has had.)
//
// After putting this script into a prim, open the menu by touching the prim and select
// "Reset" to enable the tracing of logging start date and most recent visit date.
//
// Requires the following OSSL functions: osMakeNotecard(), osGetAgents(), osAvatarName2Key()
// Make sure they are allowed in OpenSim.ini for the UUID of the avatar owning the object which contains the script.
//
// Version 1.0 by Warin Cascabel (4 July 2009)
// Version 1.1 by Warin Cascabel (6 July 2009) - set object description to visitors/visits info
//
// Slight Revision by WhiteStar Magic (July 23 2009)
// - Modified to prevent from capturing Owner Visits as this skews total visit counts
// - Added a Menu for the Owner to offer choice of Reset System, Display list data, Give list data
// - Added that on Owner Change the system Resets the data notecard & description as well
// - Added a Script reset for when a Region is restarted, it hung up a couple of times on restart.
//
// Bug fixes and improvements by Carn Iggle (30 May 2010)
// - Fixed handling of menu dialog timeouts.
// - Fixed removal of listen handler for menu dialog.
// - Fixed display of visitor list such that all lines are dumped to the chat.
// - Added start date of logging to visitors/visits info.
// - Added tracing of logging start date and most recent visit date. (15 July 2010)
// - Added option for logging the first and last visit dates for each visitor. (15 July 2010)
// Version 1.2 by Slow Putzo (23 April 2011) add NC giver to first time visitors
//
//======================================== Variables ========================================

// ------------------------------ Configuration variables -----------------------------------

integer FLOATING_TEXT = FALSE; // Show number of visitors also as floating text
integer LOG_VISITOR_DATES = TRUE; // Log dates of first and last visit for each visitor
float TimerInterval = 60.0; // Number of seconds between polling the region for new avatars
string DataNotecard = "Visitor List Data"; // Name of the notecard in which data is stored
string GiveNotecard = ""; // Name of the notecard to give first time visitor


// ------------------------- Internal variables - do not change -----------------------------

list Visitors; // Data stored in the format [ UUID, Name, Visits [...]]
integer Stride; // Length of an entry in Visitors list
list CurrentlyHere; // UUIDs of avatars detected during the previous scan
key DataRequest; // Used for reading in the settings notecard
integer NotecardLine; // Likewise
string LastVisit; // Date of last visit

//======================================== Functions ========================================

// AddName() adds the provided details to the master list, or updates the visit count if the person is
// already present in the list.
//
integer AddName( string UUID, string Name )
{
integer TotalVisits = 1;
string timestamp = GetTimestamp();
integer IndexPos = llListFindList( Visitors, [ UUID ] ); // Search for the UUID in our master list

if (IndexPos == -1) // If not found in the list, add them with 1 visit
{
if (LOG_VISITOR_DATES)
Visitors += [ UUID, Name, (string) 1, timestamp, timestamp ];
else
Visitors += [ UUID, Name, (string) 1 ];
if (GiveNotecard != "") llGiveInventory(UUID, GiveNotecard); // give NC to first time visitor
}
else // If they were found in the list, increment their visit count, and update last visit date
{
integer CountPos = IndexPos + 2;
TotalVisits = llList2Integer( Visitors, CountPos ) + 1;
if (LOG_VISITOR_DATES)
{
string FirstVisit = llList2String( Visitors, CountPos+1 );
Visitors = llListReplaceList( Visitors, [ (string) TotalVisits, FirstVisit, timestamp ], CountPos, CountPos + 2);
}
else
Visitors = llListReplaceList( Visitors, [ (string) TotalVisits ], CountPos, CountPos );
}
return 1;
}


// CheckNames() gets the list of agents present in the region, ignores any who were present during the last scan,
// and adds the remainder to the master list (or increments their visit count if they were already in it)
//
CheckNames()
{
integer NamesAdded = 0;
list l = osGetAgents(); // Get the list of all the agents present in the region (better than sensors!)
list RecentScan; // To hold the name and UUID of everyone found, but who was not present during last scan
list RecentUUIDs; // To hold just the UUIDs of everyone found, but who was not present during last scan
list AllUUIDsFound; // To hold the UUIDs of everyone found, regardless of whether or not they were present last time
integer i = llGetListLength( l ); // general iterator variable
//
// First, build a list containing the data of everyone who wasn't found during the previous scan
//
while (i--)
{
string AvatarName = llList2String( l, i ); // Get the full name
list NameParts = llParseString2List( AvatarName, [ " "], [] ); // break it into first and last names
key UUID = osAvatarName2Key( llList2String( NameParts, 0 ), llList2String( NameParts, 1 )); // Get the UUID
AllUUIDsFound += [ UUID ]; // Add their UUID to the list of all UUIDs found
// if(UUID != llGetOwner()) { // Do not count visits of the owner
if (llListFindList( CurrentlyHere, [ UUID ] ) == -1) // if we didn't find the person during the previous scan:
{
RecentUUIDs += [ UUID ]; // Add their UUID to the list of new UUIDs found during this scan
RecentScan += [ UUID, AvatarName ];// Add all their information to the recent scan list
}
// }
}
CurrentlyHere = AllUUIDsFound; // Replace CurrentlyHere with the list of everyone who's present in the region now.
//
// Add anyone new from the most recent scan to the master list, or increase their visit counts if they've already been here before
//
for (i = llGetListLength( RecentScan ); i > 0; i -= 2)
{
string thisUUID = llList2String( RecentScan, i-2 );
NamesAdded += AddName( thisUUID, llList2String( RecentScan, i-1 ));
}
//
// If we actually did anything, write out a new notecard to save the data.
//
if (NamesAdded)
{
LastVisit = GetTimestamp();
if (llGetInventoryKey( DataNotecard ) != NULL_KEY) llRemoveInventory( DataNotecard );
osMakeNotecard( DataNotecard, Visitors );
llSetObjectDesc( GetInfoText() );
}
if (FLOATING_TEXT)
llSetText( GetInfoText(), <1.0,1.0,1.0>, 1.0 );
}


// CountTotalVisits() returns the total number of visits recorded by all avatars
//
integer CountTotalVisits()
{
integer RetVal = 0;
integer i = llGetListLength( Visitors ) - 1 - (Stride - 3);
for (; i > 0; i -= Stride)
{
RetVal += llList2Integer( Visitors, i );
}
return RetVal;
}

// Returns a formatted version of llGetTimestamp()
//
string GetTimestamp()
{
list tokens = llParseString2List(llGetTimestamp(), ["T",".","Z"], []);
return llList2String(tokens, 0);
}

// Returns text with info about the scanning period
string GetDateInfo()
{
string timeinfo = "";
list tokens = llParseString2List(llGetObjectDesc(), [], [" on ", " since ", " First: ", " Last: "]);
integer numparts = llGetListLength(tokens);
string start = llList2String(tokens, -1);
if (numparts >= 5)
{
start = llList2String(tokens, -3);
if (LastVisit == "")
LastVisit = llList2String(tokens, -1);
}
if (numparts >= 3)
{
if (LastVisit == "")
timeinfo = "since " + start;
else
// timeinfo = "First: " + start + " Last: " + LastVisit;
timeinfo = " Last: " + LastVisit;
}
return timeinfo;
}

// GetInfoText() returns an info text about the recorded number of visitors, total number of visits,
// and the date of the first and last visit.
//
string GetInfoText()
{
integer VisitorsLogged = llGetListLength( Visitors ) / Stride;
integer visits = CountTotalVisits();
string ss1 = "s";
string ss2 = "s";
if (VisitorsLogged == 1) ss1 = "";
if (visits == 1) ss2 = "";
return (string) VisitorsLogged + " Visitor" + ss1 + " / " + (string) visits + " Visit" + ss2
+ " in " + llGetRegionName() + " " + GetDateInfo();
}

// DeliverReportNotecard() builds a notecard containing the visitor list sorted three ways: by frequency of visit (descending),
// alphabetically by visitor name, and by date of first visit. It then delivers the notecard to the
// owner, and deletes it from inventory.
//
// mod by WS string action for either display or give
//
DeliverReportNotecard(string action)
{
list FirstList; // to store the list ordered by date of visit
list LastList; // to store the list ordered by date of visit
list NameList; // to store the list ordered by avatar name
list VisitList; // to store the list ordered by visit count
list Notecard; // to store the report notecard
integer j = llGetListLength( Visitors );
integer i;
integer VisitorsLogged = j / Stride;
integer VisitsLogged = CountTotalVisits();
llOwnerSay( (string) (j / Stride) + " visitors/ " + (string) VisitsLogged + " visits logged. Please wait while the full report is generated." );
for (i = 0; i < j; i += Stride)
{
string name = llList2String( Visitors, i+1 );
integer visits = llList2Integer( Visitors, i+2 );
string dates = "";
string dates1 = "";
string sss = "s";
if (visits == 1) sss = "";
if (LOG_VISITOR_DATES)
dates = " First: " + llList2String( Visitors, i+3 ) + " Last: " + llList2String( Visitors, i+4 );
dates1 = llList2String( Visitors, i+4 );
FirstList += [ llToLower( name ), name + " " + (string) visits + " visit" + sss + dates + "" ];
LastList += [(string) dates1, (string) name + (string) " " + " visit" + sss + " " + visits ];
VisitList += [ visits, (string) visits + " -- " + name + dates];
}
if (VisitorsLogged == 1) // OpenSim screws up llList2ListStrided if there's only one stride in the list.
{
FirstList = llDeleteSubList( FirstList, 0, 0 );
LastList = llDeleteSubList( LastList, 0, 0 );
NameList = FirstList;
VisitList = llDeleteSubList( VisitList, 0, 0 );
}
else
{
NameList = llList2ListStrided( llDeleteSubList( llListSort( FirstList, 2, TRUE), 0, 0 ), 0, -1, 2 ); // sort alphabetically
FirstList = llList2ListStrided( llDeleteSubList( FirstList, 0, 0 ), 0, -1, 2 );
LastList = llList2ListStrided( llDeleteSubList( llListSort( LastList, 2, FALSE), 0, 0 ), 0, -1, 2 ); //sort by last visit
VisitList = llListSort( VisitList, 2, FALSE ); // sort by descending visit count
VisitList = llList2ListStrided( llDeleteSubList( VisitList, 0, 0 ), 0, -1, 2 ); // Get only the text to display
}
Notecard = [ "Total visitors: " + (string) VisitorsLogged ];
Notecard += [ "Total visits: " + (string) VisitsLogged ];
Notecard += [ "", "Sorted by number of visits: ", "" ] + VisitList;
Notecard += [ "", "Sorted by name:", "" ] + NameList;
Notecard += [ "", "Sorted by date of first visit:", "" ] + FirstList;
Notecard += [ "", "Sorted by date of last visit:", "" ] + LastList;
Notecard += [ "", "Total visitors: " + (string) VisitorsLogged ];
Notecard += [ "Total visits: " + (string) VisitsLogged ];
string NotecardName = llGetRegionName() + " visitor list " + llGetTimestamp() + ", " + GetDateInfo();
if(action == "Display")
{
string name = llGetObjectName();
llSetObjectName("");
llOwnerSay("/me " + NotecardName);
j = llGetListLength(Notecard);
for (i = 0; i < j; ++i)
llOwnerSay("/me " + llList2String(Notecard, i));
llSetObjectName(name);
}
else
{
osMakeNotecard( NotecardName, Notecard );
llGiveInventory( llGetOwner(), NotecardName );
llRemoveInventory( NotecardName );
}

}
// Modifications by WhiteStar follow
integer CHANNEL;
integer HANDLE;
MENU_Owner(key id) // Admin Menu
{
llListenRemove(HANDLE); // Safety kill listener incase left over
CHANNEL = (integer)(llFrand(-1000.0) - 1000.0); // Random negative channel
HANDLE = llListen(CHANNEL, "", NULL_KEY, ""); // listen for dialog answers
//
llDialog(id,
"\nDisplay: List visitor data in chat" +
"\nNotecard: Give a notecard with visitor data" +
"\nReset: Deletes notecard and resets description",
["Notecard","Reset","CANCEL","Display"], CHANNEL);
llSetTimerEvent(45.0); // to AutoKill Listener
}
//
// ================================ default state handler ==================================

default {

state_entry() // Read in the saved visitor list data, if it exists, and switch to the running state.
{
llSetText( "", ZERO_VECTOR, 0.0 );
Stride = 3;
if (LOG_VISITOR_DATES) Stride = 5;
Visitors = []; // clear out the visitors list
if (llGetInventoryKey( DataNotecard ) == NULL_KEY) state running; // switch to running state if the notecard doesn't exist
llOwnerSay( "Reading saved visitor list data" );
NotecardLine = 0;
DataRequest = llGetNotecardLine( DataNotecard, 0 );
}

dataserver( key id, string data )
{
if (id != DataRequest) return;
if (data == EOF)
state running;
else
{
data = llStringTrim( data, STRING_TRIM );
if (data != "") Visitors += [ data ];
DataRequest = llGetNotecardLine( DataNotecard, ++NotecardLine );
}
}
}

// ================================ running state handler ==================================

state running
{
// state_entry(): load in notecard, if present, set a timer, and check region immediately.
//
state_entry()
{
llOwnerSay( "Visitor scanning active" );
llSetTimerEvent( TimerInterval ); // Set the timer for periodic checks
CheckNames(); // Check the region immediately for avatars
}

// touch_start() will cause the report card to be generated, if the touch was from our
// owner; otherwise, it will tell the toucher how many visitors the region
// has logged.
//
touch_start( integer foo )
{
if (llDetectedKey( 0 ) == llGetOwner()) // being lazy, and assuming there's only one touch.
{
MENU_Owner(llGetOwner());
}
else
{
llInstantMessage( llDetectedKey( 0 ), GetInfoText() );
}
}

// listen event to capture owners menu response and act upon it.
//
listen( integer channel, string name, key id, string msg )
{
llListenRemove(HANDLE); HANDLE = 0; // Kill listen reduce Lag
if(msg == "Reset")
{
llRemoveInventory(DataNotecard);
llSetObjectDesc("Reset on " + GetTimestamp());
llResetScript();
}
else if((msg == "Display")||(msg == "Notecard"))
DeliverReportNotecard(msg);
}

// Poll the region every x seconds (as configured by the TimerInterval variable). Rather than using
// sensors, which are limited both in range and in the number of avatars they can detect, we'll use
// the OpenSim-only function osGetAgents().
//
timer()
{
if (HANDLE) {
llListenRemove(HANDLE); HANDLE = 0;
llSetTimerEvent( TimerInterval );
}
CheckNames();
}

// Reset the script if the region has restarted. This mainly restarts the timer and clears out the list
// of people who were detected the last time the region was scanned, but it's good to avoid any other
// unforeseen consequences.
//
changed( integer change )
{
if (change & CHANGED_REGION_RESTART)
llResetScript();
if (change & CHANGED_OWNER) {
llRemoveInventory(DataNotecard);
llSetObjectDesc("Initialized on " + GetTimestamp());
llResetScript();
}
}
}
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

radio player

Post by Constance Peregrine »

no notecard needed:

Code: Select all

// Script Name: Top-10_Radio_Stations_Player.lsl
// Author: Ferd Frederix
// This script makes any prim into the top 10 most listened to radio stations on the Internet in over 200 categories.  It auto updates and requires no notecards.
//
//

// Downloaded from : http://www.free-lsl-scripts.com/cgi/freescripts.plx?ID=1672

// This program is free software; you can redistribute it and/or modify it.
// Additional Licenes may apply that prevent you from selling this code
// and these licenses may require you to publish any changes you make on request.
//
// There are literally thousands of hours of work in these scripts. Please respect
// the creators wishes and Copyright law and follow their license requirements.
//
// License information included herein must be included in any script you give out or use.
// Licenses may also be included in the script or comments by the original author, in which case
// the authors license must be followed, and  their licenses override any licenses outlined in this header.
//
// You cannot attach a license to any of these scripts to make any license more or less restrictive.
//
// All scripts by avatar Ferd Frederix, unless stated otherwise in the script, are licensed as Creative Commons By Attribution and Non-Commercial.
// Commercial use is NOT allowed - no resale of my scripts in any form.  
// This means you cannot sell my scripts but you can give them away if they are FREE.  
// Scripts by Ferd Frederix may be sold when included in a new object that actually uses these scripts. Putting my script in a prim and selling it on marketplace does not constitute a build.
// For any reuse or distribution, you must make clear to others the license terms of my works. This is done by leaving headers intact.
// See http://creativecommons.org/licenses/by-nc/3.0/ for more details and the actual license agreement.
// You must leave any author credits and any headers intact in any script you use or publish.
///////////////////////////////////////////////////////////////////////////////////////////////////
// If you don't like these restrictions and licenses, then don't use these scripts.
//////////////////////// ORIGINAL AUTHORS CODE BEGINS ////////////////////////////////////////////


// More information on this radio player is at <a href="http://metaverse.mitsi.com/Secondlife/posts/streaming">this link</a>
//
//If your land is owned by a group, you will need to deed the prim to the group. Just edit the prim that the script is in, set 'Group:' to the same group as the land, and click 'Share with Group'.  Then click the prim and select the Cartegory and radio station and enjoy free music!
// Copyright 2010 Ferd Frederix
// License:
// Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US
// That means this must always be free. 

// V1.1 allow longer names

integer mode ;            // true if we are in refresh mode
list lCategories;        // list of categories
list  lStations;        // list of stations
key http_request_id;    // key of the current HTTP request
integer busy = 0;        // go away, I'm budy

integer type;    // 3 possible http transactions
string genre;    // the category
string url;        // the last URL
string station;    // current station
integer menuChannel;    // int of the channel number
key user;            // the poerson who touched me
integer listen_id;    // int of the current listener
string pubpriv = "Public";

// from the menu system http://wiki.secondlife.com/wiki/SimpleDialogMenuSystem
integer N_DIALOG_CHOICES;
integer MAX_DIALOG_CHOICES_PER_PG = 8; // if not offering back button, increase this to 9
string PREV_PG_DIALOG_PREFIX = "< Page ";
string NEXT_PG_DIALOG_PREFIX = "> Page ";
string DIALOG_DONE_BTN = "Done";
string DIALOG_BACK_BTN = "<< Back";

integer pageNum;
list DIALOG_CHOICES;

giveDialog(key ID, integer pageNum) {

    list buttons;
    integer firstChoice;
    integer lastChoice;
    integer prevPage;
    integer nextPage;
    string OnePage;

    CancelListen();

    menuChannel = llCeil(llFrand(1000000) + 11000000);
    listen_id = llListen(menuChannel,"","","");
    mode = FALSE;
    llSetTimerEvent(60);


    N_DIALOG_CHOICES = llGetListLength(DIALOG_CHOICES);


    if (N_DIALOG_CHOICES <= 10) {
        buttons = DIALOG_CHOICES;
        OnePage = "Yes";
    }
    else {
        integer nPages = (N_DIALOG_CHOICES+MAX_DIALOG_CHOICES_PER_PG-1)/MAX_DIALOG_CHOICES_PER_PG;


        if (pageNum < 1 || pageNum > nPages) {
            pageNum = 1;
        }
        firstChoice = (pageNum-1)*MAX_DIALOG_CHOICES_PER_PG;

        lastChoice = firstChoice+MAX_DIALOG_CHOICES_PER_PG-1;


        if (lastChoice >= N_DIALOG_CHOICES) {
            lastChoice = N_DIALOG_CHOICES;
        }
        if (pageNum <= 1) {
            prevPage = nPages;
            nextPage = 2;
        }
        else if (pageNum >= nPages) {
            prevPage = nPages-1;
            nextPage = 1;
        }
        else {
            prevPage = pageNum-1;
            nextPage = pageNum+1;
        }
        buttons = llList2List(DIALOG_CHOICES, firstChoice, lastChoice);
    }


    // FYI, this puts the navigation button row first, so it is always at the bottom of the dialog
    list buttons01 = llList2List(buttons, 0, 2);
    list buttons02 = llList2List(buttons, 3, 5);
    list buttons03 = llList2List(buttons, 6, 8);
    list buttons04;
    if (OnePage == "Yes") {
        buttons04 = llList2List(buttons, 9, 11);
    }
    buttons = buttons04 + buttons03 + buttons02 + buttons01;

    if (OnePage == "Yes") {
        buttons = [ DIALOG_DONE_BTN, DIALOG_BACK_BTN ]+ buttons;
        //omit DIALOG_BACK_BTN in line above  if not offering

    }
    else {
        buttons = [
            PREV_PG_DIALOG_PREFIX + (string)prevPage,
            DIALOG_BACK_BTN, NEXT_PG_DIALOG_PREFIX+(string)nextPage, DIALOG_DONE_BTN
                ]+buttons;
        //omit DIALOG_BACK_BTN in line above if not offering
    }
    llDialog(ID, "Page "+(string)pageNum+"\nChoose one:", buttons, menuChannel);
}


CancelListen() {
    llListenRemove(listen_id);
    llSetTimerEvent(3600);
    mode = TRUE;
}


list shrink(list in)
{
    list out;
    integer i;
    integer j = llGetListLength(in);
    for (; i < j; i++)
    {
        out += llGetSubString( llList2String(in,i), 0, 23);// V1.1 longer names
    }
    return out;
}

setStation()
{
    llOwnerSay("Station set to " + genre + ":" + station + ":" + url);
    llSetParcelMusicURL(url);
}

getCategories()
{
    type = 1;
    busy = TRUE;
    string url = "http://metaverse.mitsi.com/cgi/shoutcast.plx?search=1";
    http_request_id = llHTTPRequest(url, [], "");
}

getCategory()
{
    type = 2;
    busy = TRUE;
    string url = "http://metaverse.mitsi.com/cgi/shoutcast.plx?genre=" + llEscapeURL(genre);

    //    llOwnerSay(url);

    http_request_id = llHTTPRequest(url, [], "");
}

getURL()
{
    type = 3;
    busy = TRUE;
    string url = "http://metaverse.mitsi.com/cgi/shoutcast.plx?genre=" + llEscapeURL(genre) + "&station=" + llEscapeURL(station);

    //llOwnerSay(url);

    http_request_id = llHTTPRequest(url, [], "");
}



default {

    on_rez(integer start_param)
    {
        llResetScript();
    }

    state_entry()
    {
        getCategories();
        pageNum = 1;
    }



    touch_start(integer touchNumber)
    {
        user =  llDetectedKey(0);
        if (!busy)
        {
            DIALOG_CHOICES = [pubpriv,"Categories","Show URL"];
            giveDialog(user, pageNum);
        }
        else
        {
            llOwnerSay("Still loading stations, please wait a moment");
        }
    }

    listen(integer channel, string name, key id, string message)
    {
        integer where ;
        if (message == "-")
        {
            giveDialog(user, pageNum);
        }
        else if ( message == DIALOG_DONE_BTN)
        {
            CancelListen();
            return;
        }
        else if (message == DIALOG_BACK_BTN)
        {
            pageNum = 1;

            DIALOG_CHOICES = lCategories;
            giveDialog(user, pageNum);
        }
        else if (llSubStringIndex(message, PREV_PG_DIALOG_PREFIX) == 0)
        {
            pageNum = (integer)llGetSubString(message, llStringLength(PREV_PG_DIALOG_PREFIX), -1);
            giveDialog(user, pageNum);
        }
        else if (llSubStringIndex(message, NEXT_PG_DIALOG_PREFIX) == 0)
        {
            pageNum = (integer)llGetSubString(message, llStringLength(NEXT_PG_DIALOG_PREFIX), -1);
            giveDialog(user, pageNum);

        } else { //this is the section where you do stuff
                if (message == "Categories")
                {
                    DIALOG_CHOICES = lCategories;
                    giveDialog(user, pageNum);
                }
            else if (message == "Public")
            {
                pubpriv = "Private";
                pageNum = 1;
                DIALOG_CHOICES = lCategories;
                giveDialog(user, pageNum);

            }
            else if (message == "Private")
            {
                pubpriv = "Public";
                DIALOG_CHOICES = lCategories;
                pageNum = 1;
                giveDialog(user, pageNum);
            }
            else if (message == "Show URL")
            {
                string url = llGetParcelMusicURL();
                if (pubpriv == "Public")
                {
                    llSay(0,"Parcel URL is " + url);
                }
                else
                {
                    llOwnerSay("Parcel URL is " + url);
                }

                pageNum = 1;

                giveDialog(user, pageNum);

            }
            else
            {
                CancelListen();

                where = llListFindList(lCategories,[message]);
                if (where >= 0)
                {
                    genre = message;
                    getCategory();
                    return;
                }

                where = llListFindList(lStations,[message]);
                if (where >= 0)
                {
                    station = message;
                    getURL();
                }
            }
        }
    }

    http_response(key request_id, integer status, list metadata, string body)
    {
        if (request_id == http_request_id)
        {
            busy = FALSE;
            if (type == 1)
            {
                lCategories = llParseString2List(body,["|"],[]);
                lCategories= shrink(lCategories);
                DIALOG_CHOICES = lCategories;

            }
            else if (type == 2)
            {
                lStations = llParseString2List(body,["|"],[]);
                lStations= shrink(lStations);
                DIALOG_CHOICES = lStations;
                pageNum = 1;
                giveDialog(user, pageNum);
            }
            else if (type == 3)
            {
                url = body;
                setStation();
            }

        }
    }


    timer()
    {
        if (mode)
        {
            getCategories() ;
        }
        else
        {
            llListenRemove(listen_id);
            llWhisper(0, "Sorry. The menu timed out, click me again to change stations.");
            mode = TRUE;
            llSetTimerEvent(3600.0); //Stop the timer from being called repeatedly
        }

    }

}
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

open/close curtain

Post by Constance Peregrine »

or other handy uses:

[not tested in Kitely, per se, but in OS 7.6]

Code: Select all

//When touched the prim is retracted towards one end and when touched again stretched back out.
//
//Prim moves/changes size along the local coordinate specified in the offset vector below.
//
//To change the overall size, edit the prim when stretched out and reset the script when done. 
//
//The script works both in unlinked and linked prims.
//
// Copyright (C) 2008 Zilla Larsson
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License version 3, as 
//    published by the Free Software Foundation.
//
//    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, see <http://www.gnu.org/licenses/>
 
 
vector offset = <0.0,1.0,0.0>; //Prim moves/changes size along this local coordinate
float hi_end_fixed = TRUE; //Which end of the prim should remain in place when size changes?          
                            //The one with the higher (local) coordinate? 
float min = 0.25; //The minimum size of the prim relative to its maximum size
integer ns = 4; //Number of distinct steps for move/size change
 
 
default {
    state_entry() {
        offset *= ((1.0 - min) / ns) * (offset * llGetScale());
        hi_end_fixed -= 0.5;
    }
 
    touch_start(integer detected) {
        integer i;
        do  llSetPrimitiveParams([PRIM_SIZE, llGetScale() - offset,
                PRIM_POSITION, llGetLocalPos() + ((hi_end_fixed * offset) * llGetLocalRot())]);
        while ((++i) < ns);           
        offset = - offset;
    }
}
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

poseball

Post by Constance Peregrine »

not confirmed in Kitely but works in 7.6 OS

Code: Select all

// Jippen Faddoul's Poseball script - Low ram/lag posepall thats just drag-and drop simple
// Copyright (C) 2007 Jippen Faddoul
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License version 3, as 
//    published by the Free Software Foundation.
//
//    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, see <http://www.gnu.org/licenses/>



//This text will appear in the floating title above the ball
string TITLE="";            
//You can play with these numbers to adjust how far the person sits from the ball. ( <X,Y,Z> )
vector offset=<0.0,0.0,0.3>;            

///////////////////// LEAVE THIS ALONE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
string ANIMATION;
integer visible = TRUE;
key avatar;

vector COLOR = <1.0,1.0,1.0>;
float ALPHA_ON = 1.0;
float ALPHA_OFF = 0.0;

show(){
    visible = TRUE;
    llSetText(TITLE, COLOR,ALPHA_ON);        
    llSetAlpha(ALPHA_ON, ALL_SIDES);
}

hide(){
    visible = FALSE;
    llSetText("", COLOR,ALPHA_ON);        
    llSetAlpha(ALPHA_OFF, ALL_SIDES);
}

default{
    state_entry() {
        llSitTarget(offset,ZERO_ROTATION);
        if((ANIMATION = llGetInventoryName(INVENTORY_ANIMATION,0)) == ""){
            llOwnerSay("Error: No animation");
            ANIMATION = "sit";
            }
        llSetSitText(TITLE);
        show();
    }

    touch_start(integer detected) {
        //llOwnerSay("Memory: " + (string)llGetFreeMemory());
        if(visible){ hide(); }
        else       { show(); }
    }

    changed(integer change) {
        if(change & CHANGED_LINK) {
            avatar = llAvatarOnSitTarget();
            if(avatar != NULL_KEY){
                //SOMEONE SAT DOWN
                hide();
                llRequestPermissions(avatar,PERMISSION_TRIGGER_ANIMATION);
                return;
            }else{
                //SOMEONE STOOD UP
                if (llGetPermissionsKey() != NULL_KEY){ llStopAnimation(ANIMATION); }
                show();
                return;
            }
        }
        if(change & CHANGED_INVENTORY) { llResetScript(); }
        if(change & CHANGED_OWNER)     { llResetScript(); }
    }

    run_time_permissions(integer perm) {
        if(perm & PERMISSION_TRIGGER_ANIMATION) {
            llStopAnimation("sit");
            llStartAnimation(ANIMATION);
            hide();
        }
    }
}


Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
User avatar
Constance Peregrine
Posts: 2349
Joined: Sun Dec 23, 2012 11:35 am
Has thanked: 2778 times
Been thanked: 1482 times

book

Post by Constance Peregrine »

Ok, well, this one will take more tech skills than I have to make it work properly, so I did not test it in Kitely, specifically as I would have to bring stuff in and that takes time and energy and stuffs...but it does work in OS 7.6 elsewhere.

It's a cool script to have and someone passed it out free recently. Script first, and nc next.

Script called "book" nc called "Book.CFG" if that makes any difference and if it is case sensitive also.

Code: Select all

// ----------------------------------------------------------------
// Script Title:    1-Prim Book
// Created by:      WhiteStar Magic
// Creation Date:   Feb.06.2012
// Platforms:
//    SecondLife:    Not Tested
//    OpenSim:       Yes 
//
// Revision:        V.0.3
// Revision History:
//
// Origination:
// Initially Based loosely off the Improved book script Script @ http://forums.osgrid.org/viewtopic.php?f=5&t=2400
//
// Revision Contributors: 
// WhiteStar V.0.3 March.23.2012
// - small mod, adding BLANK_TEXTURE @ end of pages list IF the list is an odd number
//   corrects for the last page not being shown properly if odd pages in list
// WhiteStar V.0.2
// - Streamlined page handling
// - Divided pages up so each inside face holds a full texture
// - Modified texture pre-caching to use "spine & bottom" edges to preload up coming textures
// - added facility to use front & back covers
// - add states for "run" and "GET_NOTECARDS"
// - Installed Notecard reader facility to eliminate script from having to be edited.
// -    Size=    allows use of REG, LG & XLG book sizes depending on material
// -    CoverFR= for front Cover entry into NoteCard
// -    CoverBK= for back Cover entry into NoteCard
// -    Page=    to specify the pages. 1 per line using name(if contained in prim) or UUID, in sequential order.  Page-1, Page-2 Page-3 etc
//
// ================================================================
// ** SCRIPT NOTES **
//
// drop script & notecard into a BOX prim and it will set up.
// edit the Book.CFG and add the texture UUID's or Texture Names if contained in prim.
// -- sit back & enjoy your new book.
//================================================================
// ** Licence ** 
// !Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) 
// http://creativecommons.org/licenses/by-nc-sa/3.0/
//================================================================
// adjust below to make book only respond to owner
integer OWNER_ONLY  = FALSE;  // default FALSE allows anyone to use book
//
// ====================================== \\
// Make changes below at your own peril ! \\
// ====================================== \\
//
// Global Variables
vector  sz_open;    // open & closed changed in notecard reader
vector  sz_closed;
vector  sz_reg_o    = <0.050,1.00,0.75>;    // reg sizes
vector  sz_reg_c    = <0.025,0.50,0.75>;
vector  sz_lg_o     = <0.050,1.50,1.00>;    // lg sizes
vector  sz_lg_c     = <0.025,0.75,1.00>;
vector  sz_xlg_o    = <0.050,3.00,2.00>;    // xlg sizes
vector  sz_xlg_c    = <0.025,1.50,2.00>;
//
list    pcut_close  = [PRIM_TYPE, PRIM_TYPE_BOX, 0, <0.0,1.0,0.0>, 0.0, <0.0,0.0,0.0>, <1.0,1.0,1.0>, <0.0,0.0,0.0>];
list    pcut_open   = [PRIM_TYPE, PRIM_TYPE_BOX, 0, <0.0,0.700,0.0>, 0.0, <0.0,0.0,0.0>, <1.0,1.0,1.0>, <0.0,0.0,0.0>];
//      FR=Front, BK=Back covers. from notecard. UUID or TextureName if contained
string  cover_FR;
string  cover_BK;
//
string  bookstate   = "closed";
string  bookconfig  = "Book.CFG";
key     NChandle    = NULL_KEY;
integer line        = 0;
//
list    Lst_pages;          // page= data from notecard (uuid or name)
integer page_qty;           // # of pages in Lst_pages
integer page_crnt   = 0;
integer page_next   = 1;
//
integer tLT         = 6;    // Left page Touchface
integer tRT         = 5;    // Right page Touchface
float   timer_delay = 5.0;
//
// ==================== \\
// SCRIPT STARTS HERE ! \\
//======================\\
set_pages() // set textures for both inner pages
{
    key Lt_pg = (key)llList2String(Lst_pages,page_crnt);     // ODD Pages on left
    key Rt_pg = (key)llList2String(Lst_pages,(page_crnt+1)); // EVEN pages on Right
    llSetPrimitiveParams([PRIM_TEXTURE, 5, Rt_pg, <1.0,1.0,0.0>, <0.0,0,0>, 0.0]); // Right Face: full image 
    llSetPrimitiveParams([PRIM_TEXTURE, 6, Lt_pg, <1.0,1.0,0.0>, <0.0,0,0>, 0.0]); // Left Face: full image
}

pre_cache()
{
    llSetTimerEvent(0.0);       // do this only once
    if(bookstate=="closed") return;
    key oddcache=llList2Key(Lst_pages,page_next+1);
    key evencache=llList2Key(Lst_pages,page_next+2);
    //llSetColor(<0,0,0>, 3);   // colour over left face
    llSetTexture(oddcache,3);  // left face edge (spine) when open
    //llSetColor(<0,0,0>, 4);   // colour over bottom face
    llSetTexture(evencache,4); // bottom face edge when open
}

openbook()
{
    bookstate="open";
    llSetPrimitiveParams([PRIM_SIZE, sz_open]); // set new size
    llSetPrimitiveParams(pcut_open);               // set the cut params
    llSetPrimitiveParams([PRIM_TEXTURE, 2, cover_BK, <2.0,1.0,0.0>, <0.50,0,0>, 0.0]); // set back cover & scale for display on new prim form
}

closebook()
{
    bookstate="closed";
    page_crnt=0;
    page_next=1;
    //
    llSetPrimitiveParams([PRIM_SIZE, sz_closed]);
    llSetPrimitiveParams(pcut_close);    
    llSetPrimitiveParams([PRIM_TEXTURE, 4, cover_FR, <1.0,1.0,0.0>, <0.0,0,0>, 0.0]);  // Front Cover
    llSetPrimitiveParams([PRIM_TEXTURE, 2, cover_BK, <1.0,1.0,0.0>, <0.0,0,0>, 0.0]);  // Back Cover, rescaled for prim form
    //
    //llSetColor(<1.0,1.0,1.0>, 4);  // re-colour cover white IF bottom face edge was blackened in pre_cache()
    //
    llSetTexture(TEXTURE_BLANK,0); // top face edge
    llSetTexture(TEXTURE_BLANK,1); // rigt side edge
    llSetTexture(TEXTURE_BLANK,3); // left side edge (spine)
    llSetTexture(TEXTURE_BLANK,5); // bottom face adge
}

// START //
default
{
    state_entry()
    {
        state GET_NOTECARDS;
    }
}
// RUNNING //
state run
{
    state_entry()
    {
        closebook();
        llOwnerSay("[ "+ llGetListLength(Lst_pages)+" ] Pages loaded. Ready, click on cover to read");
        page_qty = llGetListLength(Lst_pages);
        float d = ((float)page_qty / 2);
        integer e = (page_qty / 2);
        if((float)d != (float)e) {Lst_pages += [TEXTURE_BLANK]; page_qty = llGetListLength(Lst_pages);} // ODD # so add BLANK TEXTURE to make EVEN #

    }

    touch_start(integer num_times)
    {
        if(OWNER_ONLY && llDetectedKey(0)!=llGetOwner()) return; // only owner is set, to ignore others
        //
        if(bookstate=="closed")
        {
            openbook();
            set_pages();
            pre_cache();
        }
        else if(bookstate=="open")
        {
            if(llDetectedTouchFace(0) == tRT) // RTface touched
            {
                page_crnt=page_crnt + 2; 

                if(page_crnt>(page_qty-2)) 
                {
                    closebook();
                }
                else
                {
                    set_pages();
                    page_next = page_crnt+1;
                }

                if ( page_next < llGetListLength(Lst_pages) )
                {
                    llSetTimerEvent(timer_delay);
                }
                else llSetTimerEvent(0.0);
            }
            else if(llDetectedTouchFace(0) == tLT) // LTface touched
            {
                page_crnt=page_crnt - 2; 
                if(page_crnt< 0)
                {
                    closebook();
                }
                else
                {
                    set_pages();
                    page_next = page_crnt-1;
                }
                if ( page_next < llGetListLength(Lst_pages) )
                {
                    llSetTimerEvent(timer_delay);
                }
                else llSetTimerEvent(0.0);
            }
        }
    }

    timer()
    {
        pre_cache();            // preload next page after a delay
    }

    changed(integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llOwnerSay("The inventory changed. Restarting book");
            llResetScript();
        }
        if (change & 1024) llResetScript();
    }
}
//-------------------\\
// Get Notecard Data \\
//-------------------\\
state GET_NOTECARDS
{
    state_entry()
    {
        line = 0;
        NChandle = llGetNotecardLine(bookconfig, 0);
    }
    dataserver(key query_id, string data)
    {
        if(query_id == NChandle) // Filtering the call
        {

            if (data == EOF)
            {
                state run;
            }
            else
            {
                data = llStringTrim(data, STRING_TRIM_HEAD);
                if (llGetSubString (data, 0, 0) != "#") // If it's # skip the line, it's a comment
                {
                    integer s = llSubStringIndex(data, "=");
                    if(~s) // does it have an "=" in it? if YES it's Valid!
                    {
                        string token = llToLower(llStringTrim(llDeleteSubString(data, s, -1), STRING_TRIM)); // trim up token & lower case it
                        data = llStringTrim(llDeleteSubString(data, 0, s), STRING_TRIM);

                        if(token == "size")             // Set Sizing
                        {
                            if(llToLower(data)=="reg")
                            {
                                sz_closed  = sz_reg_c;
                                sz_open    = sz_reg_o;
                            }
                            else if(llToLower(data)=="lg")
                            {
                                sz_closed  = sz_lg_c;
                                sz_open    = sz_lg_o;
                            }
                            else if(llToLower(data)=="xlg")
                            {
                                sz_closed  = sz_xlg_c;
                                sz_open    = sz_xlg_o;
                            }
                        }

                        if (token == "coverfr")         // Set Front Cover
                        {
                            if(data=="") llOwnerSay("CoverFR= is not identified in "+bookconfig+" No Front Cover will be shown");
                            else cover_FR = data;
                        }
                        else if (token == "coverbk")    // Set Back Cover
                        {
                            if(data=="") llOwnerSay("CoverBK= is not identified in "+bookconfig+" No Back Cover will be shown");
                            else cover_BK = data;
                        }
                        else if (token == "page")
                        {
                            if(data !="")
                            {
                                //llOwnerSay("The Data is: "+(string)data);
                                Lst_pages += [data];

                            }
                            else llOwnerSay("Loading Page= from "+bookconfig+" NoteCard: Data is Empty ! No Pages Available");
                        }
                    }
                }
                NChandle = llGetNotecardLine(bookconfig,++line);
            }
        }
    }
}

Code: Select all

# 1-Prim Book V.0.2 Configuration File
# by WhiteStar Magic  Feb.06.2012
# the # symbol is a COMMENT.  These lines are ignored
#
# size=   reg, lg, xlg
#       reg    =  (0.50m W x 0.75m H) closed    -- (1.00m W x 0.75m H)
#       lg       =   (0.75m W x 1.00m H) closed  -- (1.50m W x 1.00m H)
#       xlg     =   (1.50m W x 2.00m H) closed  -- (3.00m W x 2.00m H)
#
#  CoverFR= Front Cover of book.   Texture UUID or ( Texture Name if contained in book prim. )
#  CoverBK= Back Cover of book.  Texture UUID or ( Texture Name if contained in book prim. )
#
#  Page= Texture UUID or ( Texture Name if contained in book prim. )
#        NOTE:  Pages must be in sequence, 1,2,3,4,5 etc....
#  SPECIAL NOTE !!!   
#   IF using UUID then DO NOT INCLUDE <>  Just the UUID Only
#   IF using Texture Name place the name in "quotes"  DO NOT INCLUDE <> 
# ============================================
size=reg
CoverFR=rez_2014-01_00
CoverBK=TEXTURE_BLANK
#
##  insert your pages below, in sequence from 1,2,3,4 etc
#
Page=rez_2014-01_01
Page=rez_2014-01_02
Page=rez_2014-01_03
Page=rez_2014-01_04
Page=rez_2014-01_05
Page=rez_2014-01_06
Page=rez_2014-01_07
Page=rez_2014-01_08
Page=rez_2014-01_09
Page=rez_2014-01_10
Page=rez_2014-01_11
Page=rez_2014-01_12
Laissez faire et laissez passer, le monde va de lui même!
My little sounds store https://www.kitely.com/market?store=2040306

Ephemeral wanderer...
Post Reply