Jump to content

RFC: single script multi room rental box.


Tabris Daxter
 Share

You are about to reply to a thread that has been inactive for 3904 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

hi all,

what follows is my attempt at a multi room rental box using only a single script.

i am asking for comments, suggestions or improvements.

i know there are a few things "missing" (eg. warnings/ messages and something that happens when time runs out) these will be added soon. (once i get it clear in my mind :) )

 

CODE:

//Variables
list vacantlst = ["info","1 hour","1 day","1 week"];
list rentedlst = ["info"];
list tennantlst = ["info","Teleport","Extend"];
list LandLordlst = ["RESET","Security ON","Security Off","UPDATE"];
integer dlgchan = 666;
list room_info = [];
integer room;
list rstatus;
string status;
integer lease_start;
integer lease_length;
integer lease_time;
integer leased_room;
key tennant_key;
key touchy;
integer locnum;
string tennant;
string length;
key gQueryId;
string gNotecard = "New";
integer gLineNum = 0;
list gNotecardData;
string addydata;
integer startparam;
string dest;
key addy;


integer b = 0;
//Functions
RESET()
{
    integer link = 0;
    integer prims = llGetNumberOfPrims();
    while (link <= prims)
    {
        if (link != LINK_ROOT)
            {
                llSetLinkPrimitiveParamsFast(link,[PRIM_COLOR,ALL_SIDES,<0.0,1.0,0.0>,1,
                PRIM_TEXT,"",ZERO_VECTOR,0,
                PRIM_FULLBRIGHT,ALL_SIDES,FALSE,
                PRIM_DESC,""]);
            }
        link++;
    }
}

string roomdata(integer room, integer index)
{
    list pdesc = llParseString2List(llDumpList2String(llGetLinkPrimitiveParams(room,[PRIM_DESC]),""),[","],[]);
    return llList2String(pdesc,index);
}

string time(integer starttime, integer endtime)
{
    integer futtime = starttime + endtime;
    string realday = llList2String( ["Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday"],
            futtime % 604800 / 86400  + (futtime >> 31) );
    integer realhr = (futtime % 86400) / 3600;
    integer realmin = (futtime % 3600)/60;
    string stringmin;
    if (realmin < 10)
    {
        stringmin = "0"+(string)realmin;
    }
    else 
    {
        stringmin = (string)realmin;
    }
    string printtime = (string)realday+"::"+(string)realhr +":"+stringmin;
    return printtime;
    
}    

