<?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_Collision_Goal-v0.0.8-20120704.lsl</id>
		<title>User:Allen Kerensky/Myriad Lite Dev/BAM Collision Goal-v0.0.8-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_Collision_Goal-v0.0.8-20120704.lsl"/>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:Allen_Kerensky/Myriad_Lite_Dev/BAM_Collision_Goal-v0.0.8-20120704.lsl&amp;action=history"/>
		<updated>2026-06-13T22:45:24Z</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_Collision_Goal-v0.0.8-20120704.lsl&amp;diff=30045&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_Collision_Goal-v0.0.8-20120704.lsl&amp;diff=30045&amp;oldid=prev"/>
				<updated>2012-07-05T02:50:36Z</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_Collision_Goal-v0.0.8-20120704.lsl =&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Baroun's Adventure Machine BAM_Collision_Goal-v0.0.8-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 tasks don't overlap between adventures&lt;br /&gt;
//============================================================================&lt;br /&gt;
&lt;br /&gt;
// Object or NPC-specific info&lt;br /&gt;
string MSG_SETTEXT = &amp;quot;Processed Red Salt Cask&amp;quot;;&lt;br /&gt;
vector MSG_SETTEXT_COLOR = &amp;lt;1,0,0&amp;gt;;&lt;br /&gt;
float  MSG_SETTEXT_ALPHA = 1.0;&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; // which task number is this a goal for?&lt;br /&gt;
string  TASKDONETEXT=&amp;quot;You've found the red salt!&amp;quot;; // Mission complete message&lt;br /&gt;
string  RUMOR_TASK_DONE=&amp;quot; found some red salt.&amp;quot;; // sent as rumor suffix&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 this task is 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  ADTASKTODO=&amp;quot;Return the salt to the baker.&amp;quot;; // the next task message&lt;br /&gt;
string  ADTASKTODOHINT=&amp;quot;He's where you first met him.&amp;quot;; // hint for the task goal&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;
// 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 AND API 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;; // channel prefix for calculating dynamic channel numbers&lt;br /&gt;
string API_DIVIDER          = &amp;quot;|&amp;quot;; // The field divider within BAM messages&lt;br /&gt;
string API_INADV_QUERY      = &amp;quot;InAdv?&amp;quot;; // ask player HUD if player is in an adventure?&lt;br /&gt;
string API_INADV_RESPONSE   = &amp;quot;InAdv&amp;quot;; // player responds with adventure name they are in&lt;br /&gt;
string API_NONE             = &amp;quot;NONE&amp;quot;; // constant for player not in adventure&lt;br /&gt;
string API_TASKIP_QUERY     = &amp;quot;TaskIP?&amp;quot;; // what is the player's current task goal?&lt;br /&gt;
string API_TASKIP_RESPONSE  = &amp;quot;TaskIP&amp;quot;; // player response with current Task In Progress&lt;br /&gt;
string API_DONETASK         = &amp;quot;DoneTask&amp;quot;; // tell player they have achieved current goal&lt;br /&gt;
string API_ADDTASK          = &amp;quot;AddTask&amp;quot;; // add next task to player HUD&lt;br /&gt;
string API_ADDHINT          = &amp;quot;AddHint&amp;quot;; // add next task hint to the player HUD&lt;br /&gt;
&lt;br /&gt;
//============================================================================&lt;br /&gt;
// GLOBAL RUNTIME VARIABLES&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 avatar we're interacting with&lt;br /&gt;
string  AVNAME; // name of avatar we're interacting with.&lt;br /&gt;
integer BAM;    // Channel we listen on&lt;br /&gt;
integer TARGET; // channel of person or thing we're talking to&lt;br /&gt;
integer HANDLE; // integer handle of open listen requests&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;
    // COLLISION_START EVENT&lt;br /&gt;
    //------------------------------------------------------------------------&lt;br /&gt;
    collision_start(integer times_touched) {&lt;br /&gt;
        while (times_touched--) {&lt;br /&gt;
            AVKEY=llDetectedKey(times_touched); // UUID of who collided&lt;br /&gt;
            AVNAME=llDetectedName(times_touched); // name of who collided&lt;br /&gt;
            if ( llListFindList(RECENT,[AVKEY]) == -1 ) { // check recent list to see if collider is in it&lt;br /&gt;
                RECENT = [AVKEY,(llGetUnixTime()+TRIGGERWAIT)] + RECENT; // nope, so add new key to recent list&lt;br /&gt;
                // calculate BAMCHAN for avatar that hit collision goal&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 a BAM adventure already&lt;br /&gt;
            }&lt;br /&gt;
        }&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;
        chan = 0; // LSLINT&lt;br /&gt;
        name = &amp;quot;&amp;quot;; // LSLINT&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;
                // 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;
                // 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 + ADTASKTODO);&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 + ADTASKTODOHINT);&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;+ADTASKTODO+&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;
        llSetText(MSG_SETTEXT,MSG_SETTEXT_COLOR,MSG_SETTEXT_ALPHA);&lt;br /&gt;
        // calculate the BAM dynamic channel&lt;br /&gt;
        // FIXME - move listen open down into collision?&lt;br /&gt;
        if ( HANDLE != 0 ) llListenRemove(HANDLE);&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;); // open a listener with 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); // fire off a timer event once an hour&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;
// END&lt;br /&gt;
//============================================================================&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Allen Kerensky</name></author>	</entry>

	</feed>