From: Winter Ventura
Just thought of something... (you knew I would).
Most camping chairs have a "maximum payout" that the owner must periodically reset. These camping chairs could, theorhetically.. run the chair owner DRY of lindens.
Is there a way we can specify a "maximum cap per session" at least? (once reached, the camper gets kicked)... or a "Maximum lindens to give out before owner must 'refill'"?
(or maybe.. both?)
I've also seen camping chairs that were smart enough to limit campers to "$L100 per DAY"
Ahhh now I know why you have been plying me with Cheese Miss Winter

All options are possible, in fact pretty straight forward.
A max payout before being reset would probably be the simplist, just an extra menu and a bit of logic, something like this :-
Menu Script
integer campmoney = 0; // Initial amount to grant someone upon the VERY first sit after first rez. (Think, Special bonus)
integer campadd = 1; // Payout amount
integer camptime = 600; // Payout time in seconds (Script USES this)
string camptimeM = "10 minutes"; // Payout time in minutes (Attract SAYS this)
integer payoutLimit = 100; // Payout Limit before chair auto shutsdown
integer totalPayout;
list MenuChoices = ["On","Off","Payout","Bonus","Time","Payout Limit"];
list AmountChoices = ["1$","2$","3$","4$","5$","10$", "20"];
list BonusChoices = ["1$ Bonus","2$ Bonus","3$ Bonus","4$ Bonus","5$ Bonus","10$ Bonus"];
list TimerChoices = ["1 minute","5 minutes","10 minutes","15 minutes","20 minutes","30 minutes","60 minutes"];
list LimitChoices = ["100 L$ Limit","200$ Limit","300$ Limit","400$ Limit","500$ Limit","1000$ Limit", "RESET"];
integer Listening = 0;
integer listenchannel = 0;
SaveParameters()
{
llSetObjectDesc((string)campmoney + "/" + (string)camptime + "/" + (string)campadd + "/" + (string)payoutLimit+ "/" + (string)totalPayout);
llMessageLinked(LINK_THIS,0,"RESET",NULL_KEY);
}
GetParameters()
{
string str = llGetObjectDesc();
list ldata = llParseString2List(str, ["/"], [""]);
if(llGetListLength(ldata) == 5)
{
campmoney = llList2Integer(ldata,0);
camptime = llList2Integer(ldata,1);
campadd = llList2Integer(ldata,2);
payoutLimit = llList2Integer(ldata,3);
totalPayout = llList2Integer(ldata,4);
}
}
UpdateListen(key id)
{
CancelListen();
Listening = llListen(listenchannel,"",id,"");
llSetTimerEvent(30);
}
CancelListen()
{
if(Listening > 0) llListenRemove(Listening);
Listening = 0;
llSetTimerEvent(0);
}
// Owner Conversation Dialog
ShowMainMenu(key id)
{
string text = "Main Menu\nPlease Select an Option";
// finally show the dialog
llDialog(id,text,MenuChoices,listenchannel);
UpdateListen(id);
}
ShowPayoutMenu(key id)
{
string text = "Payout Menu\nPlease Select an amount\nCurrent Amount is L$" + (string)campadd + " / " + camptimeM;
// finally show the dialog
llDialog(id,text,AmountChoices,listenchannel);
UpdateListen(id);
}
ShowBonusMenu(key id)
{
string text = "Bonus Menu\nPlease Select an amount\nCurrent Amount is L$" + (string)campmoney;
// finally show the dialog
llDialog(id,text,BonusChoices,listenchannel);
UpdateListen(id);
}
ShowTimerMenu(key id)
{
string text = "Timer Menu\nPlease Select a time period\nCurrent period is " + camptimeM;
// finally show the dialog
llDialog(id,text,TimerChoices,listenchannel);
UpdateListen(id);
}
ShowLimitMenu(key id)
{
string text = "Payout Limit Menu\nPlease Select the maximum payout before the chair auto shuts down\nCurrent limit is L$" + (string)payoutLimit + "\nCurrent payout total is L$" + (string)totalPayout;
// finally show the dialog
llDialog(id,text,LimitChoices,listenchannel);
UpdateListen(id);
}
// States
default
{
state_entry()
{
GetParameters();
llSetTimerEvent(0);
integer perms = llGetPermissions();
if((perms & PERMISSION_DEBIT) != PERMISSION_DEBIT)llRequestPermissions(llGetOwner() , PERMISSION_DEBIT ); //Ask my owner for permission to give money and assume it suceeds
state Running;
}
on_rez(integer num) { llResetScript(); }
}
state Running
{
state_entry()
{
llSetTimerEvent(0);
}
changed(integer change)
{
// something changed
if (change & CHANGED_INVENTORY)
{
//
// reset script if inventory changes
//
llResetScript();
}
}
touch_start(integer total_number)
{
// Owner
key id = llDetectedKey(0);
if( (id == llGetOwner()))
{
state Menu;
}
}
link_message(integer sender_num, integer num, string str, key id)
{
if("PAY" == str)
{
if(num > 0)
{
llGiveMoney(id,num);
totalPayout += num;
if(totalPayout >= payoutLimit) state Disabled;
}
}
}
}
state Menu
{
state_entry()
{
listenchannel = (integer)llFrand(1000) + 10;
ShowMainMenu(llGetOwner());
}
on_rez(integer num) { state default; }
timer()
{
CancelListen();
state Running;
}
listen( integer channel, string name, key id, string message )
{
CancelListen();
if("On" == message)
{
// Force the anuimation script to reset
SaveParameters();
state Running;
}
else if("Off" == message)
state Disabled;
else if("Payout" == message)
ShowPayoutMenu(id);
else if("Bonus" == message)
ShowBonusMenu(id);
else if("Time" == message)
ShowTimerMenu(id);
else if("Payout Limit" == message)
ShowLimitMenu(id);
else if("RESET" == message)
{
totalPayout = 0;
SaveParameters();
state Running;
}
else
{
integer index = llListFindList(AmountChoices, [ message ]);
if(index >= 0)
{
campadd = (integer)message;
SaveParameters();
state Running;
}
else
{
index = llListFindList(BonusChoices , [ message ]);
if(index >= 0)
{
campmoney = (integer)message;
SaveParameters();
state Running;
}
else
{
index = llListFindList(TimerChoices, [ message ]);
if(index >= 0)
{
camptimeM = message;
camptime = 60 * (integer)message; // Payout time in seconds (Script USES this)
SaveParameters();
state Running;
}
else
{
index = llListFindList(LimitChoices, [ message ]);
if(index >= 0)
{
payoutLimit = (integer)message; // Shut down limit
SaveParameters();
state Running;
}
}
}
}
}
}
}
state Disabled
{
state_entry()
{
llSetText("OFF",<1,0,0>,1); // Set the hovertext to attract mode
llMessageLinked(LINK_THIS,0,"DISABLED",NULL_KEY);
}
touch_start(integer total_number)
{
// Owner or owner Group control
key id = llDetectedKey(0);
if( (id == llGetOwner()))
{
state Menu;
}
}
}
Animator Script
integer campmoney = 0; // Initial amount to grant someone upon the VERY first sit after first rez. (Think, Special bonus)
integer campadd = 1; // Payout amount
integer camptime = 600; // Payout time in seconds (Script USES this)
string camptimeM = "10 minutes"; // Payout time in minutes (Attract SAYS this)
integer payoutLimit = 100; // Payout Limit before chair auto shutsdown
integer totalPayout;
string receiver = NULL_KEY; // key of Sitter
// Modifications for Animation
vector pos = <0,0,-0.5>; //adjust the (x,y,z) position to fit object
string sittext = ""; // Adjust this to your needs but keep it short!
string animation; // The first animation in object will be used
GetParameters()
{
string str = llGetObjectDesc();
list ldata = llParseString2List(str, ["/"], [""]);
if(llGetListLength(ldata) == 5)
{
campmoney = llList2Integer(ldata,0);
camptime = llList2Integer(ldata,1);
campadd = llList2Integer(ldata,2);
payoutLimit = llList2Integer(ldata,3);
totalPayout = llList2Integer(ldata,4);
}
}
SetInactiveText()
{
llSetText("Group Members sit here for free money,\nL$"+(string)campadd+" every "+camptimeM,<0,1,0>,1); // Set the hovertext to attract mode
}
SetActiveText()
{
llSetText("You have earned: L$"+(string)campmoney,<1,1,1>,1); // Setting hovertext to current amount earned
}
SetInactive()
{
receiver = NULL_KEY; // forget who the receiver was
campmoney = 0; // reset earning count to 0
SetInactiveText();
llSetTimerEvent(0); // Nobody is sitting on me, so no need to call myself anymore. Disable timer.
}
// States
default
{
state_entry()
{
GetParameters();
llSetTimerEvent(0);
animation = llGetInventoryName(INVENTORY_ANIMATION,0);
llSitTarget(pos, ZERO_ROTATION);
SetInactiveText();
llSetSitText(sittext);
}
on_rez(integer num) { llResetScript(); }
changed(integer change)
{
// something changed
if (change & CHANGED_LINK)
{
// and it was a link change
if (llAvatarOnSitTarget() != NULL_KEY && receiver == NULL_KEY)
{
// if Avatar key isn't empty, somebody is sitting on me
if ( llSameGroup(llAvatarOnSitTarget()) ) // Check that the sitter is of the same group as the prim
{
// if so, allow them to sit and start the payments
receiver = llAvatarOnSitTarget(); // store sitting avatar's key
SetActiveText();
llSetTimerEvent(camptime); // amount of time between payments in seconds
llRequestPermissions(receiver, PERMISSION_TRIGGER_ANIMATION );
}
else
{
// if not, boot them off with an explanation.
llSay(0, "Group members only, sorry.");
llSay(0, "If you are a group member, please \"wear your tags\" by making the group active..");
llUnSit(llAvatarOnSitTarget()); // unsit him or her
}
}
else if( receiver != NULL_KEY )
{
// if the avatar has gotten up
llStopAnimation(animation);
if(campmoney > 0)
{
// give the avatar the amount of money he has earned.
llMessageLinked(LINK_THIS, campmoney,"PAY",receiver);
}
SetInactive();
}
}
else if (change & CHANGED_INVENTORY)
{
//
// reset script if inventory changes
//
llResetScript();
}
}
timer()
{
campmoney = campmoney+campadd; // current amount + xL$ per camptime
SetActiveText();
if (llAvatarOnSitTarget() == NULL_KEY)
{
// Noone's sitting on me, reset the vars
SetInactive();
}
}
run_time_permissions(integer perms)
{
if( (perms & PERMISSION_TRIGGER_ANIMATION) == PERMISSION_TRIGGER_ANIMATION)
{
llStopAnimation("sit");
llStartAnimation(animation);
}
}
link_message(integer sender_num, integer num, string str, key id)
{
if("DISABLED" == str)
{
state Disabled;
}
else if("RESET" == str)
{
llResetScript();
}
}
}
state Disabled
{
state_entry()
{
llSetText("Sorry not in Use",<1,0,0>,1); // Set the hovertext to off
}
link_message(integer sender_num, integer num, string str, key id)
{
if("RESET" == str) llResetScript();
}
}
Downside - if someone was to sit on the chair for an extended period they could still bankrupt you as the check is only performed at payout time.
To make it check on the sit side is a little more complex, but only a little.
We would need to keep comparing the running tally plus the last total against the payout limit and take appropriate action. I'm not 100% clear if a script forced unseat would result in the AV being paid or not. Assuming it would then the new animator script becomes this :
integer campmoney = 0; // Initial amount to grant someone upon the VERY first sit after first rez. (Think, Special bonus)
integer campadd = 1; // Payout amount
integer camptime = 600; // Payout time in seconds (Script USES this)
string camptimeM = "10 minutes"; // Payout time in minutes (Attract SAYS this)
integer payoutLimit = 100; // Payout Limit before chair auto shutsdown
integer totalPayout;
string receiver = NULL_KEY; // key of Sitter
// Modifications for Animation
vector pos = <0,0,-0.5>; //adjust the (x,y,z) position to fit object
string sittext = ""; // Adjust this to your needs but keep it short!
string animation; // The first animation in object will be used
GetParameters()
{
string str = llGetObjectDesc();
list ldata = llParseString2List(str, ["/"], [""]);
if(llGetListLength(ldata) == 5)
{
campmoney = llList2Integer(ldata,0);
camptime = llList2Integer(ldata,1);
campadd = llList2Integer(ldata,2);
payoutLimit = llList2Integer(ldata,3);
totalPayout = llList2Integer(ldata,4);
}
}
SetInactiveText()
{
llSetText("Group Members sit here for free money,\nL$"+(string)campadd+" every "+camptimeM,<0,1,0>,1); // Set the hovertext to attract mode
}
SetActiveText()
{
llSetText("You have earned: L$"+(string)campmoney,<1,1,1>,1); // Setting hovertext to current amount earned
}
SetInactive()
{
receiver = NULL_KEY; // forget who the receiver was
campmoney = 0; // reset earning count to 0
SetInactiveText();
llSetTimerEvent(0); // Nobody is sitting on me, so no need to call myself anymore. Disable timer.
}
// States
default
{
state_entry()
{
GetParameters();
llSetTimerEvent(0);
animation = llGetInventoryName(INVENTORY_ANIMATION,0);
llSitTarget(pos, ZERO_ROTATION);
SetInactiveText();
llSetSitText(sittext);
}
on_rez(integer num) { llResetScript(); }
changed(integer change)
{
// something changed
if (change & CHANGED_LINK)
{
// and it was a link change
if (llAvatarOnSitTarget() != NULL_KEY && receiver == NULL_KEY)
{
// if Avatar key isn't empty, somebody is sitting on me
if ( llSameGroup(llAvatarOnSitTarget()) ) // Check that the sitter is of the same group as the prim
{
// if so, allow them to sit and start the payments
receiver = llAvatarOnSitTarget(); // store sitting avatar's key
SetActiveText();
llSetTimerEvent(camptime); // amount of time between payments in seconds
llRequestPermissions(receiver, PERMISSION_TRIGGER_ANIMATION );
}
else
{
// if not, boot them off with an explanation.
llSay(0, "Group members only, sorry.");
llSay(0, "If you are a group member, please \"wear your tags\" by making the group active..");
llUnSit(llAvatarOnSitTarget()); // unsit him or her
}
}
else if( receiver != NULL_KEY )
{
// if the avatar has gotten up
llStopAnimation(animation);
if(campmoney > 0)
{
// give the avatar the amount of money he has earned.
llMessageLinked(LINK_THIS, campmoney,"PAY",receiver);
}
SetInactive();
}
}
else if (change & CHANGED_INVENTORY)
{
//
// reset script if inventory changes
//
llResetScript();
}
}
timer()
{
campmoney = campmoney+campadd; // current amount + xL$ per camptime
SetActiveText();
if (llAvatarOnSitTarget() == NULL_KEY)
{
// Noone's sitting on me, reset the vars
SetInactive();
}
integer temp = totalPayout + campmoney;
if(temp >= payoutLimit)
{
llSay(0, "I'm sorry but you have reached the payout limit");
llUnSit(llAvatarOnSitTarget()); // unsit him or her
}
}
run_time_permissions(integer perms)
{
if( (perms & PERMISSION_TRIGGER_ANIMATION) == PERMISSION_TRIGGER_ANIMATION)
{
llStopAnimation("sit");
llStartAnimation(animation);
}
}
link_message(integer sender_num, integer num, string str, key id)
{
if("DISABLED" == str)
{
state Disabled;
}
else if("RESET" == str)
{
llResetScript();
}
}
}
state Disabled
{
state_entry()
{
llSetText("Sorry not in Use",<1,0,0>,1); // Set the hovertext to off
}
link_message(integer sender_num, integer num, string str, key id)
{
if("RESET" == str) llResetScript();
}
}
The other options are all variations on the theme.
Hope thats useful....