default
{
    state_entry()
    {
        llListen(dlgchan,"","","");
        room_info = [];
        llSetTimerEvent(1.0);
    }
    
    timer()
    {
        integer a = 1;
        
        llSetLinkPrimitiveParams(LINK_ROOT,[PRIM_TEXT,(string)b++,ZERO_VECTOR,1]);
        while (a < 11)
        {
            
            status = roomdata(a,0);
            
            if (status == "rented")
            {
                lease_time = (integer)roomdata(a,1)+(integer)roomdata(a,2);
                leased_room = (integer)roomdata(a,3);
                
                if (lease_time > llGetUnixTime())
                {
                    llSetLinkColor(leased_room,<1.0,0.0,0.0>,ALL_SIDES);
                }
                else if (lease_time < llGetUnixTime())
                {
                llSetLinkPrimitiveParamsFast(a,[PRIM_COLOR,ALL_SIDES,<0.0,1.0,0.0>,1,
                PRIM_TEXT,"",ZERO_VECTOR,0,
                PRIM_FULLBRIGHT,ALL_SIDES,FALSE,
                PRIM_DESC,""]);
                }
            }
            a++;
        }
    }

    touch_start(integer num_detected)
    {
        
        integer i;
        for(i = 0; i < num_detected; ++i) 
        {
            room = llDetectedLinkNumber(i);
            rstatus = llCSV2List(llDumpList2String(llGetLinkPrimitiveParams(room,[PRIM_DESC]),""));
            key tenn_key = llList2Key(rstatus,4);
            touchy = llDetectedKey(i);
            string vacantmsg = "room # " + llGetLinkName(room) + " is Available for Rent";
            string rentedmsg = "Sorry this Room is UNAVAILABLE at this time. \n press the info putton to see when it will be available";
            string tennantmsg = "Welcome Back. " + llKey2Name(roomdata(room,3))+ "\n Please Choose from one of the options below.";
            if (llDetectedLinkNumber(i) != LINK_ROOT && llDetectedLinkNumber(i) <= 10 )
            {
                if (roomdata(room,0) == "rented" && tenn_key != llDetectedKey(i))
                {
                    llDialog(llDetectedKey(i),rentedmsg,rentedlst,dlgchan);
                }
                else if (roomdata(room,0) == "rented" && tenn_key == llDetectedKey(i))
                {
                    llDialog(llDetectedKey(i),tennantmsg,tennantlst,dlgchan);
                }
                else if (roomdata(room,0) != "rented")
                {
                    llDialog(llDetectedKey(i),vacantmsg,vacantlst,dlgchan);
                }
                else if (roomdata(room,0) == "PENDING" && tenn_key == llDetectedKey(i))
                {
                    llDialog(llDetectedKey(i),"Please Right Click and Select Pay",["ok"],dlgchan);
                }
                if (roomdata(room,0) == "PENDING" && tenn_key != llDetectedKey(i))
                {
                    llDialog(llDetectedKey(i),"This Room is Awaiting Payment",["ok"],dlgchan);
                }
            }
            /*else if (room == LINK_ROOT)
            {
                llDialog(llDetectedKey(i),"Please Right Click and Select Pay",["ok"],dlgchan);
            }*/
            else if (touchy == llGetOwnerKey(llGetKey()))
            {
                llDialog(llDetectedKey(i),"ADMIN AREA",LandLordlst,dlgchan);
            }
        }
    }
    
    listen(integer lchan, string lname, key l_id, string lmsg)
    {
        list tmp = llCSV2List(lmsg);
        if (lchan == dlgchan && lmsg == "1 hour")
        {
            llSetLinkPrimitiveParams(room,[PRIM_COLOR,ALL_SIDES,<1.0,0.5,0.0>,1,
            PRIM_DESC,"PENDING,"+(string)llGetUnixTime()+",3600"+","+(string)room+","+(string)touchy,
            PRIM_FULLBRIGHT,ALL_SIDES,TRUE]);
            llSetPayPrice(PAY_HIDE, [10,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
        }
        else if (lchan == dlgchan && lmsg == "1 day")
        {
            llSetLinkPrimitiveParams(room,[PRIM_COLOR,ALL_SIDES,<1.0,0.5,0.0>,1,
            PRIM_DESC,"PENDING,"+(string)llGetUnixTime()+",86400"+","+(string)room+","+(string)touchy,
            PRIM_FULLBRIGHT,ALL_SIDES,TRUE]);
            llSetPayPrice(PAY_HIDE, [50,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
        }
        else if (lchan == dlgchan && lmsg == "1 week")
        {
            llSetLinkPrimitiveParams(room,[PRIM_COLOR,ALL_SIDES,<1.0,0.5,0.0>,1,
            PRIM_DESC,"PENDING,"+(string)llGetUnixTime()+ ",604800"+","+(string)room+","+(string)touchy,
            PRIM_FULLBRIGHT,ALL_SIDES,TRUE]);
            llSetPayPrice(PAY_HIDE, [100,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
        }        
        
        else if (lchan == dlgchan && lmsg == "info")
        {
            llInstantMessage(touchy,"\nStatus: " + roomdata(room,0)+
            "\nRoom Number: "+llGetLinkName((integer)roomdata(room,3))+
            "\nTime Ending : "+time((integer)roomdata(room,1),(integer)roomdata(room,2))+
            "\nTennant: "+llKey2Name((key)roomdata(room,4)));
        }
        else if (lchan == dlgchan && lmsg == "Teleport")
        {
            integer roomnum = (integer)llGetLinkName((integer)roomdata(room,3));
            llOwnerSay((string)roomnum);
            llMessageLinked(LINK_THIS,255,"TELE",(string)(roomnum -1)+","+llKey2Name((key)roomdata(room,4)));
        }
        else if (lchan == dlgchan && lmsg == "RESET")
        {
            RESET();
        }
        else if (lchan == dlgchan && lmsg == "UPDATE")
        {
            llMessageLinked(LINK_ALL_OTHERS,255,"UPDATE",touchy);
        }
        
        if (llList2String(tmp,0) == "whereto")
        {
            list addytmp = llCSV2List(addydata);
            dest = llList2String(addytmp,0);
            addy = llList2Key(addytmp,1);
            llRegionSayTo(addy,-666,"change");
            llWhisper(startparam,"goto,"+dest);
        }
        
    }
    
    money(key id, integer amount)
    {
        if (id == (key)roomdata(room,4) && roomdata(room,0) == "PENDING")
        {
            if (roomdata(room,2) == "604800" && amount == 100)
            {
                llSetLinkPrimitiveParams(room,[PRIM_COLOR,ALL_SIDES,<1.0,0.0,0.0>,1,
                PRIM_DESC,"rented,"+(string)llGetUnixTime()+ ",604800"+","+(string)room+","+(string)touchy,
                PRIM_FULLBRIGHT,ALL_SIDES,TRUE]);
            }
            else if (roomdata(room,2) == "3600" && amount == 10)
            {
                llSetLinkPrimitiveParams(room,[PRIM_COLOR,ALL_SIDES,<1.0,0.0,0.0>,1,
                PRIM_DESC,"rented,"+(string)llGetUnixTime()+ ",3600"+","+(string)room+","+(string)touchy,
                PRIM_FULLBRIGHT,ALL_SIDES,TRUE]);
            }
            else if (roomdata(room,2) == "86400" && amount == 50)
            {
                llSetLinkPrimitiveParams(room,[PRIM_COLOR,ALL_SIDES,<1.0,0.0,0.0>,1,
                PRIM_DESC,"rented,"+(string)llGetUnixTime()+ ",86400"+","+(string)room+","+(string)touchy,
                PRIM_FULLBRIGHT,ALL_SIDES,TRUE]);
            }
        }
    }
    
    link_message(integer sender, integer num, string msg, key id)
    {
        if (msg == "TELE")
        {
            //llSetColor(<1.0,0.0,0.0>,ALL_SIDES);
            
            startparam = llGetUnixTime();
            llListen(startparam,"~~TPSEAT","","");
            list incdata = llCSV2List(id);
            locnum = llList2Integer(incdata,0);
            tennant = llList2String(incdata,1);
            gQueryId = llGetNotecardLine(gNotecard, locnum);
            
        }
        else if (msg == "PORT")
        {
            llRezObject("~~TPSEAT",llGetPos()+<-1.5,0.0,-1.0>,ZERO_VECTOR,ZERO_ROTATION,startparam);
        }
    }
    dataserver(key lqueryID, string ldata)
    {
        if (gQueryId == lqueryID)
        {
            if (ldata != EOF)
            {
                addydata = ldata;
                //llOwnerSay(ldata);
                llMessageLinked(LINK_SET,255,"PORT","");
            }
        }
    }
    
    object_rez(key id) 
    {
        llListen(startparam,"~~TPSEAT", id, "");        
        llRemoteLoadScriptPin(id, "TeleScript", startparam, TRUE, startparam);
    }
}

here are some images of the construction.

each of the squares is a separate prim.

this is VACANT

 rental box - vacant.jpg

Payment PENDING

rental box - payment pending.jpg

Room OCCUPIED

rental box - occupied.jpg

info stored in desc field

info in description field.jpg

Link to comment
Share on other sites

I see only one potentially fatal flaw; you open a lot of listens but never close them... you'll overflow your max listens in no time flat. and as far as I can tell you don't need them because....

I see that you are also custom feeding scripts to the rezzed teleport objects (to give them a destination?) instead, you can use bitshifted integers in the start param for those scripts to tell them where to go within a single region by rounding the vector values shifting them and adding them.

vIntBgn = (llFloor( vPosGoto.x ) << 21) + (llFloor( vPosGoto.y ) << 13) + llCeil( vPosGoto.z )

you can read it back out in a gwneric teleport destination script with

vPosGoto = < (vIntBgn >> 21) + 0.5, (vIntBgn >> 13 & 255) + 0.5, (vIntBgn & 8191)>;

which will give you safely within 0.5m of any normal TP spot on the region.

 

several of your if tests repeat the same test (lchan == dlgchan), instead, group all those tests together inside of one if that tests that, and only test unique values. not only do you save memory, and writing, but you'll also do less work and skip all the tests if it's false.

unless you need to know when the room was rented, all you really need to know is when the rental expires... so you can save a little space by just adding the rental time to llGetUnixTime, and store that.

llKey2Name will fail if the avatar or object with that key is not currently on the region... you may need to store the full name if that's important to you, or use the dataserver event to fetch it with llRequestAgentData.

your RESET and time custom functions are only used in one place each, it will probably be more effective if you put the code in those sections directly

instead of only grabbing one piece of of data from the roomdata string, you should consider grabbing the whole thing and only using the part you need since you make multiple calls to it in the same sections... this will cut down on size and functions calls in your script and make it faster.

I'm happy to see someone reused my weekday code, or figured out the same general solution, in your case you can remove the

+ (variable << 31)

portion, since you won't ever have to deal with dates before 1970 (which is the only way for it to be a negative value)

 

I'm sure there's more but that's plenty to play with for now.

Link to comment
Share on other sites

ty void for the feedback.

All point you made are relevant and I most likely will incorporate them.

i know about the listen problem (haven't run into it yet) but this is still a WIP.

the custom feeding of the TP script is so i can update it easier incase it needs changing in the future (new functions/ old ones broken). the TP script is a basic warp-pos straight from the wiki.

about the llkey2name it's used in a dialog in a touch event, so unless you can touch from another region it shouldn't matter. :)

i'm going to re-write the reset function maybe put it in another script so i have a timeout/ time limit for payment to be made before it reverts to vacant.

with your suggestion for the room data string function thing could you please provide an example or something to get me started.

with the unixtime to weekday is it possible to also get the day of the month. eg. Mon 14, 10:30am.

 

ty again void

 

edit: is there something borked with the email subscription system in the forums?

 

Link to comment
Share on other sites

for key to name I was noting it for the dialog where you read it from room data, since that key may not be a person in the area. (teleport option) but I have no idea what's done with that link message so it may not matter.

as for room data being pulled, if you pull it once, and store the information in variables or a list you can then reference the local variables, so that you aren't using more functions to pull out one piece at a time (for instance you check the same variable in a series of if statements in the touch event, so ever test pulls the same data again, runing all those function calls to parse and grab the description each time...  if you grab it once and store it in a variable, all that extra work goes away.)

a variable would probably be fine for the touch event (you only pull one value) but in the timer you might want to change the set up to grab the whole list and store it in a reusable list variable, since you check more than one value, then you can reference them locally using the local list and llList2* fucntions

ETA:
dunno if subscriptions work or not, never use them, but they aren't automatic, so you have to use the edit link on the first post to start them... if that's not working then I guess they may be borked.

Link to comment
Share on other sites

  • 11 months later...

It seems there is scripts missing here, and a notecard... I see it needs a notecard, wher eis it put?

I see it needs a teleport prim and script, where is it put?

 

All valid questions i think...

There is no way of some one knowing the notecard lay out, or what type of teleport script is needed..

Can some one supply those?

Link to comment
Share on other sites

The TP script, as Tabriz says earlier in this thread, is nothing fancier than WarpPos.  Now that we have llSetRegionPos, I'd use that instead.

And the format of the notecard is pretty simple.  It's a comma delimited single line, read in the dataserver event.  You can see the format in this bit of code in the listen event ....

if (llList2String(tmp,0) == "whereto")        {            list addytmp = llCSV2List(addydata);  //addydata is the line on the notecard            dest = llList2String(addytmp,0);            addy = llList2Key(addytmp,1);            llRegionSayTo(addy,-666,"change");            llWhisper(startparam,"goto,"+dest);        }

 addy is the UUID of the target prim and dest is the destination vector.

Link to comment
Share on other sites

Tommie,

there are about 5 or 6 "missing" scripts here as this i just a (very)small part of a much larger (and on hold) project.

i only posted the main script as a RFC(Request For Comment) to see if there were any MAJOR "you will blow up the server if you do this" problems.

if you message me inworld i can send you a copy of the rental box with all scripts (updated teleport) and notecards. i just ask that you don't sell it.

 

@Rolig,

Bingo.  addy is the key of the "room" to turn off security. dest is the location.

/cookie

Link to comment
Share on other sites

  • 1 year later...

You're late!  It looks like this old thread is set to be resurrected in July, not August.

Our usual resources are the scripting libraries here and on the wiki but I shouldn't think there was likely to be a copy of this.  If you'd care to tell us what you're trying to achieve we can point you in the right direction though.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3904 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...