<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://opensimulator.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://opensimulator.org/index.php?action=history&amp;feed=atom&amp;title=User%3AAllen_Kerensky%2FMyriad_Lite_Dev%2FBAM_Touch_Goal-v0.0.9-20120704.lsl</id>
		<title>User:Allen Kerensky/Myriad Lite Dev/BAM Touch Goal-v0.0.9-20120704.lsl - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://opensimulator.org/index.php?action=history&amp;feed=atom&amp;title=User%3AAllen_Kerensky%2FMyriad_Lite_Dev%2FBAM_Touch_Goal-v0.0.9-20120704.lsl"/>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite_Dev/BAM_Touch_Goal-v0.0.9-20120704.lsl&amp;action=history"/>
		<updated>2026-06-13T22:46:08Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.19.9</generator>

	<entry>
		<id>http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite_Dev/BAM_Touch_Goal-v0.0.9-20120704.lsl&amp;diff=30047&amp;oldid=prev</id>
		<title>Allen Kerensky: created</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite_Dev/BAM_Touch_Goal-v0.0.9-20120704.lsl&amp;diff=30047&amp;oldid=prev"/>
				<updated>2012-07-05T02:52:15Z</updated>
		
		<summary type="html">&lt;p&gt;created&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= BAM_Location_Goal-v0.0.9-20120704.lsl =&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Baroun's Adventure Machine BAM_Touch_Goal-v0.0.9-20120704.lsl&lt;br /&gt;
