Myriad_Lite_Module_BAM-v0.0.5-20120826.lsl
// Myriad_Lite_Module_BAM-v0.0.5-20120826.lsl
// Copyright (c) 2012 by Baroun Tardis (OSG/SL) and Allen Kerensky (OSG/SL) All Rights Reserved.
// This work is dual-licensed under
// Creative Commons Attribution (CC BY) 3.0 Unported
// http://creativecommons.org/licenses/by/3.0/
// - or -
// Modified BSD License (3-clause)
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of Myriad Lite nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
// NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad RPG System licensed under:
// Creative Commons Attribution (CC BY) 2.0 UK: England and Wales
// http://creativecommons.org/licenses/by/2.0/uk/
// CONSTANTS - DO NOT CHANGE DURING RUN
string VERSION = "0.0.5"; // script version
string VERDATE = "20120826"; // script date
string CHAN_PREFIX = "0x"; // channel prefix for calculating dynamic channels
string DIV = "|"; // message field divider
// Module to Module Messaging Constants
//integer MODULE_HUD = -1;
//integer MODULE_CHARSHEET = -2;
//integer MODULE_ARMOR = -3;
integer MODULE_BAM = -4;
//integer MODULE_RUMORS = -5;
// integer MODULE_CLOSE = -6;
// integer MODULE_RANGED = -7;
// integer MODULE_RESILIENCE = -8;
// integer MODULE_PROGRESS = -9;
// integer MODULE_WELL = -10;
// integer MODULE_METER = -11;
integer LM_SENDTOATTACHMENT = 0x80000000;
string API_OFFERADV = "OfferAdv"; // Offer an adventure to HUD wearer
string API_ACCEPTADV = "AcceptAdv"; // Offer accepted player is on an adventure
string API_INADV_QUERY = "InAdv?"; // Ask a player HUD if the player is in an adventure - InAdv?
string API_INADV_RESPONSE = "InAdv"; // In Adventure Response Yes: InAdv | String AdventureName No: InAdv | NONE
string API_TASKIP_QUERY = "TaskIP?";
string API_TASKIP_RESPONSE = "TaskIP"; // Task In Progress Reply current task in progress: TaskIP | AdventureGoal
string API_TASKCP_QUERY = "TaskCP?"; // Task Complete Query
string API_TASKCP_RESPONSE = "TaskCP"; // Task Complete Reply
string API_DONETASK = "DoneTask"; // Task Done - player achieved current goal NPC sends: DoneTask | GoalText | TaskDone Text | PlayerUUID
string API_DONEADV = "DoneAdv"; // Done Adventure reply
string API_NONE = "NONE"; // a fixed string when not in adventure - uses variable to stay consistent everywhere
string API_ADDTASK = "AddTask"; // Add a task to the Player HUD - AddTask | TaskNumber | String Describing Task
string API_ADDHINT = "AddHint"; // Add a hint for a task to the Player HUD - AddHint | TaskNumber | String Hint
string MSG_NO_ADVENTURE = "Looking for adventure...";
string MSG_CURRENT_ADVENTURE = "Adventure: ";
string MSG_CURRENT_GOAL = "Overall Goal: ";
string MSG_CURRENT_TASK = "Current Task: ";
string MSG_CURRENT_HINT = "Current Hint: ";
// RUNTIME GLOBALS - CAN CHANGE DURING RUN
integer CHANOBJBAM; // channel of thing we're talking to
string STATUSMSG; // scratch space to build status messages
integer STATUS_FLAG; // show status as HUD hover text
// Adventure-Specific Configuration
// Task numbers are (AdvNum*100)+task, so they don't overlap between adventures
string ADVNAME="NONE"; // Adventure Name
string ADVTEXT; // brief description
// Current Task-specific info
string ADVTASKTODO; // task name of the next task handed out
integer ADVTASKTDNUM; // task number of the next task handed out
string ADVTASKTODOHINT; // Hint text for the next task handed out
// Previous Task-specific info
list ADVTCOMP; // completed task numbers (list of numbers)
integer FLAG_DEBUG; // show debugging?
//============================================================================
// DEBUG - show errors on debug channel with wearer name for sorting
//============================================================================
DEBUG(string debugmsg) {
if ( FLAG_DEBUG == TRUE ) llSay(DEBUG_CHANNEL,"("+llKey2Name(llGetOwner())+") MOD BAM: "+debugmsg);
}
//============================================================================
// GETVERSION
//============================================================================
GETVERSION() {
SENDTOHUD("VERSION="+VERSION+DIV+"VERSIONDATE="+VERDATE+DIV+llGetObjectName());
}
// RESET - shut down running animations then reset the script to reload character sheet
RESET() {
llResetScript(); // now reset
}
//============================================================================
// SENDTOHUD - send reponses to HUD as Link Messages
//============================================================================
SENDTOHUD(string str) {
DEBUG("SENDTOHUD("+str+")");
llMessageLinked(LINK_THIS,LM_SENDTOATTACHMENT,str,llGetOwner());
}
//============================================================================
// SETUP - begin bringing the HUD online
//============================================================================
SETUP() {
FLAG_DEBUG=FALSE;
llSetText("",<0,0,0>,0); // clear any previous hovertext
if ( llGetAttached() >= 31 && llGetAttached() <= 38 ) { // are we attached to a HUD slot?
STATUS_FLAG = TRUE; // turn on HUD hovertext
} else {
STATUS_FLAG = FALSE; // turn off body attached hovertext
}
STATUS();
}
//============================================================================
// STATUS() - update adventure data on HUD
//============================================================================
STATUS() {
if ( ADVNAME == API_NONE ) { // is player in an adventure?
STATUSMSG = MSG_NO_ADVENTURE; // nope
} else { // yep, build the status
STATUSMSG = MSG_CURRENT_ADVENTURE + ADVNAME + "\n" +
MSG_CURRENT_GOAL + ADVTEXT + "\n" +
MSG_CURRENT_TASK + ADVTASKTODO + "\n" +
MSG_CURRENT_HINT + ADVTASKTODOHINT;
}
if ( STATUS_FLAG == FALSE ) { // if attached to body, use chat output
llOwnerSay(STATUSMSG);
} else { // attached to HUD slot, use hovertext
llSetText(STATUSMSG,<1,1,1>,1.0);
}
}
//============================================================================
// DEFAULT STATE - load character sheet
//============================================================================
default {
//------------------------------------------------------------------------
// LINK MESSAGE - commands to and from other prims in HUD
//------------------------------------------------------------------------
link_message(integer sender,integer sending_module,string message, key speakerid) {
if ( sending_module == MODULE_BAM || sending_module == LM_SENDTOATTACHMENT ) return; // ignore our own messages
DEBUG("EVENT link_message("+(string)sender+","+(string)sending_module+","+message+","+(string)speakerid+")");
// break down the commands and messages into units we can work with
list fields = llParseString2List(message,[DIV],[]); // break into list of fields based on DIVider
string command = llList2String(fields,0); // assume the first field is a Myriad Lite command
if ( command == "DEBUGOFF" ) { FLAG_DEBUG = FALSE; return; } // stop debugging
if ( command == "DEBUGON" ) { FLAG_DEBUG = TRUE; return; } // start debugging
if ( command == "RESET" ) { RESET(); return;} // reset on command
if ( message == "VERSION" ) { GETVERSION(); return; } // dump the version and date on request
if ( message == "BAMSTATUS" ) { STATUS(); return;} // show status when specifically requested
// calculate BAM dynamic channel of item/player talking to us
CHANOBJBAM = (integer)(CHAN_PREFIX + llGetSubString((string)speakerid,-7,-1));
// process the rest of the fields for multi-field commands
string data1 = llList2String(fields,1);
string data2 = llList2String(fields,2);
string data3 = llList2String(fields,3);
// We're asked what adventure we're in
if ( command == API_INADV_QUERY ) {
llSay(CHANOBJBAM,API_INADV_RESPONSE + DIV + ADVNAME); // reply with In Adventure and Adventure Name
STATUS();
return; // command done, return early
}
// We're asked our current task in progress
if ( command == API_TASKIP_QUERY ) { // what task in progress?
// respond with task in progress
llSay(CHANOBJBAM, API_TASKIP_RESPONSE + DIV + (string)ADVTASKTDNUM); // Reply with current task in progress and number
STATUS();
return; // command done, return early
}
// Get list of completed tasks
if ( command == API_TASKCP_QUERY ) { // what tasks complete?
llSay(CHANOBJBAM, API_TASKCP_RESPONSE + DIV + llList2CSV(ADVTCOMP)); // reply with current task complete list as CSV
STATUS();
return; // command done, return early
}
// player is offered an adventure
if ( command == API_OFFERADV ) { // want adventure?
// FIXME need to add dialog box to accept/decline later
ADVNAME=data1; // name of the adventure
ADVTEXT=data2; // description of the adventure
ADVTCOMP=[]; // clear the completed task list and start new one
ADVTASKTODO=""; // clear the next task name
ADVTASKTDNUM=0; // clear the next task number
llSay(CHANOBJBAM, API_ACCEPTADV + DIV +data1); // accept the adventure
STATUS();
return; // command done, return early
}
// add the next task to complete
if ( command == API_ADDTASK ) { // add a task
ADVTASKTDNUM=(integer)data1; // next task number
ADVTASKTODO=data2; // next task name
llOwnerSay(ADVTASKTODO); // tell player the next task name
STATUS();
return; // command done, return early
}
// add a hint for the next task to complete
if( ( command == API_ADDHINT ) && ( (integer)data1 == ADVTASKTDNUM) ) {
ADVTASKTODOHINT=data2; // next task hint
llOwnerSay(ADVTASKTODOHINT); // tell that player the next task hint
STATUS();
return; // command done, return early
}
// is player done with this task of the adventure?
if ( ( command == API_DONETASK ) && ( (integer)data1 == ADVTASKTDNUM) ) {
ADVTCOMP = [(integer)data1] + ADVTCOMP; // add this task number to completed list
ADVTASKTDNUM=0; // clear out the task number we're working on since its done now
ADVTASKTODO=""; // clear out the task name
ADVTASKTODOHINT=""; // clear out the task hint
llOwnerSay(data2); // tell player task is complete
if ( data3 != "" ) llPlaySound(data3,0.5); // play sound if one was defined
STATUS();
return; // command done, return early
}
// is player done with the entire adventure?
if ( ( command == API_DONEADV ) && ( data1 == ADVNAME ) ) {
ADVTCOMP = []; // clear out adventure tasks - we're done
ADVTASKTDNUM=0; // clear out next task number
ADVTASKTODO=""; // clear out name of next task
ADVTASKTODOHINT=""; // clear out next task hint
ADVNAME=API_NONE; // set current adventure name to none
ADVTEXT="Looking for adventure..."; // set the current adventure name to
llOwnerSay(data2); // tell player adventure is complete
if ( data3 != "" ) llPlaySound(data3,0.5); // play sound if one was defined
STATUS();
return; // command done, return early
}
} // end link message
//------------------------------------------------------------------------
// STATE ENTRY - called on Reset
//------------------------------------------------------------------------
state_entry() {
SETUP(); // show credits and start character sheet load
}
//------------------------------------------------------------------------
// TOUCH_START - touch HUD for adventure update
//------------------------------------------------------------------------
touch_start(integer total_number) {
total_number = 0; // LSLINT
STATUS();
}
} // end state running
// END