<?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_Preview_5%2FBAM_Adventure_Giver_NPC</id>
		<title>User:Allen Kerensky/Myriad Lite Preview 5/BAM Adventure Giver NPC - 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_Preview_5%2FBAM_Adventure_Giver_NPC"/>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite_Preview_5/BAM_Adventure_Giver_NPC&amp;action=history"/>
		<updated>2026-04-17T05:53:44Z</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_Preview_5/BAM_Adventure_Giver_NPC&amp;diff=27339&amp;oldid=prev</id>
		<title>Allen Kerensky: moved User:Allen Kerensky:Myriad Lite Preview 5:BAM Adventure Giver NPC to User:Allen Kerensky/Myriad Lite Preview 5/BAM Adventure Giver NPC: move into subsite</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite_Preview_5/BAM_Adventure_Giver_NPC&amp;diff=27339&amp;oldid=prev"/>
				<updated>2012-02-06T22:40:43Z</updated>
		
		<summary type="html">&lt;p&gt;moved &lt;a href=&quot;/wiki/User:Allen_Kerensky:Myriad_Lite_Preview_5:BAM_Adventure_Giver_NPC&quot; class=&quot;mw-redirect&quot; title=&quot;User:Allen Kerensky:Myriad Lite Preview 5:BAM Adventure Giver NPC&quot;&gt;User:Allen Kerensky:Myriad Lite Preview 5:BAM Adventure Giver NPC&lt;/a&gt; to &lt;a href=&quot;/wiki/User:Allen_Kerensky/Myriad_Lite_Preview_5/BAM_Adventure_Giver_NPC&quot; title=&quot;User:Allen Kerensky/Myriad Lite Preview 5/BAM Adventure Giver NPC&quot;&gt;User:Allen Kerensky/Myriad Lite Preview 5/BAM Adventure Giver NPC&lt;/a&gt;: move into subsite&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='1' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
			&lt;td colspan='1' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:40, 6 February 2012&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_Preview_5/BAM_Adventure_Giver_NPC&amp;diff=27202&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_Preview_5/BAM_Adventure_Giver_NPC&amp;diff=27202&amp;oldid=prev"/>
				<updated>2012-02-06T17:27:31Z</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;= Myriad Lite BAM Adventure Giver NPC =&lt;br /&gt;