// Copyright (c) 2008-2012 Baroun Tardis (SL) and Allen Kerensky (OSG/SL)&lt;br /&gt;
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai&lt;br /&gt;
// Myriad RPG licensed under the Creative Commons Attribution 2.0 UK: England and Wales&lt;br /&gt;
// http://creativecommons.org/licenses/by/2.0/uk/&lt;br /&gt;
// Myriad Lite software Copyright (c) 2011-2012 by Allen Kerensky (OSG/SL)&lt;br /&gt;
// Baroun's Adventure Machine Copyright (c) 2008-2011 by Baroun Tardis (SL)&lt;br /&gt;
// Myriad Lite and Baroun's Adventure Machine licensed under the&lt;br /&gt;
// Creative Commons Attribution-Share Alike-Non-Commercial 3.0 Unported&lt;br /&gt;
// http://creativecommons.org/licenses/by-nc-sa/3.0/&lt;br /&gt;
// You must agree to the terms of this license before making any use of this software.&lt;br /&gt;
// If you do not agree to this license, simply delete these materials.&lt;br /&gt;
// There is no warranty, express or implied, for your use of these materials.&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// Adventure-Specific Configuration&lt;br /&gt;
// Task numbers are (AdvNum*100)+task, so they don't overlap between adventures&lt;br /&gt;
//============================================================================&lt;br /&gt;
&lt;br /&gt;
// NPC or object-specific info&lt;br /&gt;
&lt;br /&gt;
// Adventure-specific info&lt;br /&gt;
string ADVNAME          = &amp;quot;Red Salt&amp;quot;; // Adventure Name&lt;br /&gt;
&lt;br /&gt;
// Current Task-specific info&lt;br /&gt;
integer ADVGOAL         = 102; // current goal&lt;br /&gt;
string  TASKDONETEXT    = &amp;quot;You've found the salt!&amp;quot;; // Mission complete message&lt;br /&gt;
string  RUMOR_TASK_DONE = &amp;quot; found the red salt.&amp;quot;; // rumor done&lt;br /&gt;
string  TASKDONEUUID    = &amp;quot;f78027c9-e8bb-38f2-9b11-1d4e89ac10a4&amp;quot;; // sound byte to play&lt;br /&gt;
string  PRIZENAME       = &amp;quot;NONE&amp;quot;; // prize to give when mission complete&lt;br /&gt;
&lt;br /&gt;
// Next Task-specific info&lt;br /&gt;
integer ADVTASKTDNUM    = 103; // next task to hand out when task is done&lt;br /&gt;
string  ADVTASKTODO     = &amp;quot;Return the salt to the baker&amp;quot;; // the next goal message&lt;br /&gt;
string  ADVTASKTODOHINT = &amp;quot;He's where you first met him&amp;quot;; // hint for the next goal&lt;br /&gt;
&lt;br /&gt;
float TOUCH_RANGE = 1.5; // in meters, how close to be for touch to work arms &amp;amp; legs = 1.5m&lt;br /&gt;
integer PRIZEWAIT = 3600; // seconds to remember players who got prize?&lt;br /&gt;
float EVENTTIMER = 15.0; // seconds between running memory and list cleanup timed events&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// MESSAGE FORMAT REFERENCE&lt;br /&gt;
//============================================================================&lt;br /&gt;
// Ask a player HUD if the player is in an adventure - InAdv?&lt;br /&gt;
&lt;br /&gt;
// Player responds:&lt;br /&gt;
// Yes in an adventure - InAdv | String AdventureName&lt;br /&gt;
// No, not in adventure - InAdv | NONE&lt;br /&gt;
&lt;br /&gt;
// Task In Progress Query - Ask player what their current goal is&lt;br /&gt;
// NPC/Object Send Example: TaskIP?&lt;br /&gt;
&lt;br /&gt;
// Task In Progress Response - The player Responds with current task in progress&lt;br /&gt;
// Player Send Example: TaskIP | AdventureGoal&lt;br /&gt;
&lt;br /&gt;
// Task Done - Tell player they have achieved their current goal&lt;br /&gt;
// NPC Object Send Example: DoneTask | GoalText | TaskDone Text | PlayerUUID&lt;br /&gt;
&lt;br /&gt;
// Add a task to the Player HUD - AddTask | TaskNumber | String Describing Task&lt;br /&gt;
// Add a hint for a task to the Player HUD - AddHint | TaskNumber | String Hint&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// GLOBAL CONSTANTS&lt;br /&gt;
//============================================================================&lt;br /&gt;
string MSG_STARTUP          = &amp;quot;Baroun's Adventure Machine is activating&amp;quot;;&lt;br /&gt;
string CHAN_PREFIX          = &amp;quot;0x&amp;quot;; // prefix for calculating dynamic channels from UUIDs&lt;br /&gt;
string API_DIVIDER          = &amp;quot;|&amp;quot;; // The field divider within BAM packets&lt;br /&gt;
string API_INADV_QUERY      = &amp;quot;InAdv?&amp;quot;; // ask a player HUD if the player is in an adventure?&lt;br /&gt;
string API_INADV_RESPONSE   = &amp;quot;InAdv&amp;quot;; // player response to in adventure request&lt;br /&gt;
string API_TASKIP_QUERY     = &amp;quot;TaskIP?&amp;quot;; // what is player task-in-progress?&lt;br /&gt;
string API_TASKIP_RESPONSE  = &amp;quot;TaskIP&amp;quot;; // player says current task-in-progress&lt;br /&gt;
string API_DONETASK         = &amp;quot;DoneTask&amp;quot;; // tell player the task is done&lt;br /&gt;
string API_NONE             = &amp;quot;NONE&amp;quot;; // magic value for no current adventure, or no prize&lt;br /&gt;
string API_ADDTASK          = &amp;quot;AddTask&amp;quot;; // add a task to player HUD&lt;br /&gt;
string API_ADDHINT          = &amp;quot;AddHint&amp;quot;; // add a task hint to player HUD&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// GLOBAL RUNTIME&lt;br /&gt;
//============================================================================&lt;br /&gt;
list    RECENT;     // list people who recently checked this goal&lt;br /&gt;
list    GOTPRIZES; // list of who got prizes [UUID,unixtime]&lt;br /&gt;
key     AVKEY;      // key of player&lt;br /&gt;
string  AVNAME;     // name of player&lt;br /&gt;
integer BAM;        // Channel we listen on&lt;br /&gt;
integer TARGET;     //channel of thing we're talking to&lt;br /&gt;
integer HANDLE;     // hold a handle for the open listener&lt;br /&gt;
&lt;br /&gt;
integer CHAN_REGION = -999;&lt;br /&gt;
integer HAND_RUMOR;&lt;br /&gt;
integer CHAN_RUMOR;&lt;br /&gt;
string  API_RUMOR_FIND = &amp;quot;RUMOR_SERVER_FIND&amp;quot;;&lt;br /&gt;
string  API_RUMOR_FOUND = &amp;quot;RUMOR_SERVER_FOUND&amp;quot;;&lt;br /&gt;
string  API_RUMOR_PUT = &amp;quot;RUMOR_PUT&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer FLAG_DEBUG;&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// DEBUG&lt;br /&gt;
//============================================================================&lt;br /&gt;
DEBUG(string debugmsg) {&lt;br /&gt;
    if ( FLAG_DEBUG == TRUE ) llInstantMessage(llGetOwnerKey(llGetKey()),&amp;quot;DEBUG: &amp;quot;+debugmsg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// DEFAULT STATE&lt;br /&gt;
//============================================================================&lt;br /&gt;
default {&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    // LISTEN EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    listen(integer chan, string name, key id, string msg) {&lt;br /&gt;
        chan = 0; // LSLINT&lt;br /&gt;
        name = &amp;quot;&amp;quot;; // LSLINTlsl&lt;br /&gt;
&lt;br /&gt;
        // Rumor server found, save its channel number&lt;br /&gt;
        if ( msg == API_RUMOR_FOUND ) {&lt;br /&gt;
            CHAN_RUMOR = (integer)(CHAN_PREFIX + llGetSubString((string)id,0,6));&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // calculate the BAM dynamic channel of the person interacting with us&lt;br /&gt;
        TARGET= (integer)(CHAN_PREFIX + llGetSubString((string)llGetOwnerKey(id),-7,-1));&lt;br /&gt;
&lt;br /&gt;
        list tokens = llParseString2List(msg, [API_DIVIDER], []); // split message apart around | symbols&lt;br /&gt;
        string command = llList2String(tokens, 0); // assign first item in list as BAM command&lt;br /&gt;
        string data    = llList2String(tokens, 1); // assign second item in list as BAM data for command&lt;br /&gt;
&lt;br /&gt;
        // if they answer with the current adventure, then react accordingly&lt;br /&gt;
        if ( command == API_INADV_RESPONSE ) { // player responded they are in an adventure&lt;br /&gt;
            if ( data == ADVNAME ) { // are they in THIS adventure?&lt;br /&gt;
                llSay(TARGET,API_TASKIP_QUERY); // if so, ask which task in this adventure they are working on&lt;br /&gt;
                return; // exit early to save processing&lt;br /&gt;
            }&lt;br /&gt;
            return; // done processing &amp;quot;in adventure&amp;quot; responses, exit listen early&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ( command == API_TASKIP_RESPONSE ) { // player responded with their task in progress&lt;br /&gt;
            if ( data == (string)ADVGOAL ) { // its the task for THIS object - player has found the goal&lt;br /&gt;
&lt;br /&gt;
                // tell player HUD the task is done! - DoneTask|(num)|(text)|UUID&lt;br /&gt;
                llSay(TARGET, API_DONETASK + API_DIVIDER + (string)ADVGOAL+ API_DIVIDER +TASKDONETEXT+ API_DIVIDER+ TASKDONEUUID);&lt;br /&gt;
                // now tell GM the task is done&lt;br /&gt;
                DEBUG(llKey2Name(llGetOwnerKey(id))+&amp;quot; (adventure &amp;quot;+ADVNAME+&amp;quot;): finished task &amp;quot;+(string)ADVGOAL+&amp;quot; (&amp;quot;+TASKDONETEXT+&amp;quot;).&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                // Send a rumor that the player progressed in the quest&lt;br /&gt;
                if ( CHAN_RUMOR != 0 ) {&lt;br /&gt;
                    string who = llKey2Name(llGetOwnerKey(id));&lt;br /&gt;
                    string rumor = API_RUMOR_PUT+API_DIVIDER+who+API_DIVIDER+who+RUMOR_TASK_DONE;&lt;br /&gt;
                    llRegionSay(CHAN_RUMOR,rumor);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // The Task is Done, Distribute the Prize, if any&lt;br /&gt;
                if ( PRIZENAME != API_NONE &amp;amp;&amp;amp; llListFindList(GOTPRIZES,[llGetOwnerKey(id)]) == -1 ) { // is there a prize at this step?&lt;br /&gt;
                    llGiveInventory(llGetOwnerKey(id),PRIZENAME); // give it over&lt;br /&gt;
                    GOTPRIZES = [ llGetOwnerKey(id), (llGetUnixTime() + PRIZEWAIT) ] + GOTPRIZES; // remember who and when&lt;br /&gt;
                    // tell the GM&lt;br /&gt;
                    DEBUG(llKey2Name(llGetOwnerKey(id))+&amp;quot; (adventure &amp;quot;+ADVNAME+&amp;quot;) prize given: &amp;quot;+PRIZENAME);&lt;br /&gt;
                }&lt;br /&gt;
                // Does finishing this task trigger a new task? If so, add it and a hint to the HUD&lt;br /&gt;
                if ( ADVTASKTDNUM != 0 ) { // there is a &amp;quot;TODO&amp;quot; task too&lt;br /&gt;
                    // assign the next task to the player HUD&lt;br /&gt;
                    llSay(TARGET, API_ADDTASK + API_DIVIDER +(string)ADVTASKTDNUM + API_DIVIDER + ADVTASKTODO);&lt;br /&gt;
                    // assign the next task HINT to the player HUD&lt;br /&gt;
                    llSay(TARGET, API_ADDHINT + API_DIVIDER +(string)ADVTASKTDNUM + API_DIVIDER + ADVTASKTODOHINT);&lt;br /&gt;
                    // tell the GM the player is on the next task&lt;br /&gt;
                    DEBUG(llKey2Name(llGetOwnerKey(id))+&amp;quot; (adventure &amp;quot;+ADVNAME+&amp;quot;): Assigning next task &amp;quot;+(string)ADVTASKTDNUM+&amp;quot; (&amp;quot;+ADVTASKTODO+&amp;quot;)&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                return; // we're done with API_TASKIP_RESPONSE, so exit listen early in case we add more commands later&lt;br /&gt;
            } // if data = ADVGOAL&lt;br /&gt;
            return; // return early since we are done with TASKIP responses, in case we add more later&lt;br /&gt;
        } // end if command equal TASKIP reponse&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    // STATE_ENTRY EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        FLAG_DEBUG = FALSE;&lt;br /&gt;
        DEBUG(MSG_STARTUP);&lt;br /&gt;
        // calculate our dynamic channel&lt;br /&gt;
        BAM= (integer)(CHAN_PREFIX + llGetSubString((string)llGetKey(),-7,-1));&lt;br /&gt;
        HANDLE = llListen(BAM,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;); // start a listener with llremove handle&lt;br /&gt;
        if ( HAND_RUMOR != 0 ) llListenRemove(HAND_RUMOR);&lt;br /&gt;
        CHAN_RUMOR = (integer)(CHAN_PREFIX + llGetSubString((string)llGetKey(),0,6));&lt;br /&gt;
        HAND_RUMOR = llListen(CHAN_RUMOR,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;);&lt;br /&gt;
        llRegionSay(CHAN_REGION,API_RUMOR_FIND); // send request for rumor server channel&lt;br /&gt;
        llSetTimerEvent(EVENTTIMER); // set a timer to manage the recent list&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    // TIMER EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    timer() {&lt;br /&gt;
        // on timer, check memory left and clear recent list if needed&lt;br /&gt;
        integer freemem = llGetFreeMemory(); // how much memory free?&lt;br /&gt;
        if ( freemem &amp;lt; 1024 ) { // is it too little?&lt;br /&gt;
            DEBUG(&amp;quot;Memory low for &amp;quot;+llGetObjectName()+&amp;quot; in &amp;quot;+llGetRegionName()+&amp;quot;. Resetting RECENT list.&amp;quot;);&lt;br /&gt;
            RECENT=[]; // clear the recent list&lt;br /&gt;
            GOTPRIZES=[]; // clear the gotPrizes list&lt;br /&gt;
            return; // exit timer event, no sense in processing lists further since we just emptied them&lt;br /&gt;
        }&lt;br /&gt;
        // check to see if entries in RECENT list have expired&lt;br /&gt;
        integer i; // temporary index number into list&lt;br /&gt;
        list temprecent = []; // temporary list to hold entries we want to keep&lt;br /&gt;
        key who; // temporary place to keep the keys we process in the lists&lt;br /&gt;
        integer time; // temporary place to keep the time we process in the lists&lt;br /&gt;
        for (i = 0; i &amp;lt; llGetListLength(RECENT); i += 2) { // step through strided list from begin to end&lt;br /&gt;
            who = llList2Key(RECENT,i); // get the UUID for this list stride&lt;br /&gt;
            time = llList2Integer(RECENT,i+1); // get the integer time for this list stride&lt;br /&gt;
            if ( llGetUnixTime() &amp;lt; time ) temprecent = [who,time] + temprecent; // non expired, keep this entry&lt;br /&gt;
        }&lt;br /&gt;
        RECENT = temprecent; // now, replace the RECENT list with the pruned version&lt;br /&gt;
        // check to see if entries in GOTPRIZES list have expired&lt;br /&gt;
        temprecent = []; // clear the temp list again&lt;br /&gt;
        for (i = 0; i &amp;lt; llGetListLength(GOTPRIZES); i += 2) { // step through next strided list&lt;br /&gt;
            who = llList2Key(GOTPRIZES,i); // get the uuid for this list stride&lt;br /&gt;
            time = llList2Integer(GOTPRIZES,i+1); // get the integer time for this list stride&lt;br /&gt;
            if ( llGetUnixTime() &amp;lt; time ) temprecent = [who,time] + temprecent; // non expired, keep this entry&lt;br /&gt;
        }&lt;br /&gt;
        GOTPRIZES = temprecent; // replace the gotprizes list with the pruned one        &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    // TOUCH EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    touch_start(integer times_touched) {&lt;br /&gt;
        while (times_touched--) { // count down through all touches in this event&lt;br /&gt;
            AVKEY=llDetectedKey(times_touched); // get the UUID of the toucher&lt;br /&gt;
            AVNAME=llDetectedName(times_touched); // get the name of the toucher&lt;br /&gt;
            float dist = llVecDist(llGetPos(),llList2Vector(llGetObjectDetails(AVKEY,[OBJECT_POS]),0)); // find distance between item and toucher&lt;br /&gt;
            if ( dist &amp;lt;= TOUCH_RANGE ) { // is toucher within arms reach?&lt;br /&gt;
                if ( llListFindList(RECENT,[AVKEY]) == -1 ) { // is player in recent list?&lt;br /&gt;
                    RECENT = [AVKEY] + RECENT; // no, add player to list&lt;br /&gt;
                }&lt;br /&gt;
                // calculate player-specific BAM dynamic channel&lt;br /&gt;
                TARGET= (integer)(CHAN_PREFIX + llGetSubString((string)AVKEY,-7,-1));&lt;br /&gt;
                llSay(TARGET, API_INADV_QUERY); // ask player if they are in adventure, must be within 10m for effect&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
//============================================================================&lt;br /&gt;
// END&lt;br /&gt;
//============================================================================&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Allen Kerensky</name></author>	</entry>

	</feed>