User:Yumi Murakami/Golden Vendor

From Second Life Wiki
< User:Yumi Murakami
Revision as of 11:20, 7 August 2013 by Yumi Murakami (talk | contribs) (Created page with "This is a vendor which has an additional function: an avie can click on the vendor frame and pay a small fee to "claim" the vendor. For a certain period of time, they then get co…")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This is a vendor which has an additional function: an avie can click on the vendor frame and pay a small fee to "claim" the vendor. For a certain period of time, they then get commission on all sales. The idea was to combine a vendor and a game by allowing people to earn L$ by selling a product to others. Didn't take off very much, but I know some people still liked it, in part because of my super paranoid validation that the vendor is set up properly (largely because I was burned by badly set ones several times myself..).

This is in two parts: the vendor and the frame. The frame needs to be a separate object near the vendor, but not linked. Originally the frame was just that - a frame - and the vendor was just a box, but nothing in the script really requires that.

<lsl>

key currentClaimer = NULL_KEY; string currentClaimerName;

string itemToSell; string infocardName; integer itemPrice; integer claimAmount; integer claimPrice; integer claimTime;

list percentSplits;

key myFrame;

integer notecardLine; integer maxLine; string notecardName = "Configuration Notecard";

key partnerKey; string partnerName; integer partnerSplit; integer doingPartnerRequest; integer totalPartnerSplits; integer claimStartTime; key lastFrameClick; integer startUpTime;

integer totalSales; integer totalNotecards; integer totalClaims; integer totalClaimedSales;

integer autoAdjustClaim; float aaClaimMultiplier = 2.0; integer aaClaimMinimum = 4;

init() {

   llSay(-593927,"reset");
   partnerKey = NULL_KEY;
   partnerSplit = 0;
   totalPartnerSplits = 0;
   doingPartnerRequest = FALSE;
   autoAdjustClaim = FALSE;
   llOwnerSay("Reading notecard.. (this may take a few moments)");
   if (llGetInventoryType(notecardName) != INVENTORY_NOTECARD) {
       llOwnerSay("Error: Configuration Notecard is missing!");
       state setupError;
   }
   doingPartnerRequest = FALSE;
   notecardLine = -1;
   llGetNumberOfNotecardLines(notecardName);

}

adjustAmount() {

   integer upTime = (llGetUnixTime() - startUpTime) / 60;
   float spm;
   if (upTime < claimTime) {
       spm = 0;
   } else {
       spm = totalSales / upTime;
   }
   integer salesInTime = (integer)( spm * ((float)claimTime) );
   integer targetSales;
   targetSales = (integer) ( (float)salesInTime * aaClaimMultiplier);
   if (targetSales < aaClaimMinimum) targetSales = aaClaimMinimum;
   integer suggestPrice = claimAmount * (targetSales - 1);
   if (suggestPrice != claimPrice) {
       claimPrice = suggestPrice;   
       llInstantMessage(llGetOwner(),"Claim price auto-adjusted to L$" + (string)claimPrice + " (actual average SCP " + (string)salesInTime + ", target SCP " + (string)targetSales +")");
   }     

}

