<?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%2FBAM_Adventure_Giver_NPC-Preview6.lsl</id>
		<title>User:Allen Kerensky/Myriad Lite/BAM Adventure Giver NPC-Preview6.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%2FBAM_Adventure_Giver_NPC-Preview6.lsl"/>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite/BAM_Adventure_Giver_NPC-Preview6.lsl&amp;action=history"/>
		<updated>2026-06-13T20:07:52Z</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/BAM_Adventure_Giver_NPC-Preview6.lsl&amp;diff=30363&amp;oldid=prev</id>
		<title>Allen Kerensky: version and date fix</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite/BAM_Adventure_Giver_NPC-Preview6.lsl&amp;diff=30363&amp;oldid=prev"/>
				<updated>2012-08-12T14:53:46Z</updated>
		
		<summary type="html">&lt;p&gt;version and date fix&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 14:53, 12 August 2012&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 34:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 34:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;// Creative Commons Attribution (CC BY) 2.0 UK: England and Wales&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;// Creative Commons Attribution (CC BY) 2.0 UK: England and Wales&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;// http://creativecommons.org/licenses/by/2.0/uk/&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;// http://creativecommons.org/licenses/by/2.0/uk/&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;string&amp;#160; VERSION = &amp;quot;0.0.7&amp;quot;; // version number&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;string&amp;#160; VERDATE = &amp;quot;20120704&amp;quot;; // version date&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;//============================================================================&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;//============================================================================&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Allen Kerensky</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite/BAM_Adventure_Giver_NPC-Preview6.lsl&amp;diff=30359&amp;oldid=prev</id>
		<title>Allen Kerensky: BAM_Adventure_Giver_NPC-Preview6.lsl</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite/BAM_Adventure_Giver_NPC-Preview6.lsl&amp;diff=30359&amp;oldid=prev"/>
				<updated>2012-08-12T14:37:18Z</updated>
		
		<summary type="html">&lt;p&gt;BAM_Adventure_Giver_NPC-Preview6.lsl&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= BAM_Adventure_Giver_NPC-Preview6.lsl =&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Baroun's Adventure Machine BAM_Adventure_Giver_NPC-v0.0.7-20120704.lsl&lt;br /&gt;
