User:Yumi Murakami/Golden Vendor
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>