CasperLet/OpenSourceScripts: Difference between revisions

From CasperTech Wiki
Jump to navigation Jump to search
 
(31 intermediate revisions by 2 users not shown)
Line 1: Line 1:
= '''<span style="color:#00528c">Cautions & Warnings</span>''' =  
{|align=right
  |__TOC__
  |}
 
= '''<span style="color:#00528c">CasperLet API</span>''' =
See the '''[[CasperLet/API | CasperLet API]]''' page for details and other sample scripts that are not on this page.
 
= '''<span style="color:#00528c">Open Source Cautions & Warnings</span>''' =  
{{Critical|Both the door and sign objects (and thus their full perm scripts) are provided "As-Is", as a tool for scripters to use, without warranty, guarantee or support. This also means CasperTech is '''NOT''' under any obligation to add any new features.'''}}
{{Critical|Both the door and sign objects (and thus their full perm scripts) are provided "As-Is", as a tool for scripters to use, without warranty, guarantee or support. This also means CasperTech is '''NOT''' under any obligation to add any new features.'''}}


== '''<span style="color:#00528c">Making a product using these scripts?</span>''' ==
= '''<span style="color:#00528c">Making a product using these scripts?</span>''' =


{{Information|Casper Warden requests that if you use these scripts in a more advanced product and set it up for sale that you let him know, send him a vendor for the final product, and he'll help promote it.}}
{{Information|Casper Warden requests that if you use these scripts in a more advanced product and set it up for sale that you let him know, send him a vendor for the final product, and he'll help promote it.}}


=== Sample Door Script (Unsupported) ===
== '''<span style="color:#00528c">Sample Door Script (Unsupported)</span>''' ==
----
You may '''informally''' ask in the CasperTech support group if you get stuck, of course, but remember that that CasperTech will not be adding new features to these scripts - this is why they're open-source and full perm. Chances are there's a scripter in the group who might be willing to help, or you can see if there's a scripter already on your team.


==== Using the door script as-is ====
=== Using the door script as-is ===
----
----
You may '''informally''' ask in the CasperTech support group if you get stuck, of course, but remember that that CasperTech will not be adding new features to these scripts - this is why they're open-source and full perm. Chances are there's a scripter in the group who might be willing to help, or you can see if there's a scripter already on your team.
Naturally, you're welcome to use them without restriction. To use them as-is (applies to both door and sign):


# Rez the door near the CasperLet unit
# Rez the door near the CasperLet unit
Line 22: Line 26:
# The door should now function as most doors will, save that it will automatically restrict itself to the current CasperLet tenant when rented.  
# The door should now function as most doors will, save that it will automatically restrict itself to the current CasperLet tenant when rented.  


The door will still work from within a linkset.
The door DOES work from within a linkset - feel free to link the door to your build.
 
The script, by default, rotates the door on the "Z" axis. (This is always the BLUE arrow when you right-click > edit the object inworld.)


==== Door script code ====
=== Errors ===
----
----
If the door is not linked properly, or the script has been stopped, the door will not work for the tenant. The system owner (not the managers) must be the one to properly link the door to the rental unit.


=== Sample Sign Script (Unsupported) ===
==== Door script code v1.13 ====
----
----
<syntaxhighlight lang="lsl">
// THIS IS A FULL PERM DOOR DEMO SHOWING INTERACTIONS WITH CASPERLET UNITS.
// IT USES THE v2 API, AND THUS REQUIRES CASPERLET v1.10 OR HIGHER.
// BSD LICENSE.
// - Casper Warden
string owner="";
integer open=FALSE;
integer waitingforping = FALSE;
key candidate = "";
key listeningunit = NULL_KEY;
list additionaltenants=[];
default
{
    state_entry()
    {
        llListen(77777, "", "", "");
    }
    listen(integer channel, string name, key id, string message)
    {
        if (llGetOwnerKey(id)==llGetOwner() && id != llGetOwner())
        {
            list tmp = llParseString2List(message,["|"],[]);
            list tmp2 = llParseString2List(message,["@"],[]);
            if (llList2String(tmp2,0)=="ADDTNTS")
            {
                if (id == listeningunit)
                {
                    tmp2 = llParseString2List(llList2String(tmp2,1),["#"],[]);
                    additionaltenants=[];   
                    integer x;
                    for(x=0; x<llGetListLength(tmp2); x=x+2)
                    {
                        additionaltenants+=[llList2Key(tmp2, x)]; 
                    }
                } 
            }
            if (llList2String(tmp,0)=="REXTR")
            {
                if (waitingforping)
                {
                    waitingforping = FALSE;
                    candidate = id;
                    llParticleSystem([7, 6.0, 1, <1,1,1>, 3, <0,0,1>, 2, 1.0, 4, 0.5, 5, <0.07, 0.07, 0.1>, 6, <0.1,0.1,0.1>, 13, 0.01, 15, 2, 16, 0.1, 17, 3.0, 18, 3.0, 8, <0,0,-0.4>, 22, 0.0, 23, PI, 21, <0,0,1>, 19, 0.0, 0, PSYS_PART_EMISSIVE_MASK | PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_TARGET_POS_MASK | PSYS_PART_TARGET_LINEAR_MASK, 9, PSYS_SRC_PATTERN_DROP, 20, id, 12, "chain"]);
                    llDialog(llGetOwner(),"Please watch the particles emitting from the door. Are they going to the correct unit?",["YES","NO"],77777);
                }
                else if (id == listeningunit)
                {
                    key user = llList2Key(tmp,2);
                    if (user != NULL_KEY)
                    {
                        owner = user;
                    }   
                    else
                    {
                        additionaltenants=[];
                        owner = llGetOwner();   
                    }
                } 
            }
        }
        else if (id == llGetOwner() && candidate != "")
        {
            llParticleSystem([]);
            if (message == "YES")
            {
              owner = llGetOwner();
              llRegionSay(-77777, "CLAPI"+(string)candidate+"-Reset|"+(string)owner+"|0");   
              listeningunit = candidate;
            }
            candidate = "";
        } 
    }
    on_rez(integer j)
    {
        llResetScript();   
    }
    touch_start(integer j)
    {
        for(j--; j>-1; j--)
        {
            if (llDetectedKey(j)==llGetOwner() && owner == "")
            {
                waitingforping = TRUE;
                llDialog(llGetOwner(), "Please touch the rental unit that you want to link to this door.",["OK"],-1);
            }
            else
            {
                integer found = llListFindList(additionaltenants,[llDetectedKey(j)]);
                if (llDetectedKey(j)!=owner && llDetectedKey(j) != llGetOwner() && found==-1)
                {
                    llPlaySound("f6ffb2dc-b880-ef60-e958-541d1493f813", 1.0);
                    llInstantMessage(llDetectedKey(j),"You have no permission to use this door."); 
                }
                else
                {
                    open=!open;
                    if (open)
                    {
                        llPlaySound("8f438543-a18a-236f-9e97-629f18d852c7", 0.7);
                       
                        //This stuff makes sure it works well as part of a linkset too
                       
                        vector axis=<0.0,0.0,1.0>;
                        axis=axis*llGetLocalRot();
                        rotation test=llAxisAngle2Rot(axis, 1.570796);
                        llSetLocalRot(llGetLocalRot() / test);
                    }
                    else
                    {
                        llPlaySound("cf33a3f9-6b15-351d-af15-b71e1b0e36bb", 0.7);
                       
                        //This stuff makes sure it works well as part of a linkset too
                       
                        vector axis=<0.0,0.0,1.0>;
                        axis=axis*llGetLocalRot();
                        rotation test=llAxisAngle2Rot(axis, 1.570796);
                        llSetLocalRot(llGetLocalRot() * test);
                    }
                }
            }
        }
    }
}
</syntaxhighlight>
== '''<span style="color:#00528c">Sample Sign Script (Unsupported)</span>''' ==
You may '''informally''' ask in the CasperTech support group if you get stuck, of course, but remember that that CasperTech will not be adding new features to these scripts - this is why they're open-source and full perm. Chances are there's a scripter in the group who might be willing to help, or you can see if there's a scripter already on your team.


==== Landlords: Using the sign as-is ====
=== Landlords: Using the sign as-is ===
----
----
# Rez the sign near the CasperLet unit,  
# Rez the sign near the CasperLet unit,  
Line 39: Line 177:
# The sign will now be linked to the rental, and only allow the tenant to change the texture
# The sign will now be linked to the rental, and only allow the tenant to change the texture


==== Tenant usage of properly linked sign ====
=== Tenants: Using properly linked sign ===
----
----
# Customer pays the associated rental unit to begin a rental.
# Tenant pays the associated rental unit to begin a rental.
# Customer clicks sign, gets '''''"Please HOLD DOWN CONTROL and drag the texture..."''''' message.
# Tenant clicks sign, gets '''''"Please HOLD DOWN CONTROL and drag the texture..."''''' message in local chat.
# Texture must be set by the renter as FULL PERM to NEXT OWNER
# Texture must be set by the renter as FULL PERM to NEXT OWNER
# Customer then CTL + drags the proper texture over to the sign.  
# Customer then CTL + drags the proper texture over to the sign.  
# If customer drags the wrong texture, they need to repeat steps 3 and 4 to change the texture.
# If customer drags the wrong texture, they need to repeat steps 3 and 4 to change the texture.


New texture is NOT stored within the rental unit or the sign - the script calls it by the UUID, which is why the texture needs to be set to full perms.  
New texture is NOT stored within the rental unit or the sign - the script calls it by the UUID, which is why the texture needs to be set to full perms.


==== Error message ====
=== Error message ===
----
----
If the message on the tenant's click changes to '''''"This store is available! If you pay the rental meter below..."''''' then the CasperLet system owner needs to properly link the sign.
If the message on the tenant's click changes to '''''"This store is available! If you pay the rental meter below..."''''' then the CasperLet system owner (not the managers) needs to properly link the sign.


==== Sign script code v1.13 ====
----
<syntaxhighlight lang="lsl" >


==== Sign script code ====
// THIS IS A FULL PERM SIGN DEMO SHOWING INTERACTIONS WITH CASPERLET UNITS.
----
// IT USES THE v2 API, AND THUS REQUIRES CASPERLET v1.10 OR HIGHER.
// BSD LICENSE.
// - Casper Warden


=== CasperLet API ===
string owner = "";
----
integer waitingforping = FALSE;
See the '''[[CasperLet/API | CasperLet API]]''' page for details.
key candidate = "";
key listeningunit = NULL_KEY;
integer dropping = FALSE;
list additionaltenants=[];
default
{
    state_entry()
    {
        llListen(77777, "", "", "");
    }
    on_rez(integer j)
    {
        llResetScript();   
    }
    listen(integer channel, string name, key id, string message)
    {
        if (llGetOwnerKey(id)==llGetOwner() && id != llGetOwner())
        {
            list tmp = llParseString2List(message,["|"],[]);
            list tmp2 = llParseString2List(message,["@"],[]);
            if (llList2String(tmp2,0)=="ADDTNTS")
            {
                if (id == listeningunit)
                {
                    tmp2 = llParseString2List(llList2String(tmp2,1),["#"],[]);
                    additionaltenants=[];   
                    integer x;
                    for(x=0; x<llGetListLength(tmp2); x=x+2)
                    {
                        additionaltenants+=[llList2Key(tmp2, x)]; 
                    }
                } 
            }
            if (llList2String(tmp,0)=="REXTR")
            {
                if (waitingforping)
                {
                    waitingforping = FALSE;
                    candidate = id;
                    llParticleSystem([7, 6.0, 1, <1,1,1>, 3, <0,0,1>, 2, 1.0, 4, 0.5, 5, <0.07, 0.07, 0.1>, 6, <0.1,0.1,0.1>, 13, 0.01, 15, 2, 16, 0.1, 17, 3.0, 18, 3.0, 8, <0,0,-0.4>, 22, 0.0, 23, PI, 21, <0,0,1>, 19, 0.0, 0, PSYS_PART_EMISSIVE_MASK | PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_TARGET_POS_MASK | PSYS_PART_TARGET_LINEAR_MASK, 9, PSYS_SRC_PATTERN_DROP, 20, id, 12, "chain"]);
                    llDialog(llGetOwner(),"Please watch the particles emitting from the sign. Are they going to the correct unit?",["YES","NO"],77777);
                }
                else if (id == listeningunit)
                {
                    key user = llList2Key(tmp,2);
                    if (user != NULL_KEY)
                    {
                        if (owner != user)
                        {
                            owner = user;
                            llInstantMessage(owner,"Hey, thanks for renting with us! If you want, you can now touch the sign above your store and drop your own texture into it!");
                        }
                    }   
                    else
                    {
                        additionaltenants=[];
                        owner = llGetOwner(); 
                        llSetTexture("bb795fc1-1cf3-81a4-d878-ab828c46d3f5",1);
                    }
                } 
            }
        }
        else if (id == llGetOwner() && candidate != "")
        {
            llParticleSystem([]);
            if (message == "YES")
            {
              owner = llGetOwner();     
              llRegionSay(-77777, "CLAPI"+(string)candidate+"-Reset|"+(string)owner+"|0");
              listeningunit = candidate;
            }
            candidate = "";
        } 
    }
    touch_start(integer j)
    {
        for(j--; j>-1; j--)
        {
            integer found = llListFindList(additionaltenants,[llDetectedKey(j)]);
            if (llDetectedKey(j)==llGetOwner() && owner == "")
            {
                waitingforping = TRUE;
                llDialog(llGetOwner(), "Please touch the rental unit that you want to link to this sign.",["OK"],-1);             
                llSetTimerEvent(300);
            }
            else if (llDetectedKey(j) == owner || found!=-1)
            {   
                llAllowInventoryDrop( TRUE );
    dropping = TRUE;
                llInstantMessage(llDetectedKey(j),"Please HOLD DOWN CONTROL and drag the texture onto the sign now.  Please remember - It must be full perm!");
            }
            else if (owner == "" || owner == llGetOwner())
            {
                llInstantMessage(llDetectedKey(j),"This store is available! If you pay the rental meter below, you can put your own logo into this sign!");   
            }
            else
            {
                llInstantMessage(llDetectedKey(j),"Sorry, this sign is in use by someone else!");   
            }
        }
    }
    timer()
    {
        dropping = FALSE;
        llSetTimerEvent(0.0);
        llAllowInventoryDrop( FALSE );
        llInstantMessage(owner,"Sorry, you took too long! Please touch if you want to try again.");
    }
    changed(integer j)
    {
        if ((j & CHANGED_ALLOWED_DROP || j & CHANGED_INVENTORY) && dropping )
        {
            j = llGetInventoryNumber(INVENTORY_ALL);
            for(j--; j>-1; j--)
            {
                string name = llGetInventoryName(INVENTORY_ALL,j);
                if (llGetInventoryType(name)!=INVENTORY_SCRIPT)
                {
                    if (llGetInventoryType(name)!=INVENTORY_SCRIPT)
                    {
                        if (llGetInventoryType(name)!=INVENTORY_TEXTURE)
                        {
                            llRemoveInventory(name);
                            llInstantMessage(owner,"That wasn't a texture! Try again!");   
                        }
                        else
                        {
                            integer perm = llGetInventoryPermMask(name,MASK_OWNER);
                            if (perm & PERM_COPY && perm & PERM_MODIFY && perm & PERM_TRANSFER)
                            {
                                dropping = FALSE;
                                llSetTimerEvent(0.0);
                                key tex = llGetInventoryKey(name);
                                llRemoveInventory(name);
                                llSetTexture(tex,1);
                               
                                llAllowInventoryDrop( FALSE );
                                llInstantMessage(owner,"Thanks.. that looks great! Touch if you want to try again"); 
                            }
                            else
                            {
                                llRemoveInventory(name);
                              llInstantMessage(owner,"That wasn't full perm! Try again!");   
                            } 
                        }
                    }
                } 
            }   
        }   
    }
  }
</syntaxhighlight>

Latest revision as of 18:34, 16 November 2020

CasperLet API

See the CasperLet API page for details and other sample scripts that are not on this page.

Open Source Cautions & Warnings

Both the door and sign objects (and thus their full perm scripts) are provided "As-Is", as a tool for scripters to use, without warranty, guarantee or support. This also means CasperTech is NOT under any obligation to add any new features.

Making a product using these scripts?

Casper Warden requests that if you use these scripts in a more advanced product and set it up for sale that you let him know, send him a vendor for the final product, and he'll help promote it.

Sample Door Script (Unsupported)

You may informally ask in the CasperTech support group if you get stuck, of course, but remember that that CasperTech will not be adding new features to these scripts - this is why they're open-source and full perm. Chances are there's a scripter in the group who might be willing to help, or you can see if there's a scripter already on your team.

Using the door script as-is


  1. Rez the door near the CasperLet unit
  2. Touch/click it
  3. Click the CasperLet unit you want to link the door to
  4. Click "Yes" on the popup menu
  5. Now click the CasperLet unit once more to send the most recent data
  6. The door should now function as most doors will, save that it will automatically restrict itself to the current CasperLet tenant when rented.

The door DOES work from within a linkset - feel free to link the door to your build.

The script, by default, rotates the door on the "Z" axis. (This is always the BLUE arrow when you right-click > edit the object inworld.)

Errors


If the door is not linked properly, or the script has been stopped, the door will not work for the tenant. The system owner (not the managers) must be the one to properly link the door to the rental unit.

Door script code v1.13


// THIS IS A FULL PERM DOOR DEMO SHOWING INTERACTIONS WITH CASPERLET UNITS.
// IT USES THE v2 API, AND THUS REQUIRES CASPERLET v1.10 OR HIGHER.
// BSD LICENSE.
// - Casper Warden

string owner="";
integer open=FALSE;
integer waitingforping = FALSE;
key candidate = "";
key listeningunit = NULL_KEY;
list additionaltenants=[];
default
{
    state_entry() 
    { 
        llListen(77777, "", "", "");
    }
    listen(integer channel, string name, key id, string message)
    {
        if (llGetOwnerKey(id)==llGetOwner() && id != llGetOwner())
        {
            list tmp = llParseString2List(message,["|"],[]);
            list tmp2 = llParseString2List(message,["@"],[]);
            if (llList2String(tmp2,0)=="ADDTNTS")
            {
                if (id == listeningunit)
                {
                    tmp2 = llParseString2List(llList2String(tmp2,1),["#"],[]);
                    additionaltenants=[];    
                    integer x;
                    for(x=0; x<llGetListLength(tmp2); x=x+2)
                    {
                        additionaltenants+=[llList2Key(tmp2, x)];   
                    }
                }   
            }
            if (llList2String(tmp,0)=="REXTR")
            {
                if (waitingforping)
                {
                    waitingforping = FALSE;
                    candidate = id;
                    llParticleSystem([7, 6.0, 1, <1,1,1>, 3, <0,0,1>, 2, 1.0, 4, 0.5, 5, <0.07, 0.07, 0.1>, 6, <0.1,0.1,0.1>, 13, 0.01, 15, 2, 16, 0.1, 17, 3.0, 18, 3.0, 8, <0,0,-0.4>, 22, 0.0, 23, PI, 21, <0,0,1>, 19, 0.0, 0, PSYS_PART_EMISSIVE_MASK | PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_TARGET_POS_MASK | PSYS_PART_TARGET_LINEAR_MASK, 9, PSYS_SRC_PATTERN_DROP, 20, id, 12, "chain"]);
                    llDialog(llGetOwner(),"Please watch the particles emitting from the door. Are they going to the correct unit?",["YES","NO"],77777); 
                }
                else if (id == listeningunit)
                {
                    key user = llList2Key(tmp,2);
                    if (user != NULL_KEY) 
                    {
                        owner = user; 
                    }    
                    else
                    {
                        additionaltenants=[];
                        owner = llGetOwner();    
                    }
                }   
            }
        }
        else if (id == llGetOwner() && candidate != "")
        {
            llParticleSystem([]);
            if (message == "YES")
            {
               owner = llGetOwner(); 
               llRegionSay(-77777, "CLAPI"+(string)candidate+"-Reset|"+(string)owner+"|0");    
               listeningunit = candidate; 
            }
            candidate = "";
        }  
    }
    on_rez(integer j)
    {
        llResetScript();    
    }
    touch_start(integer j)
    {
        for(j--; j>-1; j--)
        {
            if (llDetectedKey(j)==llGetOwner() && owner == "")
            {
                waitingforping = TRUE;
                llDialog(llGetOwner(), "Please touch the rental unit that you want to link to this door.",["OK"],-1);
            }
            else
            {
                integer found = llListFindList(additionaltenants,[llDetectedKey(j)]);
                if (llDetectedKey(j)!=owner && llDetectedKey(j) != llGetOwner() && found==-1) 
                {
                    llPlaySound("f6ffb2dc-b880-ef60-e958-541d1493f813", 1.0);
                    llInstantMessage(llDetectedKey(j),"You have no permission to use this door.");   
                } 
                else 
                {
                    open=!open;
                    if (open) 
                    {
                        llPlaySound("8f438543-a18a-236f-9e97-629f18d852c7", 0.7);
                        
                        //This stuff makes sure it works well as part of a linkset too
                        
                        vector axis=<0.0,0.0,1.0>;
                        axis=axis*llGetLocalRot();
                        rotation test=llAxisAngle2Rot(axis, 1.570796); 
                        llSetLocalRot(llGetLocalRot() / test); 
                    } 
                    else 
                    {
                        llPlaySound("cf33a3f9-6b15-351d-af15-b71e1b0e36bb", 0.7);
                        
                        //This stuff makes sure it works well as part of a linkset too
                        
                        vector axis=<0.0,0.0,1.0>;
                        axis=axis*llGetLocalRot();
                        rotation test=llAxisAngle2Rot(axis, 1.570796); 
                        llSetLocalRot(llGetLocalRot() * test); 
                    }
                }
            }
        }
    }
}

Sample Sign Script (Unsupported)

You may informally ask in the CasperTech support group if you get stuck, of course, but remember that that CasperTech will not be adding new features to these scripts - this is why they're open-source and full perm. Chances are there's a scripter in the group who might be willing to help, or you can see if there's a scripter already on your team.

Landlords: Using the sign as-is


  1. Rez the sign near the CasperLet unit,
  2. Touch/click it
  3. Click the CasperLet unit you want to link the door to
  4. Click "Yes" on the popup menu
  5. Now click the CasperLet unit once more to send the most recent data
  6. The sign will now be linked to the rental, and only allow the tenant to change the texture

Tenants: Using properly linked sign


  1. Tenant pays the associated rental unit to begin a rental.
  2. Tenant clicks sign, gets "Please HOLD DOWN CONTROL and drag the texture..." message in local chat.
  3. Texture must be set by the renter as FULL PERM to NEXT OWNER
  4. Customer then CTL + drags the proper texture over to the sign.
  5. If customer drags the wrong texture, they need to repeat steps 3 and 4 to change the texture.

New texture is NOT stored within the rental unit or the sign - the script calls it by the UUID, which is why the texture needs to be set to full perms.

Error message


If the message on the tenant's click changes to "This store is available! If you pay the rental meter below..." then the CasperLet system owner (not the managers) needs to properly link the sign.

Sign script code v1.13


// THIS IS A FULL PERM SIGN DEMO SHOWING INTERACTIONS WITH CASPERLET UNITS.
// IT USES THE v2 API, AND THUS REQUIRES CASPERLET v1.10 OR HIGHER.
// BSD LICENSE.
// - Casper Warden

string owner = "";
integer waitingforping = FALSE;
key candidate = "";
key listeningunit = NULL_KEY;
integer dropping = FALSE;
list additionaltenants=[];
default
{
    state_entry() 
    { 
        llListen(77777, "", "", "");
    }
    on_rez(integer j)
    {
        llResetScript();    
    }
    listen(integer channel, string name, key id, string message)
    {
        if (llGetOwnerKey(id)==llGetOwner() && id != llGetOwner())
        {
            list tmp = llParseString2List(message,["|"],[]);
            list tmp2 = llParseString2List(message,["@"],[]);
            if (llList2String(tmp2,0)=="ADDTNTS")
            {
                if (id == listeningunit)
                {
                    tmp2 = llParseString2List(llList2String(tmp2,1),["#"],[]);
                    additionaltenants=[];    
                    integer x;
                    for(x=0; x<llGetListLength(tmp2); x=x+2)
                    {
                        additionaltenants+=[llList2Key(tmp2, x)];   
                    }
                }   
            }
            if (llList2String(tmp,0)=="REXTR")
            {
                if (waitingforping)
                {
                    waitingforping = FALSE;
                    candidate = id;
                    llParticleSystem([7, 6.0, 1, <1,1,1>, 3, <0,0,1>, 2, 1.0, 4, 0.5, 5, <0.07, 0.07, 0.1>, 6, <0.1,0.1,0.1>, 13, 0.01, 15, 2, 16, 0.1, 17, 3.0, 18, 3.0, 8, <0,0,-0.4>, 22, 0.0, 23, PI, 21, <0,0,1>, 19, 0.0, 0, PSYS_PART_EMISSIVE_MASK | PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_TARGET_POS_MASK | PSYS_PART_TARGET_LINEAR_MASK, 9, PSYS_SRC_PATTERN_DROP, 20, id, 12, "chain"]);
                    llDialog(llGetOwner(),"Please watch the particles emitting from the sign. Are they going to the correct unit?",["YES","NO"],77777); 
                } 
                else if (id == listeningunit)
                {
                    key user = llList2Key(tmp,2);
                    if (user != NULL_KEY) 
                    {
                        if (owner != user)
                        {
                            owner = user; 
                            llInstantMessage(owner,"Hey, thanks for renting with us! If you want, you can now touch the sign above your store and drop your own texture into it!");
                        }
                    }    
                    else
                    {
                        additionaltenants=[];
                        owner = llGetOwner();   
                        llSetTexture("bb795fc1-1cf3-81a4-d878-ab828c46d3f5",1);
                    }
                }   
            }
        }
        else if (id == llGetOwner() && candidate != "")
        {
            llParticleSystem([]);
            if (message == "YES")
            {
               owner = llGetOwner();      
               llRegionSay(-77777, "CLAPI"+(string)candidate+"-Reset|"+(string)owner+"|0");
               listeningunit = candidate; 
            }
            candidate = "";
        }  
    }
    touch_start(integer j)
    {
        for(j--; j>-1; j--)
        {
            integer found = llListFindList(additionaltenants,[llDetectedKey(j)]);
            if (llDetectedKey(j)==llGetOwner() && owner == "")
            {
                waitingforping = TRUE;
                llDialog(llGetOwner(), "Please touch the rental unit that you want to link to this sign.",["OK"],-1);               
                llSetTimerEvent(300);
            }
            else if (llDetectedKey(j) == owner || found!=-1)
            {    
                llAllowInventoryDrop( TRUE );
    dropping = TRUE;
                llInstantMessage(llDetectedKey(j),"Please HOLD DOWN CONTROL and drag the texture onto the sign now.  Please remember - It must be full perm!");
            }
            else if (owner == "" || owner == llGetOwner())
            {
                llInstantMessage(llDetectedKey(j),"This store is available! If you pay the rental meter below, you can put your own logo into this sign!");    
            }
            else
            {
                llInstantMessage(llDetectedKey(j),"Sorry, this sign is in use by someone else!");    
            }
        }
    }
    timer()
    {
        dropping = FALSE;
        llSetTimerEvent(0.0);
        llAllowInventoryDrop( FALSE );
        llInstantMessage(owner,"Sorry, you took too long! Please touch if you want to try again.");
    }
    changed(integer j)
    {
        if ((j & CHANGED_ALLOWED_DROP || j & CHANGED_INVENTORY) && dropping )
        {
            j = llGetInventoryNumber(INVENTORY_ALL);
            for(j--; j>-1; j--)
            {
                string name = llGetInventoryName(INVENTORY_ALL,j);
                if (llGetInventoryType(name)!=INVENTORY_SCRIPT)
                {
                    if (llGetInventoryType(name)!=INVENTORY_SCRIPT)
                    {
                        if (llGetInventoryType(name)!=INVENTORY_TEXTURE)
                        {
                            llRemoveInventory(name);
                            llInstantMessage(owner,"That wasn't a texture! Try again!");    
                        }
                        else
                        { 
                            integer perm = llGetInventoryPermMask(name,MASK_OWNER);
                            if (perm & PERM_COPY && perm & PERM_MODIFY && perm & PERM_TRANSFER)
                            {
                                dropping = FALSE;
                                llSetTimerEvent(0.0);
                                key tex = llGetInventoryKey(name);
                                llRemoveInventory(name);
                                llSetTexture(tex,1);
                                
                                 llAllowInventoryDrop( FALSE );
                                llInstantMessage(owner,"Thanks.. that looks great! Touch if you want to try again");   
                            }
                            else
                            {
                                llRemoveInventory(name);
                               llInstantMessage(owner,"That wasn't full perm! Try again!");     
                            }   
                        }
                    }
                }  
            }    
        }    
    }
  }