// Copyright (c) 2012 by Baroun Tardis and Allen Kerensky (OSG/SL) All Rights Reserved.&lt;br /&gt;
// This work is dual-licensed under&lt;br /&gt;
// Creative Commons Attribution (CC BY) 3.0 Unported&lt;br /&gt;
// http://creativecommons.org/licenses/by/3.0/&lt;br /&gt;
// - or -&lt;br /&gt;
// Modified BSD License (3-clause)&lt;br /&gt;
// Redistribution and use in source and binary forms, with or without&lt;br /&gt;
// modification, are permitted provided that the following conditions are met:&lt;br /&gt;
// * Redistributions of source code must retain the above copyright notice, &lt;br /&gt;
//   this list of conditions and the following disclaimer.&lt;br /&gt;
// * Redistributions in binary form must reproduce the above copyright notice,&lt;br /&gt;
//   this list of conditions and the following disclaimer in the documentation&lt;br /&gt;
//   and/or other materials provided with the distribution.&lt;br /&gt;
// * Neither the name of Myriad Lite nor the names of its contributors may be&lt;br /&gt;
//   used to endorse or promote products derived from this software without&lt;br /&gt;
//   specific prior written permission.&lt;br /&gt;
//&lt;br /&gt;
// THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR&lt;br /&gt;
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES&lt;br /&gt;
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN&lt;br /&gt;
// NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,&lt;br /&gt;
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT&lt;br /&gt;
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,&lt;br /&gt;
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY&lt;br /&gt;
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT&lt;br /&gt;
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF&lt;br /&gt;
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
//&lt;br /&gt;
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai&lt;br /&gt;
// Myriad RPG System licensed under:&lt;br /&gt;
// Creative Commons Attribution (CC BY) 2.0 UK: England and Wales&lt;br /&gt;
// http://creativecommons.org/licenses/by/2.0/uk/&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// Adventure-Specific Configuration&lt;br /&gt;
//============================================================================&lt;br /&gt;
// NPC-specific Info&lt;br /&gt;
string  MSG_NPCNAME         = &amp;quot;BAM Adventure Giver NPC&amp;quot;;   // hovertext name for NPC - I hate hovertext&lt;br /&gt;
vector  MSG_SETTEXT_COLOR   = &amp;lt;1.0,1.0,1.0&amp;gt;;   // color to display settext in&lt;br /&gt;
float   MSG_SETTEXT_ALPHA   = 1.0; // alpha for hovertext. 0.0 = clear, 1.0 = solid.&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;
string  ADVTEXT             = &amp;quot;Find some red salt for luck.&amp;quot;; // brief description&lt;br /&gt;
string  ADV_ATTRACT            = &amp;quot;can you help me find some red salt for luck?&amp;quot;; // hook to get player to play&lt;br /&gt;
string  MSG_OWNER_STARTADV  = &amp;quot; has started the Red Salt Adventure&amp;quot;;&lt;br /&gt;
string  ADV_ALL_TASKS       = &amp;quot;101,102&amp;quot;; // CSV list of task numbers that all have to be done for adventure to be complete example: &amp;quot;101, 102, 103&amp;quot;&lt;br /&gt;
string  MSG_ADV_INCOMPLETE  = &amp;quot;, It looks like you still have work to do.&amp;quot;; // prefixed by AVNAME&lt;br /&gt;
string  MSG_OWNER_DONEADV   = &amp;quot; has completed Red Salt Adventure&amp;quot;; // message to speak when task complete&lt;br /&gt;
string  ADVDONETEXT         = &amp;quot;Thanks! I appreciate your help!&amp;quot;;&lt;br /&gt;
string  ADVDONEUUID         = &amp;quot;f78027c9-e8bb-38f2-9b11-1d4e89ac10a4&amp;quot;; //object or sounds to give as a mission complete&lt;br /&gt;
string  PRIZENAME           = &amp;quot;NONE&amp;quot;; // prize to give when adventure is complete&lt;br /&gt;
&lt;br /&gt;
// Task-Specific Info&lt;br /&gt;
// Task numbers are (AdvNum*100)+task, so they don't match up between adventures&lt;br /&gt;
integer ADVTASKTDNUM        = 101; // task number for the task THIS node hands out&lt;br /&gt;
string  ADVTASKTODO         = &amp;quot;Find the Red Salt Mines&amp;quot;; // task description of what to do&lt;br /&gt;
string  ADVTASKTODOHINT     = &amp;quot;Look in the other corners of the platform&amp;quot;; // string&lt;br /&gt;
&lt;br /&gt;
//integer TRIGGERWAIT = 60; // seconds to remember players to prevent re-triggering task?&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;
integer FLAG_USESENSOR; // set to TRUE to use sensor alerts - set in state_entry&lt;br /&gt;
float SENSOR_RANGE = 3.0; // how close do you have to be to trigger the NPC&lt;br /&gt;
float SENSOR_ARC = PI; // what is the sensor's sweep?&lt;br /&gt;
float SENSOR_REPEAT = 10; // how often to repeat the sensor&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// MESSAGE FORMAT REFERENCE&lt;br /&gt;
//============================================================================&lt;br /&gt;
// -1 OUT - [YES,NO,CLOSE]&lt;br /&gt;
// -1 IN  - YES&lt;br /&gt;
// BAMCHAN OUT - InAdv?&lt;br /&gt;
// BAMCHAN IN  - InAdv|str NONE&lt;br /&gt;
// BAMCHAN IN  - InAdv|str AdventureName&lt;br /&gt;
// BAMCHAN OUT - OfferAdv|str AdventureName|str AdventureText&lt;br /&gt;
// BAMCHAN OUT - TaskCP?&lt;br /&gt;
// BAMCHAN IN  - AcceptAdv|str AdvName&lt;br /&gt;
// BAMCHAN OUT - AddTask|int TaskNumber|str TaskToDo&lt;br /&gt;
// BAMCHAN OUT - AddHint|int TaskNumber|str TaskHint&lt;br /&gt;
// BAMCHAN IN  - TaskCP|&lt;br /&gt;
// BAMCHAN IN  - TaskCP|str 999&lt;br /&gt;
// BAMCHAN OUT - DoneAdv|str AdventureName|str AdventureText|key AdventureDoneUUID&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// Global Constants&lt;br /&gt;
//============================================================================&lt;br /&gt;
integer FLAG_DEBUG;&lt;br /&gt;
integer REPLY_FLAG          = FALSE;    // flag to store if we got a reply in time or not for InAdv?&lt;br /&gt;
string  CHAN_PREFIX         = &amp;quot;0x&amp;quot;;     // random chat channel prefix&lt;br /&gt;
string  CHAT_DIVIDER        = &amp;quot;, &amp;quot;;     // to comma-separate elements in emitted chat elements&lt;br /&gt;
string  MSG_STARTUP         = &amp;quot;Baroun's Adventure Machine is activating.&amp;quot;;&lt;br /&gt;
string  DEBUG_LISTEN_CHANNEL= &amp;quot;BAM Listening on channel: &amp;quot;; // debug message to see picked channel&lt;br /&gt;
string  API_INADV_QUERY     = &amp;quot;InAdv?&amp;quot;; // API trigger to check if in an adventure.&lt;br /&gt;
string  API_TASKCP_QUERY    = &amp;quot;TaskCP?&amp;quot;; // task complete?&lt;br /&gt;
string  API_INADV_RESPONSE  = &amp;quot;InAdv&amp;quot;;  // confirms player is already in an adventure&lt;br /&gt;
string  DIV1                = &amp;quot;|&amp;quot;;      // divides fields of API messages&lt;br /&gt;
string  API_NONE            = &amp;quot;NONE&amp;quot;;   // magic text if player not in an adventure&lt;br /&gt;
string  API_OFFER_ADV       = &amp;quot;OfferAdv&amp;quot;; // offer player an adventure&lt;br /&gt;
string  API_ACCEPT_ADV      = &amp;quot;AcceptAdv&amp;quot;; // player accepts adventure&lt;br /&gt;
string  API_ADD_TASK        = &amp;quot;AddTask&amp;quot;; // add a task to player&lt;br /&gt;
string  API_ADD_HINT        = &amp;quot;AddHint&amp;quot;; // add a hint for the current task&lt;br /&gt;
string  API_TASKCP_RESPONSE = &amp;quot;TaskCP&amp;quot;; // task completed&lt;br /&gt;
string  API_DONEADV         = &amp;quot;DoneAdv&amp;quot;; // adventure done&lt;br /&gt;
string  MSG_NEED_HUD        = &amp;quot;, you'll need Baroun's Adventure Machine HUD to join this adventure. Here's one for you to wear.&amp;quot;;&lt;br /&gt;
string  INVENTORY_HUD       = &amp;quot;Baroun's Adventure Machine HUD&amp;quot;; // name of HUD item to give from inventory.&lt;br /&gt;
string  INVENTORY_NOTE      = &amp;quot;BAM Baroun's Adventure Machine Instructions&amp;quot;; // name of notecard to give&lt;br /&gt;
string  MSG_HUDMENU         = &amp;quot;Would you like a copy of Barouns Adventure Machine to join into adventures?&amp;quot;;&lt;br /&gt;
list    MENU                = [&amp;quot;YES&amp;quot;,&amp;quot;NO&amp;quot;,&amp;quot;CLOSE&amp;quot;];&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;
integer CHAN_REGION         = -999; // Myriad Region Server&lt;br /&gt;
integer HAND_OBJECT; // object channel handle for rumors&lt;br /&gt;
integer CHAN_OBJECT; // object channel for rumors&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// Runtime Globals&lt;br /&gt;
//============================================================================&lt;br /&gt;
list    Recent; // list of [UUID,unixtime] who recently collided with this goal&lt;br /&gt;
list    GotPrizes; // list of who got prizes [UUID,unixtime]&lt;br /&gt;
key     AVKEY;      // UUID of the avatar we are interacting with&lt;br /&gt;
string  AVNAME;     // String name of the avatar we are interacting with&lt;br /&gt;
integer CHANBAM;    // Channel we listen on&lt;br /&gt;
integer CHANTARGET; // channel of thing we're talking to&lt;br /&gt;
integer MENUHAND;   // llListenRemove handle for Menu chat channel&lt;br /&gt;
integer CHAN_RUMOR; // what channel is the rumor server listening on?&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// Runtime Globals&lt;br /&gt;
//============================================================================&lt;br /&gt;
DEBUG(string debugmsg) {&lt;br /&gt;
    if ( FLAG_DEBUG == TRUE ) {&lt;br /&gt;
        llInstantMessage(llGetOwnerKey(llGetKey()),&amp;quot;DEBUG: &amp;quot;+debugmsg);&lt;br /&gt;
    }&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;
        name = &amp;quot;&amp;quot;; // LSLINT&lt;br /&gt;
        if ( chan == -1 ) {&lt;br /&gt;
            if ( msg == &amp;quot;YES&amp;quot; ) { // player responded yes to menu asking if they want a HUD&lt;br /&gt;
                llGiveInventory(id,INVENTORY_HUD); // send them the HUD&lt;br /&gt;
                llGiveInventory(id,INVENTORY_NOTE); // send them instructions            &lt;br /&gt;
                return; // exit early in case we decide to add more commands, and we're done with this one&lt;br /&gt;
            }&lt;br /&gt;
            llListenRemove(MENUHAND); // done with stuff on menu channel, remove the listener&lt;br /&gt;
            llSetTimerEvent(0.0); // stop a running timer&lt;br /&gt;
            REPLY_FLAG = FALSE; // reset the reply flag&lt;br /&gt;
            return; // exit early since we're done with menu channel&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if ( msg == API_RUMOR_FOUND ) {&lt;br /&gt;
            CHAN_RUMOR = (integer)(&amp;quot;0x&amp;quot; + llGetSubString((string)id,0,6));&lt;br /&gt;
            llOwnerSay(&amp;quot;Rumor server found on channel &amp;quot;+(string)CHAN_RUMOR);&lt;br /&gt;
            if ( CHAN_OBJECT != 0 ) llListenRemove(CHAN_OBJECT); // remove the unneeded object channel listener&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        list   tokens  = llParseString2List(msg, [DIV1], []); // split incoming message apart using |&lt;br /&gt;
        string command = llList2String(tokens, 0); // the first part of the message is a command&lt;br /&gt;
        string data    = llList2String(tokens, 1); // the second part is command-specific data&lt;br /&gt;
&lt;br /&gt;
        // if they answer they are in an adventure, react accordingly&lt;br /&gt;
        if ( command == API_INADV_RESPONSE ) { // In An Adventure Response&lt;br /&gt;
            REPLY_FLAG = TRUE; // we got a response from a HUD, remember it&lt;br /&gt;
            if ( data == API_NONE ) { // responded with no current adventure&lt;br /&gt;
                llSay(PUBLIC_CHANNEL,AVNAME+CHAT_DIVIDER+ADV_ATTRACT);&lt;br /&gt;
                llSay(CHANTARGET,API_OFFER_ADV+DIV1+ADVNAME+DIV1+ADVTEXT); // offer one&lt;br /&gt;
                return;        &lt;br /&gt;
            }&lt;br /&gt;
            if ( data == ADVNAME ) { // already in the current adventure&lt;br /&gt;
                llSay(CHANTARGET,API_TASKCP_QUERY); // so let's check if they have completed adventure?&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // If they are accepting the adventure, hand them first task&lt;br /&gt;
        if ( command == API_ACCEPT_ADV ) { // accepting an adventure&lt;br /&gt;
            if ( data == ADVNAME ) { // accepting this nodes adventure&lt;br /&gt;
                llSay(PUBLIC_CHANNEL,ADVTEXT);&lt;br /&gt;
                llSay(CHANTARGET,API_ADD_TASK+DIV1+(string)ADVTASKTDNUM+DIV1+ADVTASKTODO); // give them first task&lt;br /&gt;
                llSay(CHANTARGET,API_ADD_HINT+DIV1+(string)ADVTASKTDNUM+DIV1+ADVTASKTODOHINT); // give them first task hint&lt;br /&gt;
                DEBUG(llKey2Name(llGetOwnerKey(id))+MSG_OWNER_STARTADV); // tell owner adventure begins&lt;br /&gt;
                if ( CHAN_RUMOR != 0 ) {&lt;br /&gt;
                    string who = llKey2Name(llGetOwnerKey(id));&lt;br /&gt;
                    llRegionSay(CHAN_RUMOR,API_RUMOR_PUT+DIV1+who+DIV1+who+MSG_OWNER_STARTADV);&lt;br /&gt;
                }&lt;br /&gt;
                return; // done with this chat command, exit early&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ( command == API_TASKCP_RESPONSE ) { // player sends TaskCP|task# to NPC    &lt;br /&gt;
            string playertasks = llList2CSV(llListSort(llCSV2List(data),1,TRUE));&lt;br /&gt;
            string alltasks = llList2CSV(llListSort(llCSV2List(ADV_ALL_TASKS),1,TRUE));&lt;br /&gt;
            if ( playertasks == alltasks ) { // if all tasks are in done list, then adventure is done&lt;br /&gt;
                // tell player HUD that the adventure is done&lt;br /&gt;
                llSay(CHANTARGET,API_DONEADV+DIV1+ADVNAME+DIV1+ADVDONETEXT+DIV1+ADVDONEUUID);&lt;br /&gt;
                // tell player and public that adventure is done&lt;br /&gt;
                llSay(PUBLIC_CHANNEL,llKey2Name(llGetOwnerKey(id))+CHAT_DIVIDER+ADVDONETEXT);&lt;br /&gt;
                // give player the prize if one is defined&lt;br /&gt;
                if (PRIZENAME!=&amp;quot;NONE&amp;quot;  &amp;amp;&amp;amp; llListFindList(GotPrizes,[llGetOwnerKey(id)]) == -1 ) {&lt;br /&gt;
                    llGiveInventory(llGetOwnerKey(id),PRIZENAME);&lt;br /&gt;
                    GotPrizes = [ llGetOwnerKey(id), (llGetUnixTime() + PRIZEWAIT) ] + GotPrizes; // remember who and when&lt;br /&gt;
                }&lt;br /&gt;
                // send message to quest OWNER that a player finished and got the prize&lt;br /&gt;
                DEBUG(llKey2Name(llGetOwnerKey(id))+MSG_OWNER_DONEADV);&lt;br /&gt;
                if ( CHAN_RUMOR != 0 ) {&lt;br /&gt;
                    string who = llKey2Name(llGetOwnerKey(id));&lt;br /&gt;
                    llRegionSay(CHAN_RUMOR,API_RUMOR_PUT+DIV1+who+DIV1+who+MSG_OWNER_DONEADV);&lt;br /&gt;
                }&lt;br /&gt;
                return; // exit early&lt;br /&gt;
            }&lt;br /&gt;
            // player has not completed last quest task, so tell them there is more to do&lt;br /&gt;
            llSay(PUBLIC_CHANNEL,llKey2Name(llList2String(llGetObjectDetails(id,[OBJECT_OWNER]),0))+MSG_ADV_INCOMPLETE);&lt;br /&gt;
            return; // exit early in case we add more chat commands&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    // SENSOR&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    sensor(integer num_sensed) {&lt;br /&gt;
        while (num_sensed--) { // count down through all touches in this event&lt;br /&gt;
            AVKEY=llDetectedKey(num_sensed); // get the UUID of the toucher&lt;br /&gt;
            if ( llListFindList(Recent,[AVKEY]) == -1 ) { // player not in list of people recently completing the quest&lt;br /&gt;
                AVNAME=llDetectedName(num_sensed); // get the name of the toucher&lt;br /&gt;
                CHANTARGET = (integer)(CHAN_PREFIX + llGetSubString((string)AVKEY,-7,-1));&lt;br /&gt;
                llSay(CHANTARGET, 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;
    // STATE_ENTRY EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        FLAG_DEBUG = FALSE; // do we want debug messages&lt;br /&gt;
        FLAG_USESENSOR = FALSE; // use the sensor or not?&lt;br /&gt;
        llParticleSystem([]); // shut off any running particles&lt;br /&gt;
        llSetText(MSG_NPCNAME,MSG_SETTEXT_COLOR,MSG_SETTEXT_ALPHA);&lt;br /&gt;
        DEBUG(MSG_STARTUP); // tell the owner we are initializing&lt;br /&gt;
        CHANBAM = (integer)(CHAN_PREFIX + llGetSubString((string)llGetKey(),-7,-1)); // calculate channel to listen on&lt;br /&gt;
        DEBUG(DEBUG_LISTEN_CHANNEL+(string)CHANBAM);&lt;br /&gt;
        llListen(CHANBAM,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;); // listen on channel for all messages from any name, name UUID, and any message&lt;br /&gt;
        if ( CHAN_OBJECT != 0 ) llListenRemove(CHAN_OBJECT); // remove the unneeded object channel listener&lt;br /&gt;
        CHAN_OBJECT = (integer)(CHAN_PREFIX + llGetSubString((string)llGetKey(),0,6)); // calculate channel to listen on&lt;br /&gt;
        HAND_OBJECT = llListen(CHAN_OBJECT,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;); // listen for rumor server&lt;br /&gt;
        llSetTimerEvent(EVENTTIMER); // fire off a timer event once an hour&lt;br /&gt;
        llRegionSay(CHAN_REGION,API_RUMOR_FIND); // send a region message to see if there is a rumor server&lt;br /&gt;
        if ( FLAG_USESENSOR == TRUE ) {&lt;br /&gt;
            llSensorRepeat(&amp;quot;&amp;quot;,NULL_KEY,AGENT,SENSOR_RANGE,SENSOR_ARC,SENSOR_REPEAT); // start NPC looking for someone to help&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    // TIMER EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    timer() {&lt;br /&gt;
        if ( REPLY_FLAG == FALSE &amp;amp;&amp;amp; FLAG_USESENSOR == TRUE) {&lt;br /&gt;
            // no response to test if player already wearing HUD, so ask them if they want one&lt;br /&gt;
            MENUHAND = llListen(-1,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;); // set up a listen channel for the menu to reply on&lt;br /&gt;
            // Send them the menu&lt;br /&gt;
            llDialog(AVKEY,MSG_HUDMENU,MENU,-1);&lt;br /&gt;
            llSay(PUBLIC_CHANNEL,AVNAME+MSG_NEED_HUD); // tell player they need a HUD to play&lt;br /&gt;
            REPLY_FLAG = TRUE; // set a reply flag so we don't keep sending more HUDs&lt;br /&gt;
        }&lt;br /&gt;
        llSetTimerEvent(0.0); // remove the 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_START 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;
            &lt;br /&gt;
                //if ( llListFindList(Recent,[AVKEY]) == -1 ) { // is player in recent list?&lt;br /&gt;
                //    Recent = [AVKEY,llGetUnixTime()+TRIGGERWAIT] + Recent; // no, add player to list&lt;br /&gt;
                //    // calculate player-specific BAM dynamic channel&lt;br /&gt;
                    CHANTARGET = (integer)(CHAN_PREFIX + llGetSubString((string)AVKEY,-7,-1));&lt;br /&gt;
                    llSay(CHANTARGET, 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;
        REPLY_FLAG = FALSE; // set a flag to track if we get a reply or not...&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>