default {

   state_entry() {
       init();
   }
   on_rez(integer junk) {
       init();
   }
   changed(integer theChange) {
       llOwnerSay("My inventory changed!  Starting again...");
       llResetScript();
   }
   dataserver(key request, string result) {
       if (doingPartnerRequest) {
           llSetTimerEvent(0);
           doingPartnerRequest = FALSE;
           partnerName = result;
       } else {
           
       if (notecardLine == -1) {
           maxLine = ((integer)result) - 1;
       } else {
           if (llGetSubString(result,0,2) != "//") {
               integer commandBreak = llSubStringIndex(result," ");
               string command = llToLower(llGetSubString(result,0,commandBreak - 1));
               string rest = llGetSubString(result,commandBreak+1,-1);
               if (command == "item") {
                   itemToSell = rest;
                   if (llGetInventoryType(itemToSell) == INVENTORY_NONE) {
                       llOwnerSay("Error: Item to sell (" + itemToSell + ") not found in inventory.");
                       state setupError;
                       return;
                   }
                   if (! ((llGetInventoryPermMask(itemToSell,MASK_OWNER)) & (PERM_COPY | PERM_TRANSFER))) {
                       llOwnerSay("Error: Can't sell this item, I don't have copy and transfer permission.");
                       state setupError;
                       return;
                   }
                   if (! ((llGetInventoryPermMask(itemToSell,MASK_NEXT)) & (PERM_COPY | PERM_TRANSFER))) {
                       llOwnerSay("Warning: Customer will get copy and transfer permission!");
                   }
               } 
               if (command == "notecard") {
                   infocardName = rest;
                   if (llGetInventoryType(infocardName) != INVENTORY_NOTECARD) {
                       llOwnerSay("Error: Information notecard (" + infocardName + ") not found in inventory.");
                       state setupError;
                       return;
                   }
                   if (! ((llGetInventoryPermMask(infocardName,MASK_OWNER)) & (PERM_COPY | PERM_TRANSFER))) {
                       llOwnerSay("Error: Can't give out this information notecard, I don't have copy and transfer permission.");
                       state setupError;
                       return;
                   }
                   if (! ((llGetInventoryPermMask(infocardName,MASK_NEXT)) & (PERM_COPY | PERM_TRANSFER))) {
                       llOwnerSay("Error: Customer won't be able to read information notecard, you need to give them copy and transfer permission.");
                       state setupError;
                       return;
                   }
               }       
               if (command == "itemprice") {
                   itemPrice = (integer)rest;
                   if (itemPrice <= 0) {
                       llOwnerSay("Error: Price is not valid, or is zero.  (This vendor is not suitable for free items.)");
                       state setupError;
                       return;
                   }
               }
               if (command == "claimprice") {
                   if (rest == "auto") {
                       autoAdjustClaim = TRUE;
                   } else {
                       autoAdjustClaim = FALSE;
                       claimPrice = (integer)rest;
                       if ((claimPrice <= 0) && (result != "0")) {
                           llOwnerSay("Error: Claim price is not valid.");
                           state setupError;
                           return;
                       }
                   }
               }
               if (command == "claimamount") {
                   claimAmount = (integer)rest;
                   if ((claimAmount <= 0)) {
                       llOwnerSay("Error: Claim amount is not valid or is zero.");
                       state setupError;
                       return;
                   }   
               }
               if (command == "claimtime") {
                   claimTime = (integer)rest;
                   if ((claimTime <= 0)) {
                       llOwnerSay("Error: Claim time is not valid or is zero.");
                       state setupError;
                       return;
                   }   
               }  
               if (command == "claimminimum") {
                   aaClaimMinimum = (integer)rest;
                   if ((aaClaimMinimum <= 0)) {
                       llOwnerSay("Error: Claim minimum is not valid or is zero.");
                       state setupError;
                       return;
                   }   
               }  
               if (command == "claimmultiply") {
                   aaClaimMultiplier = (float)rest;
                   if ((aaClaimMinimum <= 0.0)) {
                       llOwnerSay("Error: Claim multiplier is not valid or is zero.");
                       state setupError;
                       return;
                   }   
               }  
               
               if (command == "partnerkey") {
                   if (partnerKey != NULL_KEY){
                       llOwnerSay("Error: Two partnerkeys in a row with no partnersplit in between.");
                       state setupError;
                       return;
                   }
                   partnerKey = (key)rest;
                   llSetTimerEvent(5);
                   doingPartnerRequest = TRUE;
                   llRequestAgentData(partnerKey,DATA_NAME);
                   return;
               }  
               if (command == "partnersplit") {
                   if (partnerKey == NULL_KEY) {
                       llOwnerSay("Error: Partnersplit needs to be preceded by a partnerkey.");
                       state setupError;
                       return;
                   }
                   partnerSplit = (integer)rest;
                   if ((partnerSplit <= 0)) {
                       llOwnerSay("Error: Partner split amount is not valid or is zero.");
                       state setupError;
                       return;
                   }   
                   totalPartnerSplits += partnerSplit;
                   llOwnerSay("Partner: " + partnerName + " recieves " + (string)partnerSplit + "%.");
                   percentSplits += [partnerKey, partnerSplit];
                   partnerKey = NULL_KEY;
               }
                    
           }
       }
       }
       if (notecardLine == maxLine) {
           // finalValidate();
           if (claimAmount >= itemPrice) {
               llOwnerSay("Error: Claim amount is greater than item price!");
               state setupError;
               return;
           }
           if (totalPartnerSplits > 100) {
               llOwnerSay("Error: Partner splits add up to greater than 100%!");
               state setupError;
               return;
           }
           if ((itemPrice == 0) || (itemToSell == "") || ((claimPrice == 0) && (autoAdjustClaim == FALSE)) || (claimTime == 0) || (claimAmount == 0)) {
               llOwnerSay("Error: Essential information is missing.");
               llOwnerSay((string)autoAdjustClaim);
               state setupError;
               return;
           }
           state setupStage;   
           return;
       }
       notecardLine++;
       llGetNotecardLine(notecardName,notecardLine);
   }
      
   timer() {
       llSetTimerEvent(0);
       llOwnerSay("Error: Dataserver timed out while checking information for partner key " + (string)partnerKey + ".");
       llOwnerSay("This can be caused by lag, but more usually means that there's a mistake in the key.");
       state setupError;
       return;
   }

}