&lt;br /&gt;
All quests start and end with an NPC. The first quest NPC would be fictional task 100, and each step of the quest would be 101, 102, etc, and when done, the player returns to the quest NPC to claim the prize.&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
There are a number steps and configurable items for a BAM Adventure Giver NPC:&lt;br /&gt;
# Create your quest NPC item.&lt;br /&gt;
# Drop in the BAM Adventure Giver NPC script.&lt;br /&gt;
# Edit the &amp;quot;Adventure Specific Configuration&amp;quot; section at the top of the script. The variables are explained next.&lt;br /&gt;
## Set MSG_NPCNAME to the NPC's game name&lt;br /&gt;
## Choose a hovertext color for the NPC - http://wiki.secondlife.com/wiki/Category:LSL_Color&lt;br /&gt;
## Choose an alpha/transparency - 0.0 is totally clear, 1.0 is totally visible.&lt;br /&gt;
## ADVNAME: Adventure Name - set a short name for this adventure. Example: &amp;quot;Red Salt Quest&amp;quot;&lt;br /&gt;
## ADVTEXT: Adventure Description - set a short one-line description for this adventure. Example: &amp;quot;Find the rest salt for the baker&amp;quot;&lt;br /&gt;
## ADV_ATTRACT: Attract Message - Set a message for the NPC to attract player help. Example: &amp;quot; can you help me find some red salt?&amp;quot;&lt;br /&gt;
## MSG_OWNER_STARTADV: Message to owner that player started adventure. Example: &amp;quot; has started Red Salt Quest&amp;quot;&lt;br /&gt;
## ADV_ALL_TASKS: list of all task numbers that MUST be completed to get the prize. Example: &amp;quot;101, 102&amp;quot; NOTE: This list is a comma-separated values list, so there should be a SPACE after each comma. If the adventure does not finish when the player has performed all tasks, check this first!&lt;br /&gt;
## MSG_ADV_INCOMPLETE: what NPC should say if player comes back with not all tasks complete. Example: &amp;quot; Not done yet?&amp;quot;&lt;br /&gt;
## MSG_OWNER_DONEADV: message to quest owner when player finishes a quest. Example: &amp;quot;has completed Red Salt Quest&amp;quot;&lt;br /&gt;
## ADVDONETEXT: message from NPC to player that the quest is done. Example: &amp;quot;Thanks for finding red salt for me!&amp;quot;&lt;br /&gt;
## ADVDONEUUID: uuid key of a sound to play when player is successful on the quest, like a fanfare.  Example: a &amp;quot;TA-DA&amp;quot; horn sound Can be the name of a sound effect file in the NPC object inventory too.&lt;br /&gt;
## PRIZENAME: name of a prize object in NPC object inventory to give to the player when they finish the quest. Example: Sweet roll or NONE. Put the Prize object in the NPC's object inventory. The key value NONE means do not give a prize at the end of the quest.&lt;br /&gt;
## ADVTASKTDNUM: the task to-do number of the NEXT TASK. Example: 101&lt;br /&gt;
## ADTASKTODO: a text description of the NEXT TASK the player should do.  Example: &amp;quot;Find the Red Salt Mine.&amp;quot;&lt;br /&gt;
## ADVTASKTODOHINT: a hint for the player on how to complete the NEXT TASK they are being given. Example: &amp;quot;You think the Red Salt Mine is northeast.&amp;quot;&lt;br /&gt;
## TRIGGERWAIT: how long in seconds before a player can re-trigger this NPC or goal. Example: 60&lt;br /&gt;
## PRIZEWAIT: how long in seconds between when player can re-do quest and get the prize again. Example: 3600 (= 1 hour, or 86400 = 1 day)&lt;br /&gt;
## EVENTTIMER: how long between timer events, the smaller the number, the more lag. Example: 15.0 The timer processes the trigger and prize given lists to expire old entries - too long a wait between timers means longer before players can retry the quests.&lt;br /&gt;
# Save the script and let the NPC restart.&lt;br /&gt;
# Move on to creating the quest goals for this NPC's quest.&lt;br /&gt;
&lt;br /&gt;
== BAM_Adventure_Giver_NPC-v0.0.6-20120130.lsl ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
// Baroun's Adventure Machine BAM_Adventure_Giver_NPC-v0.0.6-20120130.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;
//============================================================================&lt;br /&gt;
// NPC-specific Info&lt;br /&gt;
string  MSG_NPCNAME         = &amp;quot;Testy Testerson&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;Testing&amp;quot;; // Adventure Name&lt;br /&gt;
string  ADVTEXT             = &amp;quot;The Quest To Test This Questy Test&amp;quot;; // brief description&lt;br /&gt;
string  ADV_ATTRACT            = &amp;quot;can you help me test a quest?&amp;quot;; // hook to get player to play&lt;br /&gt;
string  MSG_OWNER_STARTADV  = &amp;quot; has started Testing Adventure&amp;quot;;&lt;br /&gt;
string  ADV_ALL_TASKS       = &amp;quot;999&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 Testing 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        = 999; // task number for the task THIS node hands out&lt;br /&gt;
string  ADVTASKTODO         = &amp;quot;Test reaching a goal&amp;quot;; // task description of what to do&lt;br /&gt;
string  ADVTASKTODOHINT     = &amp;quot;Test using a hint&amp;quot;; // string&lt;br /&gt;
&lt;br /&gt;
integer TRIGGERWAIT = 60; // seconds to remember players to prevent re-triggering task?&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;
// -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 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;
&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;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// DEFAULT STATE&lt;br /&gt;
//============================================================================&lt;br /&gt;
default {&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    // STATE_ENTRY EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        llParticleSystem([]); // shut off any running particles&lt;br /&gt;
        llSetText(MSG_NPCNAME,MSG_SETTEXT_COLOR,MSG_SETTEXT_ALPHA);&lt;br /&gt;
        llOwnerSay(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;
        llOwnerSay(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;
        llSetTimerEvent(EVENTTIMER); // fire off a timer event once an hour&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;
            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;
        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;
    // TIMER EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    timer() {&lt;br /&gt;
        if ( REPLY_FLAG == FALSE) {&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,&amp;quot;Would you like a copy of Barouns Adventure Machine to join into adventures?&amp;quot;,[&amp;quot;YES&amp;quot;,&amp;quot;NO&amp;quot;,&amp;quot;CLOSE&amp;quot;],-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;
            llInstantMessage(llGetOwnerKey(llGetKey()),&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;
    // 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;
        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;
                llInstantMessage(llGetOwner(),llKey2Name(llGetOwnerKey(id))+MSG_OWNER_STARTADV); // tell owner adventure begins&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;
                llInstantMessage(llGetOwner(),llKey2Name(llGetOwnerKey(id))+MSG_OWNER_DONEADV);&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;
// END&lt;br /&gt;
//============================================================================&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Allen Kerensky</name></author>	</entry>

	</feed>