X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=huffware%2Fhuffotronic_tools_n_testers_v6.1%2FVote_for_me_v4.2.txt;fp=huffware%2Fhuffotronic_tools_n_testers_v6.1%2FVote_for_me_v4.2.txt;h=ab8aca15523eeaa2020e3ced63f5b64670400d56;hb=cb9011b7dd78ac93d48a871a9fdda062c9181138;hp=0000000000000000000000000000000000000000;hpb=ad0ce3f89fcb4e06393aa84e342c2745aef72da8;p=feisty_meow.git diff --git a/huffware/huffotronic_tools_n_testers_v6.1/Vote_for_me_v4.2.txt b/huffware/huffotronic_tools_n_testers_v6.1/Vote_for_me_v4.2.txt new file mode 100755 index 00000000..ab8aca15 --- /dev/null +++ b/huffware/huffotronic_tools_n_testers_v6.1/Vote_for_me_v4.2.txt @@ -0,0 +1,426 @@ + +// huffware script: vote for me, by fred huffhines. +// +// original author: ChuChu Ricardo January 14, 2010 +// numerous mods: Fred Huffhines, March 2010 [including but not limited to refactoring +// existing functions and fixing payment behavior] +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// this script is licensed by the GPL v3 which is documented at: http://www.gnu.org/licenses/gpl.html +// do not use it in objects without fully realizing you are implicitly accepting that license. +// + +// global constants... + +string LINDEN_MARK = "L$"; // the money symbol for linden dollars. +integer MINIMUM_FREE_MEMORY = 3400; // the least memory we can get by with. + +// a set of menu items we'll be displaying on the voter menu. +string ITEM_VOTEME = "Vote for Me"; +string ITEM_STATUS = "Show Info"; +string ITEM_NOT_NOW = "Not Now"; +// items for the owner menu only. +string ITEM_RESET = "Reset"; +string ITEM_GIVE_NOTE = "Give Note"; +string ITEM_NO_NOTE = "No Notecard"; +string ITEM_GIVE_OBJ = "Give Gift"; +string ITEM_NO_OBJ = "No Gift"; + +integer ONE_MINUTE; // number of seconds in a minute. initialized later. +integer ONE_HOUR; // number of seconds in an hour. initialized later. +integer FULL_DAY; // number of seconds in a day. initialized later. + +// these are the textures we'll show when it's time to register the average vote. +list TEXTURE_UUIDS = [ + "8dfc709a-c37d-6103-2670-d287e871f0e7", // zero average. + "14278369-1db4-4497-13ef-5dc75a1017f0", // lowest rating (red, many bars). + "8a891c33-1070-6c6b-148b-919651323b5e", + "25f8618d-181d-9af3-720e-01a3a0fa1861", + "3f89b392-b70a-8a63-f09f-b51f6d91b437", + "a6d02c4e-7b8c-0fd9-47a5-08cb61159bfa", + "b7fb64db-5658-547d-560d-3ca86ff77e37", + "bc8057e8-61f2-1919-74f9-59ea5b731bc7", + "ec54863f-665c-9dc0-ab64-051fe96750af", + "2acaa661-db7a-1035-d4e4-0ed50304887c", + "53f1465d-7f39-d1cc-6ade-4610ec053646", + "c868135f-0ad1-20ea-a85b-0c48a780ea7f", + "78215a59-c52b-1886-0cae-bce11592e9b1", + "ffa2ed36-df97-4889-4903-06dca758336d", + "f1a625cb-4346-91b2-8e48-9290be22ec90", + "6301df4e-d3bf-2b41-9738-a6e4b7f10715", + "a3f566fa-0e2e-68dc-92ac-a60258717525", + "83088c7a-8397-404d-1285-54def3ff179e", + "cde91186-7365-02c1-fe79-740cc82bc01a", + "08d22575-0848-b7c4-1dfb-665216165831" // highest rating (green, no bars) +]; + +// the secret channel where the user can change the text shown on title. +integer COMMAND_CHANNEL = 9; + +// global variables... + +key last_owner; // the last person who owned this object. +string persistent_message; // additional text for the title bar. +integer voter_dialog_channel; // where the voter (non-owner) menu will be heard. +integer owner_dialog_channel; // where the owner's big menu will be heard. +integer vote_price = 10; // amount of lindens paid per vote, with default value. +integer give_notecards = TRUE; // should we hand out notecards for a vote? +integer give_objects = TRUE; // should we hand out objects for a vote? + +// these four variables need to reset daily... +list voter_ids; // the identities of the voters. +list vote_magnitudes; // the value (on the likes-me scale) of each vote cast. +float average_score; // Average score computed so far. +integer last_reset_time; // the last time we did a vote reset. + +// perform initialization tasks. +setup_voteme() +{ + // initialize our "constants" here, since LSL doesn't like generated constants. + ONE_MINUTE = 60; + ONE_HOUR = 60 * ONE_MINUTE; + FULL_DAY = 24 * ONE_HOUR; + + last_owner = llGetOwner(); // remember so we can know when changing hands. + last_reset_time = llGetUnixTime(); // track when we cranked up. + + // default add-in for titler is the avatar's name. + persistent_message = llKey2Name(llGetOwner()); + + llSetText("VoteME: "+ persistent_message, <1,1,1>, 1.0); + + set_faces_to_texture((key)llList2String(TEXTURE_UUIDS, 0)); + + llRequestPermissions(llGetOwner(), PERMISSION_DEBIT); + + // set up the menu dialog channel so we will hear what they picked. + owner_dialog_channel = -(integer)(llFrand(999999) + 250); + voter_dialog_channel = owner_dialog_channel + 1; + llListen(owner_dialog_channel, "", llGetOwner(), ""); + llListen(voter_dialog_channel, "", NULL_KEY, ""); + + // listen on our special command channel. + llListen(COMMAND_CHANNEL, "", llGetOwner(), ""); + + llSetTimerEvent(ONE_MINUTE); +} + +// looks for the voter to see if they've already voted today. +// true is returned if the "id" is found. +integer seek_voter(key id) { return llListFindList(voter_ids, [id]) >= 0; } + +// adds a record for the voter with key "id", if they are not already present. +// true is returned if this is a new voter. +integer add_voter(key id) +{ + if (llGetFreeMemory() < MINIMUM_FREE_MEMORY) { + llOwnerSay("omitting vote due to low memory."); + return FALSE; + } + // if the entry's not there already, add it. + if (seek_voter(id)) return FALSE; // that one was there. + // if we got to here, then the voter was not there yet. + voter_ids += [ id ]; + return TRUE; +} + +// creates a string out of the time in "decode_time" which is expected to +// be compatible with llGetWallClock() values. +string time_string(integer decode_time) +{ + integer hours = decode_time / ONE_HOUR; + decode_time -= hours * ONE_HOUR; + integer minutes = decode_time / ONE_MINUTE; + decode_time -= minutes * ONE_MINUTE; + integer seconds = decode_time; + return (string)hours + ":" + (string)minutes + ":" + (string)seconds; +} + +// sets all the x/y faces of the object to the texture key specified. +// the top and bottom are unchanged. +set_faces_to_texture(key texture_id) +{ + integer i; + for (i = 1; i <= 4; i++) { + llSetTexture(texture_id, i); + } +} + +// pops up the menu for the owner's use. +show_owner_menu() +{ + string msg0 = "You can choose the amount you want voters to pay,\nor configure giving out notecards and/or gifts to your voters."; + list menu0_btns = [ + // first row at bottom. + ITEM_GIVE_NOTE, ITEM_NO_NOTE, ITEM_STATUS, + ITEM_GIVE_OBJ, ITEM_NO_OBJ, ITEM_RESET, + LINDEN_MARK + "10", LINDEN_MARK + "20", LINDEN_MARK + "50", + // last row at top. + LINDEN_MARK + "100" + ]; + + llDialog(llGetOwner(), msg0, menu0_btns, owner_dialog_channel); +} + +// lets the avatar know we can't process their vote right now. +apologize_but_refuse_vote() +{ + llSay(0, "Sorry, You have already voted for " + llKey2Name(llGetOwner()) + " today."); +} + +key last_toucher; // the last person that clicked the voter object. +//move this! + +// handles a particular avatar that has touched the voter. +process_toucher(integer which) +{ + string voter_id = llDetectedKey(which); + string voter_name = llDetectedName(which); + // see if this was the owner touching the object. + if (voter_id == llGetOwner()) { + show_owner_menu(); + return; // done with owner touch handling. + } + // handle when someone other than the owner touches the voter. + if (!seek_voter(voter_id)) { + // new voter. + if (last_toucher != voter_id) { + llSay(0, "Hello " + voter_name + "... please Vote for Me."); + last_toucher = voter_id; + if (give_notecards == TRUE) { + string card_name = llGetInventoryName(INVENTORY_NOTECARD, 0); + if (card_name != "") llGiveInventory(voter_id, card_name); + } + } + string msg1 = "Please Choose to Vote for me.\nYou can also choose to see my current voting status."; + list menu1_btns = [ ITEM_VOTEME, ITEM_STATUS, ITEM_NOT_NOW ]; + llDialog(voter_id, msg1, menu1_btns, voter_dialog_channel); + } else { + // they had already voted, so we don't give them the whole menu. + string msg1 = "Thanks for your vote! You can check my status, but you cannot vote again until tomorrow."; + list menu1_btns = [ ITEM_STATUS ]; + llDialog(voter_id, msg1, menu1_btns, voter_dialog_channel); + } +} + +// processes when an avatar touches the voter. +handle_touches(integer total_number) +{ + // run through all the people that touched the voter this time. + integer i; + for (i = 0; i < total_number; i++) { process_toucher(i); } +} + +// deals with people throwing money at us. +handle_monetary_gift(key giver, integer amount) +{ + if (giver == llGetOwner()) { + // fine, genius, you gave yourself some money. you don't get to vote. + return; + } + if (amount != vote_price) { + // refund the amount paid, since this was not the right vote cost. + llSay(0, "Oops! That's not the right amount for the vote; SL is hosing up or something. Here's a refund."); + llGiveMoney(giver, amount); + return; + } + if (seek_voter(giver)) { + // they've already voted so they're not allowed again. + apologize_but_refuse_vote(); + llGiveMoney(giver, amount); + return; + } + add_voter(giver); + + llSay(0, "Thanks for the " + LINDEN_MARK + (string)amount + ", " + llKey2Name(giver) + + ". Your voting menu will open shortly."); + + string msg3 = "Voting Key:\n1-means you like me a little\n10-means you really adore me\nThank You!"; + list menu3_btns = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" ]; + llDialog(giver, msg3, menu3_btns, voter_dialog_channel); +} + +// announces how the owner is doing so far. +show_status() +{ + integer count = llGetListLength(voter_ids); + llSay(0, "My name is " + llKey2Name(llGetOwner()) + " and I have received " + + (string)count + " votes.\n" + + "My average score per vote is " + (string)average_score + "."); + +integer since_reset = llGetUnixTime() - last_reset_time; +llOwnerSay("last reset " + time_string(since_reset) + " H:M:S ago."); + +} + +// processes responses from menus and deals with spoken commands. +hear_voices(integer channel, string speaker_name, key id, string message) +{ + // see if this is from the owner about what to show on the voter. + if ( (channel == COMMAND_CHANNEL) && (id == llGetOwner()) ) { +//hmmm: undocumented! + persistent_message = message; + llOwnerSay("Changed title bar to add \"" + persistent_message + "\"."); + llSetText("VoteME: " + persistent_message, <1,1,1>, 1.0); + return; + } + + // check if the message comes from the owner's dialog. + if (channel == owner_dialog_channel) { + if (message == ITEM_STATUS) { + show_status(); + return; + } else if (message == ITEM_RESET) { +//hmmm: is this in the menu??? + llOwnerSay("Resetting now..."); + llResetScript(); + } else if (llGetSubString(message, 0, 1) == LINDEN_MARK) { + vote_price = (integer)llGetSubString(message,2,-1); + llOwnerSay("Voting for you will now cost avatars " + + LINDEN_MARK + (string)vote_price + "."); + llSetPayPrice(PAY_HIDE, [vote_price, PAY_HIDE, PAY_HIDE, PAY_HIDE]); + } else if (message == ITEM_GIVE_OBJ) { + llOwnerSay("Gift giving enabled."); + give_objects = TRUE; + } else if (message == ITEM_NO_OBJ) { + llOwnerSay("Gift giving disabled."); + give_objects = FALSE; + } else if (message == ITEM_GIVE_NOTE) { + llOwnerSay("Notecard giving enabled."); + give_notecards = TRUE; + } else if (message == ITEM_NO_NOTE) { + llOwnerSay("Notecard giving disabled."); + give_notecards = FALSE; + } + // assume for the choices that fall through that they want to see the menu again. + show_owner_menu(); + return; // done handling our own dialog. + } + + // see if this is the dialog for the voting person. + if (channel == voter_dialog_channel) { + if (message == ITEM_VOTEME) { + string msg2 = "To show your confidence in me, pay me " + + LINDEN_MARK + (string)vote_price + ".\n" + + "Then rate me from 1 to 10 after you pay.\n" + + "1 = You like me a little bit\n10 = You really adore me\n" + + "Ready? Right-click this object and pick \"Pay\". Thanks very much!"; + list menu2_btns = [ "Understood" ]; + llDialog(id, msg2, menu2_btns, voter_dialog_channel); + } else if (message == ITEM_STATUS) { + show_status(); + } else if (message == ITEM_NOT_NOW) { + llSay(0, "Thanks for the interest anyhow, " + llKey2Name(id) + "."); + } else if ((integer)message > 0 && (integer)message <= 10) { + if (give_notecards == TRUE) { + string name = llGetInventoryName(INVENTORY_NOTECARD, 0); + if (name != "") llGiveInventory(id, name); + } + if (give_objects == TRUE) { + string name = llGetInventoryName(INVENTORY_OBJECT, 0); + if (name != "") llGiveInventory(id, name); + } + register_vote((integer)message); + } + } +} + +// deals with our timer clicks. +handle_timer() +{ + integer wall_clock = (integer)llGetWallclock(); + +//llOwnerSay("tick: " + time_string(wall_clock)); + + // see if it seems like time to reset. we'll do this when the clock has just passed + // midnight (that is, we're in the first hour after midnight), or if the device had + // possibly been taken out of commission a long time ago (meaning more time has passed + // since the last reset than has elapsed today so far). + integer reset_it = FALSE; + integer time_since_reset = llGetUnixTime() - last_reset_time; + // is it the first hour of midnight, and we didn't just reset? + if ( (wall_clock < ONE_HOUR) && (time_since_reset > ONE_HOUR) ) reset_it = TRUE; + // or, is it a really long time since we did reset? longer than when the hour turned? + if (time_since_reset > wall_clock) reset_it = TRUE; + + if (reset_it) { + // aha, we've decided it's that time. + llOwnerSay("Resetting voters and average, since the clock rolled over."); + voter_ids = []; + vote_magnitudes = []; + average_score = 0; + last_reset_time = llGetUnixTime(); + register_vote(0); // just recalculate average and show texture. + } +} + +// tracks that they've made a vote. +register_vote(integer this_vote_value) +{ + // zero is a special value that just makes us recalculate the average. + if (this_vote_value != 0) vote_magnitudes += [ this_vote_value ]; + +//move this to an averager method. + integer sum = 0; + integer n = llGetListLength(vote_magnitudes); + integer i = 0; + for(i = 0;i= 20) tex_num = 19; //We dont have all green texture + + set_faces_to_texture((key)llList2String(TEXTURE_UUIDS, tex_num)); +} + +default { + state_entry() { if (llSubStringIndex(llGetObjectName(), "huffotronic") < 0) state real_default; } + on_rez(integer parm) { state rerun; } +} +state rerun { state_entry() { state default; } } + +// main state machine. +state real_default +{ + state_entry() { setup_voteme(); } + + on_rez(integer parm) { + if (last_owner != llGetOwner()) { + llOwnerSay("Now configuring for " + llKey2Name(llGetOwner())); + llResetScript(); + } + } + + run_time_permissions(integer perm) { + if (perm & PERMISSION_DEBIT) { +//llOwnerSay("got permission for debits, will set price to " + (string)vote_price); + llSetPayPrice(PAY_HIDE, [vote_price, PAY_HIDE, PAY_HIDE, PAY_HIDE]); + } else { + llOwnerSay("We were denied debit permission and cannot function without it. Use the menu and select \"" + ITEM_RESET + "\" to fix this."); + } + } + + timer() { handle_timer(); } + + touch_start(integer total_number) { handle_touches(total_number); } + + money(key giver, integer amount) { handle_monetary_gift(giver, amount); } + + listen(integer channel, string name, key id, string message) + { hear_voices(channel, name, id, message); } +} + + +//feature ideas: +// have the voter track the highest paying guy? +// actually no, the owner sets that limit. rats. +// but what about the highest voting guy!? the guy/gal who thought the most could be tracked. + +//hmmm: need a helper notecard function for owner! +