Table of Contents

About

Similar to the trivia ball, a party ball can be created that, when touched, will randomly select an avatar in range and ask a question from a series of notecards inside the party ball.

The build takes care to randomly shuffle both notecards and notecard lines in order to not be too repetitive.

Screenshot

Code

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2021 - 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    //
///////////////////////////////////////////////////////////////////////////
list spinChars = [ "↑", "↗", "→", "↘", "↓", "↙", "←" ];
string spin() {
    string text = llList2String(llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXT]), 0);
    do {
        string tok = llGetSubString(text, llStringLength(text)-1, llStringLength(text)-1);
        if(!~llListFindList(spinChars, (list)tok) && tok != "\n" && tok != "[" && tok != "]") jump show;
        text = llDeleteSubString(text, llStringLength(text)-1, llStringLength(text)-1);
    } while(llStringLength(text));
@show;
    string next = llList2String(spinChars,  0);
    spinChars = llDeleteSubList(spinChars, 0, 0);
    spinChars += next;
    return "[" + next + "]";
}
 
list cards = [];
integer cardIterator;
integer lineIterator;
string card;
integer shutdown;
string question;
 
default {
    state_entry() {
        llSetText("-=:[ Please wait, reading brains... ]:=-\n", <1,1,0>, 1);
        integer i = llGetInventoryNumber(INVENTORY_NOTECARD)-1;
        do {
            list qCard = llParseString2List(llGetInventoryName(INVENTORY_NOTECARD, i), ["_"], [""]);
            if(llList2String(qCard, 0) != "Question" || llList2String(qCard, 1) != "Brain") jump continue;
            cards += llGetInventoryName(INVENTORY_NOTECARD, i);
@continue;
        } while(--i>-1);
        if(llGetListLength(cards) != 0) {
            state select;
        }
        llSay(DEBUG_CHANNEL, "Failed to find any Question brains.");
    }
    on_rez(integer param) {
        llResetScript();
    }
    changed(integer change) {
        if(change & CHANGED_INVENTORY) llResetScript();
    }
}
 
state select {
    state_entry() {
        cardIterator = (integer)llFrand((float)llGetListLength(cards));
        card = llList2String(cards, cardIterator);
        llGetNumberOfNotecardLines(card);
    }
    dataserver(key id, string data) {
        lineIterator = (integer)llFrand((integer) data);
        state search;
    }
    on_rez(integer param) {
        llResetScript();
    }
    changed(integer change) {
        if(change & CHANGED_INVENTORY) llResetScript();
    }
}
 
state search {
    state_entry() {
        card = llList2String(cards, cardIterator);
        llGetNotecardLine(card, lineIterator);
    }
    dataserver(key id, string data) {
        if(data == EOF) {
            cardIterator = (integer)llFrand((float)llGetListLength(cards));
            state select;
        }
        if(data == "") jump continue;
        question = data;
        cardIterator = (integer)llFrand((float)llGetListLength(cards));
        state ask;
@continue;
        string text = "-=:[ Searching question... ]:=-\n" + "Brain: " + card + " " + spin();
        llSetText(text, <1,1,0>, 1);
        llGetNotecardLine(card, --lineIterator);
    }
    on_rez(integer param) {
        llResetScript();
    }
    changed(integer change) {
        if(change & CHANGED_INVENTORY) llResetScript();
    }
}
 
state ask {
    state_entry() {
        llSetText("-=:[ Touch for a question... ]:=-\n", <1,1,0>, 1);
    }
    touch_start(integer num) {
        llSensor("", "", AGENT, 64, TWO_PI);
    }
    no_sensor() {
        llSetText("-=:[ Nobody is in range :( ]:=-\n", <1,1,0>, 1);
        llSetTimerEvent(1);
    }
    sensor(integer num) {
        string name = llDetectedName((integer)llFrand((float)num));
        vector qC = <llFrand(1), llFrand(1), llFrand(1)>;
        llParticleSystem([
           PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0), 
           PSYS_PART_START_SCALE, <.01, .014, 0>, PSYS_PART_END_SCALE, <.1, .14, 0>, 
           PSYS_PART_START_COLOR, qC,    PSYS_PART_END_COLOR, <.5 + qC.x,.5 + qC.y, .5 + qC.z>,
           PSYS_SRC_BURST_PART_COUNT, 0x7FFFFFFF,
           PSYS_PART_MAX_AGE, 1.25,
           PSYS_SRC_MAX_AGE, 1.25,
           PSYS_SRC_PATTERN, 8,
           PSYS_SRC_BURST_SPEED_MIN, (float)1,   PSYS_SRC_BURST_SPEED_MAX, (float)1.2, 
           PSYS_SRC_ANGLE_BEGIN, 0,    PSYS_SRC_ANGLE_END, TWO_PI,       
           PSYS_PART_FLAGS, ( 0 | PSYS_PART_INTERP_SCALE_MASK
                                | PSYS_PART_INTERP_COLOR_MASK    
                                | PSYS_PART_EMISSIVE_MASK     
                            )                  
        ]);
        llShout(0, name + ": " +question);
        state select;
    }
    timer() {
        state select;
    }
    on_rez(integer param) {
        llResetScript();
    }
    changed(integer change) {
        if(change & CHANGED_INVENTORY) llResetScript();
    }
}