Table of Contents

ChangeLog

15 July 2015

  • Added the ability to restrict the looting only to the members of the same group as the objects that also have the same group active - thank you K9Instinct!

About

On role-play simulators, or for game-hunts, this script allows you to create lootable coins that will reward the toucher once they have been clicked. The scripts uses a configuration notecard which defines the reward amount and whether the owner is asked for a confirmation before looting the coin.

Setup

####################### START CONFIGURATION ##################################

# This is the reward to be paid...
reward = 100

# Whether to ask the owner to confirm the payment...
# Valid values for this setting are:  yes or no
confirm = no

# If this is set to "true", then looting will be permitted only to members
# that have the same group active as this object's group. To make this work,
# you need to set this object to your group and avatars will have to set their
# current active group as your object.
#
# Valid values for this setting are: true or false
group = true

####################### END CONFIGURATION ###################################

and drop it inside the primitive.

Settings

There are two settings as of the current version of the script:

Code

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueEncode(list data) {
    list k = llList2ListStrided(data, 0, -1, 2);
    list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
    data = [];
    do {
        data += llList2String(k, 0) + "=" + llList2String(v, 0);
        k = llDeleteSubList(k, 0, 0);
        v = llDeleteSubList(v, 0, 0);
    } while(llGetListLength(k) != 0);
    return llDumpList2String(data, "&");
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string k, string data) {
    if(llStringLength(data) == 0) return "";
    if(llStringLength(k) == 0) return "";
    list a = llParseStringKeepNulls(data, ["&", "="], []);
    integer i = llListFindList(a, [ k ]);
    if(i != -1) return llList2String(a, i+1);
    return "";
}
 
// for notecard reading
integer line = 0;
 
// key-value data will be read into this list
list tuples = [];
 
// com handle
integer handle = 0;
// avatar
key winner = NULL_KEY;
 
default {
    state_entry() {
        if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
            llSay(DEBUG_CHANNEL, "Sorry, could not find an inventory notecard.");
            return;
        }
        llGetNotecardLine("configuration", line);
    }
    dataserver(key id, string data) {
        if(data == EOF) state permissions; // invariant, length(tuples) % 2 == 0
        if(data == "") jump continue;
        integer i = llSubStringIndex(data, "#");
        if(i != -1) data = llDeleteSubString(data, i, -1);
        list o = llParseString2List(data, ["="], []);
        string k = llStringTrim(llList2String(o, 0), STRING_TRIM);
        string v = llStringTrim(llList2String(o, 1), STRING_TRIM);
        if(k == "" || v == "") jump continue;
        tuples += k;
        tuples += v;
@continue;
        llGetNotecardLine("configuration", ++line);
    }
    on_rez(integer num) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
}
 
state permissions {
    state_entry() {
        llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
    }
    run_time_permissions(integer perm) {
        if(perm & PERMISSION_DEBIT) state process;
        llSay(DEBUG_CHANNEL, "You must grant permission for the script to pay out.");
        llSetTimerEvent(5);
    }
    timer() {
        llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
}
 
state process {
    touch_start(integer num) {
        string group = wasKeyValueGet("group", wasKeyValueEncode(tuples));
        if(group != "false" && llDetectedGroup(0) == FALSE) {
            llInstantMessage(llDetectedKey(0), "Sorry, you do not have the same group active as this object.");
            return;
        }
        winner = llDetectedKey(0);
        state click;
    }
    on_rez(integer num) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
}
 
state click {
    state_entry() {
        if(wasKeyValueGet("confirm", wasKeyValueEncode(tuples)) == "no") {
            if(llGetPermissions() & PERMISSION_DEBIT) {
                llTransferLindenDollars(winner, (integer)wasKeyValueGet("reward", wasKeyValueEncode(tuples)));
            }
            return;
        }
        integer channel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        handle = llListen(channel, "", llGetOwner(), "");
        llDialog(
            llGetOwner(), 
            llKey2Name(winner) + " requests to be paid the reward of: L$" + wasKeyValueGet("reward", wasKeyValueEncode(tuples)) + ". Do you accept or decline the request?",
            [ "✔ Accept", "✗ Decline" ],
            channel
        );
    }
    listen(integer channel, string name, key id, string message) {
        llListenRemove(handle);
        if(message != "✔ Accept") state process;
        if(llGetPermissions() & PERMISSION_DEBIT) {
            llTransferLindenDollars(winner, (integer)wasKeyValueGet("reward", wasKeyValueEncode(tuples)));
            return;
        }
        llSay(DEBUG_CHANNEL, "Lost debit permissions, script is resetting.");
    }
    transaction_result(key id, integer success, string data) {
        if(success == FALSE) {
            llSay(DEBUG_CHANNEL, "There was an error making the payment, script is resetting.");
            llResetScript();
        }
        llTriggerSound("5d1c1f23-513d-531f-7ea9-58488f57d3e8",1);
        llDie();
    }
    on_rez(integer num) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
}