User:BUTTONpUSHER Jones/pet protocol/.pet
Jump to navigation
Jump to search
integer DEBUG = FALSE; // if TRUE, chat results to the owner. integer DEBUG2 = TRUE; // for debugging the current piece of code I'm working on. string gBehavior_0; // this pet's behavior string gBehavior_1; // one other pet's behavior list glBehaviors_MRU = [0,0,0 ,0,0,0 ,0,0,0 ,0,0,0 ,0,0,0 ,0,0,0 ,0,0,0 ,0,0,0 ,0,0,0 ,0,0,0]; // last 10 pet keys and their fight/flee parameters "ID, fight, flee" // string gCurrentAction; delete? list gActions; // Action probabilities list gObey; // obey values for threat, neutral, prey, owner, other avatar list glCurrentMessage; // the most recently received message float gTime = 0; //sum of all action probabilities integer gL1; // listen handler for owner integer gL2; // listen handler for pet introduction channel integer gL3; // listen handler for group channel integer gL4; // listen handler for pet's private channel integer gIntroduction_channel = 9000; integer gGroup_channel = 1; //this value should be defined in the read_behavior function; integer gPet_channel; key gOwner; // get_pet_channel grabs the numbers in the last 9 digits of this pet's key. We will use this integer as this pet's private chat channel. integer get_pet_channel(key ID_key) { integer temp_ID = (integer)llDumpList2String(llParseString2List(llGetSubString(ID_key, 28, 37), ["-","a","b","c","d","e","f"], []), ""); return temp_ID; } initialize() { gOwner = llGetOwner(); llListenRemove(gL1); llListenRemove(gL2); llListenRemove(gL3); //integer llListen(integer channel, string name, key id, string msg); gL1 = llListen (0, "", gOwner,""); gL2 = llListen (gIntroduction_channel, "", "", ""); gL3 = llListen (gGroup_channel, "", "", ""); gPet_channel = get_pet_channel(llGetKey()); // llWhisper(0, (string)gPet_key + " "+ (string)llGetKey()); gL4 = llListen (gPet_channel, "", "", ""); gTime = 0; llSetTimerEvent(10); //move this to a better place. This is how often we send our Behavior to the introduction channel. read_behavior(); } //string get_param_value (string) //{ read_behavior() { // read behavior from notecard, email, or XML-RPC read_notecard(); // hard-coded these values for now gBehavior_0 = "fight|0.3 + flee|0.4 + type|dog + subtype|beagle + action|watching + target|master + group|6500"; if(DEBUG)llOwnerSay(":.pet: " + (string)gBehavior_0); gActions = [ 40,"sleep", 1,"speak", 20,"follow + target|owner", 10,"evade + target|owner + offsetR| <-0,0,0> + distance|4.5", 30,"command + action|eat + target|owner", 10,"command + action|stay", 50,"command + action|follow + target|mykey + offsetR|<-5,0,0>" ]; // the following sums the probabilities of the possible actions integer i; integer max = llGetListLength(gActions); for (i=0;i<max;i+=2) { gTime = gTime + llList2Float(gActions, i); // llWhisper(0,(string)gTime); } gObey = [1.0, 0.5, 0.1, 0.9, 0.5]; } read_notecard() { // Read description // Read actions list } write_behavior() {// IM's or emails owner the current behavior } ////////////////////////////////////////////////////////////////////////// // CHOOSE BEHAVIOR // mod: mood modifier: // < 1 will only do the first mod% of the behaviors // = 1 will do behaviors exactly as specified (will do a behavior every time) // > 1 has increasing chance of doing nothing // time: the sum of all 'chances' much faster to calculate this ahead of time then as you go // behaviors: A list that looks like [chance, "behavior_command", chance, "behavior_command" // ex: [0.4, "bark", 0.2, "sit"] or [4, "bark", 2, "sit"] // Num and target are sent with the link message. Perhaps always call this with the key of // any currently targeted animal? Will work fine if 0 and "" are used respectively. // // Example call, although behavior should be a list stored in a variable made from reading a notecard... // choose_behavior(1,0.6,[0.4,"sleep",0.2,"bark"],0,""); choose_behavior(float mod, float time, list behaviors, integer num, key target) { float choice = llFrand(time * mod); // llWhisper(0,"time = "+(string)time); // llWhisper(0,"choice = "+(string)choice); integer i; integer max = llGetListLength(behaviors); for (i=0;i<max;i+=2) { if (choice < (float)llList2String(behaviors,i)) { //Do this action! llMessageLinked(LINK_SET,num,llList2String(behaviors,i+1),target); // llWhisper(0,llList2String(behaviors,i+1)); llSetText(llList2String(behaviors,i+1), <0.5,0.5,1>,1); return; } else { choice -= llList2Float(behaviors,i); } } } introduce() { llSay(gIntroduction_channel, "introduction + "+gBehavior_0); } ////////////////////////////////////////////////////////////////////////// // OBEY function // Any incoming commands are sent to this function. This script determines // if the command will be obeyed based on values from the pet's behavior // setup. If the command will be obeyed, it will be sent out to the other // scripts in the pet. // There are 5 parameters for the obey variable, // (threat, neutral, prey, owner, other avatar), // each ranging from 0 to 1. // If the parameter is 0, the pet will never obey a command from something // in that class, if it's 1 the pet will always obey that command. integer obey ( string command, string string_this_pet, key commander ) { //gBehavior_0 = "fight|0.3 + flee|0.4 + type|dog + subtype|beagle + action|watching + target|master + group|6500"; list list_this_pet = llParseString2List(string_this_pet, ["|", "+", " "], []); if(DEBUG)llOwnerSay(":.pet: " + "list_this_pet is "+llDumpList2String(list_this_pet, ",")); //integer llSubStringIndex(string source, string pattern) float this_pet_flee = llList2Float(list_this_pet, (llListFindList(list_this_pet, ["flee"])+1)); float this_pet_fight = llList2Float(list_this_pet, (llListFindList(list_this_pet, ["fight"])+1)); //check that we actually have a flee & fight value for commander in our MRU. if not, assume commander has fight of 0, flee of 1. float commander_flee = 1; float commander_fight = 0; integer obey = FALSE; //NEED COMMANDER'S KEY //THEN SEARCH THE MRU FOR THE KEY integer commander_in_MRU = llListFindList(glBehaviors_MRU, [(string)commander]); if ( commander_in_MRU != -1 ) { if(DEBUG)llOwnerSay(":.pet: " + "commander_in_MRU is "+(string)commander_in_MRU); //IF THE COMMANDER'S KEY IS IN OUR MRU //READ THE FIGHT AND FLEE FROM OUR MRU commander_fight = llList2Float(glBehaviors_MRU, (commander_in_MRU+1)); if(DEBUG)llOwnerSay(":.pet: " + "llListFindList(list_this_pet) is "+(string)(llListFindList(list_this_pet, ["flee"])+1)); commander_flee = llList2Float(glBehaviors_MRU, commander_in_MRU+2 ); //***to do*** make sure numbers are between 0.0 and 1.0 } ; //llSay(0, "glBehaviors_MRU is "+llDumpList2String(glBehaviors_MRU, ",")); if(DEBUG)llOwnerSay(":.pet: " + "this_pet_flee is "+(string)this_pet_flee+" & this_pet_fight is "+(string)this_pet_fight); if(DEBUG)llOwnerSay(":.pet: " + "commander_flee is "+(string)commander_flee+" & commander_fight is "+(string)commander_fight); // owner // else if ( other == gOwner ) { // if (llList2Float(commander,4) > llFrand(1)) // calculate chance of obeying the command // llMessageLinked(command); } //other // else if ( other != gOwner ) { // if (llList2Float(commander,5) > llFrand(1)) // calculate chance of obeying the command // llMessageLinked(command); } // test if commander is a threat if ( commander_fight > this_pet_fight ) { llSay(0, (string)commander_fight +">"+ (string)this_pet_flee); if (llList2Float(gObey,0) > llFrand(1)) // calculate chance of obeying the command { llMessageLinked(-4, 0, command, NULL_KEY); obey = TRUE; llSay(0, "commander_fight > this_pet_flee. obey is "+(string)obey); } } // prey // else if ( this_pet.fight > commander.flee ) { // if (llList2Float(commander,3) > llFrand(1)) // calculate chance of obeying the command // llMessageLinked(command); } // neutral // if ( commander.fight > this_pet.flee ) { // if (llList2Float(obey,2) > llFrand(1)) // calculate chance of obeying the command // llMessageLinked(command); } return obey; } default { state_entry() { initialize(); } on_rez(integer start_param) { initialize(); } listen(integer channel, string name, key id, string message) { // if id = gOwner // if id = pet_key // if id = pet_group // list lPet_key = [(string)get_pet_channel(id)]; //***to do***do a bounds check before converting to list? list glCurrentMessage = llParseString2List(message, ["|", "+", " "], []); //gBehavior_1 = llSetText(llKey2Name(id)+": "+(string)message, <1,0,0>,1); llSleep(0.01); llSetText(llKey2Name(id)+": "+(string)message, <1,1,1>,1); //llWhisper(0,(string)message); //llSay(0, llList2String(glCurrentMessage, 0)); if (llList2String(glCurrentMessage, 0) == "command") obey(message, gBehavior_0, id); // decide if this pet should obey the command // (respond to requests) // (respond to questions) // (make note of introductions) if (llList2String(glCurrentMessage, 0) == "introduction") { // glBehaviors_MRU = [ "a", "0", "0", "0", "0", "0", "0", "b", "9916", "h" ]; integer Pet_key_in_MRU = llListFindList(glBehaviors_MRU, [(string)id]); // find where this pet is in our contact list //llWhisper(0,"lPet_key "+(string)lPet_key+" is at '"+(string)Pet_key_in_MRU+"'"); //================== //llSay(0, "glBehaviors_MRU is "+llDumpList2String(glBehaviors_MRU, ",")); //================== // 1) See if the pet is already in the list // 2) If they are in the list, remove them from the list and add them to the front of the list // 3) if they are not in the list, add them to the front of the list and delete whatever is at the end of the list if (Pet_key_in_MRU == -1) // if the pet is not in our contact list, add it and it's fight/flee parameters to the front of the list and delete the last pet on the list { // find the fight/flee parameters list temp_list = llParseString2List(message, ["|"," + "], []); float fight_value = llList2Float(temp_list, (llListFindList(temp_list, ["fight"])+1)); float flee_value = llList2Float(temp_list, (llListFindList(temp_list, ["flee"])+1)); // llInstantMessage(llGetOwner(), "fight_value = '"+(string)fight_value+"'"); // llInstantMessage(llGetOwner(), "flee_value = '"+(string)flee_value+"'"); glBehaviors_MRU = [(string)id, fight_value, flee_value]+glBehaviors_MRU; glBehaviors_MRU = llDeleteSubList(glBehaviors_MRU, 27, 29); //glBehaviors_MRU = ["A", "5", "orange"]+glBehaviors_MRU; // llInstantMessage(llGetOwner(), "glBehaviors_MRU = '"+(string)glBehaviors_MRU+"'"); // llInstantMessage(llGetOwner(), "lPet_key = '"+(string)llget_param_value("fight|")+"'"); } else { // find the fight/flee parameters list temp_list = llParseString2List(message, ["|"," + "], []); float fight_value = llList2Float(temp_list, (llListFindList(temp_list, ["fight"])+1)); float flee_value = llList2Float(temp_list, (llListFindList(temp_list, ["flee"])+1)); glBehaviors_MRU = llDeleteSubList(glBehaviors_MRU, Pet_key_in_MRU, Pet_key_in_MRU+2); glBehaviors_MRU = [(string)id, fight_value, flee_value]+glBehaviors_MRU; } } } changed(integer change) { // read_notecard; } timer() { // if not in the middle of behavior?? introduce(); //choose_behavior(float mod, float time, list behaviors, integer num, key target) choose_behavior(1,gTime,gActions,0,""); // stay_close_to_owner(); } }