state setupError {

   state_entry() {
       llOwnerSay("An error occured in setup.  Please click me to try again.");
   }
   touch_start(integer junk) {
       if (llDetectedKey(0) == llGetOwner()) llResetScript();
   }

}

state setupStage {

   state_entry() {
       llListen(-593827,"",NULL_KEY,"frame");
       llOwnerSay("Setting up linkage.  Please click on my frame.");
   }
   
   listen(integer channel, string name, key speaker, string message) {
       if (llGetOwnerKey(speaker) != llGetOwner()) return;
       if (message != "frame") return;
       myFrame = speaker;
       llOwnerSay("Linked to frame " + (string)speaker);
       llWhisper(-593827,myFrame);
       llSleep(1);
       llRequestPermissions(llGetOwner(),PERMISSION_DEBIT);
   }
   run_time_permissions(integer perms) {
       if (perms & PERMISSION_DEBIT) {
           state gotFrame;
       } else {
           llOwnerSay("Debit permissions are required for this vendor to work.");
           llOwnerSay("Please click on my frame to try again.");
           llWhisper(-593927,"reset");
       }
   }
   changed(integer thechange) {
       if (thechange && CHANGED_INVENTORY) {
           state maint;
       }
   }
   

}

state gotFrame {

   state_entry() {
       llOwnerSay("Vendor setup complete and ready to sell.");
       llListen(-593927,"",myFrame,"");
       llSetPayPrice(PAY_HIDE,[itemPrice,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
       totalSales = 0;
       totalNotecards = 0;
       totalClaims = 0;
       totalClaimedSales = 0;
       startUpTime = llGetUnixTime();
       if (autoAdjustClaim) adjustAmount();
       llWhisper(-593927,(string)claimPrice);
       llSetTimerEvent(60);
   }
   on_rez(integer junk) {
       llResetScript();
   }
   touch_start(integer junk) {
       if (llDetectedKey(0) != llGetOwner()) {
           totalNotecards++;
           if (infocardName != "") llGiveInventory(llDetectedKey(0),infocardName);
           return;
       } else {
           llOwnerSay("I have made " + (string)totalSales + " sales (" + (string)totalClaimedSales + " while claimed), given out " + (string)totalNotecards + " notecards, and been claimed " + (string)totalClaims + " times.");
       }
   }
   
   money(key giver, integer amount) {
       if (amount != itemPrice) {
           llGiveMoney(giver,amount);
           llSay(0,llKey2Name(giver) + ", you paid the wrong amount.  The price is L$" + (string)itemPrice + ".");
           return;
       }
       totalSales++;
       integer gotMoney = itemPrice;
       llGiveInventory(giver,itemToSell);
       if (currentClaimer != NULL_KEY) {
           totalClaimedSales++;
           llGiveMoney(currentClaimer,claimAmount);
           gotMoney -= claimAmount;
       }
       integer totalSplits = 0;
       if (percentSplits != []) {
           integer t;
           for (t=0; t<llGetListLength(percentSplits); t+=2) {
               key benefit = llList2Key(percentSplits,t);
               float percent = llList2Float(percentSplits,t+1);
               integer share = (integer) ( ((float)gotMoney / 100.0) * percent);
               llGiveMoney(benefit,share);
               totalSplits += share;
           }
       }
       string message = llKey2Name(giver) + " (" + (string)giver + ") bought a " + itemToSell + " from " + llGetRegionName() + " for L$" + (string)itemPrice + ".";

       if (currentClaimer != NULL_KEY) {
           message += "  Vendor was claimed by " + currentClaimerName + " who recieved L$" + (string)claimAmount +".";
       }
       if (totalSplits != 0) {
           message += "  L$" + (string)totalSplits + " was paid to partners.";
       }
       llInstantMessage(llGetOwner(),message);
       if (currentClaimer != NULL_KEY) {
           llInstantMessage(currentClaimer,"A " + itemToSell + " was sold from a vendor you claimed; you win L$" + (string)claimAmount + "!");
       }
       
   }
           
   listen(integer channel, string name, key speaker, string message) {
       if (speaker != myFrame) return;
       list msgFromFrame = llParseString2List(message,["|"],[]);
       integer amount = (integer)(llList2String(msgFromFrame,1));
       key giver = (key)(llList2String(msgFromFrame,0));
       string giverName = llKey2Name(giver);
       if (amount == -1) {
           if (currentClaimer != NULL_KEY) {
               integer passed = llGetUnixTime() - claimStartTime;
               passed /= 60;
               integer left = claimTime - passed;
               llSay(0,"This vendor is already claimed.  It will be available to claim in " + (string)left + " minutes.");
           } else {
               llSay(0,"This vendor is available to be claimed right now!");
           }
           llSay(0,"Cost to claim: L$" + (string)claimPrice + ".  You earn L$" + (string)claimAmount + " per sale for " + (string)claimTime + " minute.");
         
           llSay(0,"If you've never played a Golden Vendor before, click the frame again for an information notecard.");
           llSay(0,"Note - if you just want to buy the product, ignore this message and click the white poster part itself."); 
           if (giver == lastFrameClick) {
               llGiveInventory(giver,"About Golden Vendors");
           }
           lastFrameClick = giver;
           return;
       }
       if (amount != claimPrice) {
           llGiveMoney(giver,amount);
           llSay(0,giverName + ", you paid the wrong amount.  Price to claim the vendor is " + (string)claimPrice + ".");
           return;
       }
       if (currentClaimer != NULL_KEY) {
           llGiveMoney(giver,amount);
           llSay(0,giverName + ", sorry, this vendor is already claimed.");
           return;
       }
       totalClaims++;
       llWhisper(-593927,"noclaim");
       currentClaimer = giver;
       currentClaimerName = giverName;
       claimStartTime = llGetUnixTime();
       llSay(0,currentClaimerName + ", you have claimed this vendor for " + (string)claimTime + " minutes.");
       llSay(0,"Get as many other people to buy this item as you can and win money!");
       
   }
   changed(integer thechange) {
       if (thechange && CHANGED_INVENTORY) {
           state maint;
       }
   }
   
   timer() {
       if (currentClaimer != NULL_KEY) {
           if (llGetUnixTime() >= (claimStartTime + (claimTime * 60))) {
                llInstantMessage(currentClaimer,"Your claim time is over!");
                currentClaimer = NULL_KEY;
                llWhisper(-593927,"claim");
           }
       }
       if (autoAdjustClaim) adjustAmount();
   }
       
   

}

state maint {

   state_entry() {
       llWhisper(-593927,"noclaim");
       llOwnerSay("My inventory changed.  Please click me to reset..");
   }
   
   touch_start(integer count) {
       if (llDetectedKey(0) == llGetOwner()) llResetScript();
   }
   

} </lsl>

And the script for the frame..

<lsl>

key master;

init() {

   llListen(-593827,"",NULL_KEY,"");

}

default {

   state_entry() { init(); }
   on_rez(integer junk) { init();}
    
   touch_start(integer total_number)
   {
       if (llDetectedKey(0) != llGetOwner()) return;
       llSay(-593827,"frame");        
   }
   
   listen(integer channel, string name, key speaker, string message) {
       if (llGetOwnerKey(speaker) != llGetOwner()) return;
       if (((key)message) != llGetKey()) return;
       master = speaker;
       llOwnerSay("Frame linked to vendor key " + (string)master);
       state running;
   }

}

state running {

   state_entry() {
       llListen(-593927,"",master,"");
   }
   
   on_rez(integer junk) {
       llResetScript();
   }
   
   touch_start(integer total_number) {
       llSay(-593927,(string)llDetectedKey(0) + "|-1");
   }
   
   listen(integer channel, string name, key speaker, string message) {
       if (speaker != master) return;
       if (message == "reset") llResetScript();
       if (message == "noclaim") state noClaim;
       llSetPayPrice(PAY_HIDE,[(integer)message,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
   }
    
   money(key giver, integer amount) {
       llSay(-593927,(string)giver + "|" + (string)amount);
   }      
   

}

state noClaim {

   state_entry() {
       llListen(-593927,"",master,"");
   }
   
   on_rez(integer junk) {
       llResetScript();
   }
   
   touch_start(integer total_number) {
       llSay(-593927,(string)llDetectedKey(0) + "|-1");
   }
   
   listen(integer channel, string name, key speaker, string message) {
       if (speaker != master) return;
       if (message == "reset") llResetScript();
       if (message == "claim") state running;
       llOwnerSay(message);
       llSetPayPrice(PAY_HIDE,[(integer)message,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
   }

} </lsl>