Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- integer channel = 68;
- integer PEG_CHAN=699;
- integer TIMER_INTERVAL=5; // how often to run the timer ////DEFAULT IS 5
- integer autoLoadOnReset=0;
- string LASTNAME="";
- // Nothing to edit here, see https://github.com/opensimworld/active-npcs for configuration
- list availableNames = [];
- list lastNames = [];
- // These will be loaded from notecards
- list wNodes = [];
- list wLinks = [];
- list wNodeNames=[];
- // list of nodes for the "Flyaround" command
- list flyTargets = [];
- list menuItems = ["SaveNPC", "LoadNPC", "RemoveNPC", "RemoveAll", "LoadAll", "ReConfig","InitCmds", "DumpData", "TimerOnOff", "Close"];
- string userInputState ="";
- integer gListener;
- integer zListener;
- integer howmany;
- list avis;
- integer curVisitors=1;
- integer deflectToNode = -1; // if set, the NPCs will only run notecards at the specified waypoint
- list aviUids;
- list aviNames;
- list aviNodes;
- list aviPrevNodes;
- list aviStatus;
- list aviFollow;
- list aviCurrentAnim;
- list aviPath;
- list aviAlarm;
- list aviScriptIndex;
- list aviScriptText;
- list aviHttpId;
- list aviTarget; // user we are interacting with
- list scriptVars;
- list aviScriptState;
- list aviPrompts;
- list cache;
- integer aviIndex = -1;
- list seenArchive;
- list positionsList;
- list greetedAvis;
- integer timerRuns;
- integer timerRunning;
- integer curPoint;
- integer prevPoint;
- list wayPoints;
- list wayNames;
- list wayLinks;
- list wayKeys;
- string name;
- key npc;
- list candidateNode=[];
- string vec2str(vector v)
- {
- return "<"+v.x+","+v.y+","+v.z+">";
- }
- string GetLastName(string first)
- {
- integer idx = llListFindList(availableNames, [first]);
- if (idx >=0) return llList2String(lastNames, idx);
- else return LASTNAME;
- }
- key getAgentByName(string firstName)
- {
- firstName = llToLower(firstName);
- list ag = osGetAvatarList();
- integer howmany = llGetListLength(ag);
- integer i;
- for (i =0; i < howmany; i+=3)
- {
- string name = llList2String(ag, i+2);
- integer sep = llSubStringIndex(name, " ");
- if (llToLower(llGetSubString(name, 0,sep-1)) == firstName)
- {
- return llList2Key(ag, i);
- }
- }
- return NULL_KEY;
- }
- string GetScriptVar(string cmd3)
- {
- integer i;
- for (i=0; i < llGetListLength(scriptVars); i+=2)
- {
- if (llList2String(scriptVars,i) == cmd3 )
- {
- return llList2String(scriptVars, i+1);
- }
- }
- return ""; // default value;
- }
- integer ScriptJump(integer idx, string label, integer complain)
- {
- // Jump to a label in the notecard
- integer foundLine = FindScriptLineAfter(llList2String(aviScriptText,idx), "@"+label,-1);
- if (foundLine == -1)
- {
- if (complain) llOwnerSay("Error: @"+label+" label not found");
- return 0;
- }
- else
- {
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [foundLine+1], idx, idx);
- return 1;
- }
- }
- list permList;
- string permCache;
- LoadPerms()
- {
- permList=[];
- permCache = "";
- if (llGetInventoryType("__permissions")==INVENTORY_NOTECARD)
- {
- llOwnerSay("Loading Permissions...");
- list lines = llParseString2List(osGetNotecard("__permissions"), ["\n"], []);
- integer l;
- for (l=0;l<llGetListLength(lines);l++)
- {
- list tk = llParseString2List(llList2String(lines,l), [" "], []);
- if (llList2String(tk,2) == "=")
- {
- string kw = llList2String(tk,3);
- string rule=llToLower(llList2String(tk,0)+" "+llList2String(tk,1));
- string n= llToLower(llStringTrim(llList2String(tk,4)+ " " + llList2String(tk,5), STRING_TRIM));
- if (n == "" ) n= "*";
- string val=kw+"|"+n+"|";
- permList+=rule;
- permList+=kw;
- permList+=n;
- if (llSubStringIndex(permCache,rule)<0) permCache+= rule;
- }
- }
- llOwnerSay(llList2CSV(permList));
- llOwnerSay(llList2CSV(permCache));
- }
- }
- integer IsAllowed(string npc, string cmd, key uid)
- {
- if (uid == llGetOwner() || llGetListLength(permList)==0) return 1;
- string ss = "* *";
- string ns = npc+" *";
- string sc = "* "+cmd;
- string nc = npc+" "+cmd;
- if (llSubStringIndex(permCache, ss)<0 && llSubStringIndex(permCache, ns)<0 && llSubStringIndex(permCache, sc)<0 && llSubStringIndex(permCache, nc)<0 ) return 1;
- integer allow=1;
- string name = llToLower(llKey2Name(uid));
- integer k;
- for (k=0; k< llGetListLength(permList); k+=3)
- {
- string rule = llList2String(permList,k);
- if (rule==ss || rule==ns || rule==sc || rule==nc)
- {
- //llOwnerSay("R="+rule);
- string r = llList2String(permList, k+1);
- if (r =="ALLOW" || r == "DENY")
- {
- string who=llList2String(permList, k+2);
- if (who == "*" || who==name)
- {
- if (r == "ALLOW") allow=1;
- else allow=0;
- }
- }
- else if (r=="ALLOWID")
- {
- if ( uid == llList2Key(permList, k+2)) allow=1;
- }
- else if (r=="DENYID")
- {
- if ( uid == llList2Key(permList, k+2)) allow=0;
- }
- else if (r =="ALLOWSAMEGROUP")
- {
- if ( llSameGroup(uid)) {
- allow=1;
- }
- }
- }
- }
- return allow;
- }
- ReloadConfig()
- {
- availableNames = [];
- lastNames = [];
- list tk = llParseString2List(osGetNotecard("__npc_names"), ["\n"] , []);
- integer i=0;
- for (i=0; i < llGetListLength(tk); i++)
- {
- list t2 = llParseString2List(llList2String(tk,i), [" "] , []);
- string f = llList2String(t2, 0);
- string l = llList2String(t2, 1);
- if (l =="") l = LASTNAME;
- if (f != "")
- {
- availableNames += f;
- lastNames += l;
- }
- }
- llOwnerSay("npc_names: "+llList2CSV(availableNames));
- flyTargets = llParseString2List(osGetNotecard("__fly_targets"), [" ", "\n", ""] , []);
- string ncName = "__config";
- autoLoadOnReset=0;
- if (llGetInventoryType(ncName) == INVENTORY_NOTECARD)
- {
- list tok = llParseString2List(osGetNotecard("__config"), ["=", "\n"] , []);
- integer j;
- for (j=0; j < llGetListLength(tok); j+=2)
- {
- string opt = llList2String(tok,j);
- if (opt== "AutoLoadOnReset") autoLoadOnReset = (integer)llList2String(tok, j+1);
- else if (opt== "LastName") LASTNAME = llList2String(tok, j+1);
- }
- }
- if (LASTNAME == "") LASTNAME = "(NPC)";
- LoadPerms();
- }
- integer countVisitors()
- {
- list avis = llGetAgentList(AGENT_LIST_REGION, []);
- integer howmany = llGetListLength(avis);
- integer i;
- integer nNew =0;
- for ( i = 0; i < howmany; i++ ) {
- if ( ! osIsNpc(llList2Key(avis, i)) )
- {
- nNew++; // only non-NPC's
- key uu = llList2Key(avis, i);
- string nm = llKey2Name(uu);
- if (nm != "")
- {
- integer fnd = llListFindList(seenArchive, [nm]);
- if (fnd >=0)
- seenArchive = [] + llListReplaceList(seenArchive, [nm, llGetUnixTime()], fnd, fnd+1);
- else
- seenArchive = [] + seenArchive + [nm, llGetUnixTime()];
- }
- }
- }
- return nNew;
- }
- doLoadNPC(string first, string last)
- {
- integer idx =(GetNPCIndex(first));
- if (idx >=0)
- {
- llOwnerSay(first+ " is already in region, not loading");
- osNpcStand(llList2Key(aviUids, idx));
- return;
- }
- key unpc = osNpcCreate(first, last, llGetPos()+<3,0,3>, "APP_"+llToLower(first), OS_NPC_SENSE_AS_AGENT );
- if (unpc != NULL_KEY)
- doAddNpc(first, unpc);
- }
- doAddNpc(string name, string unpc)
- {
- llOwnerSay( "Adding '"+name+"'");
- aviUids += unpc;
- aviNames += llToLower(name);
- aviNodes += 1;
- aviPrevNodes += 0;
- aviStatus += "";
- aviFollow += "";
- aviCurrentAnim += "";
- aviHttpId += "";
- aviAlarm += -1;
- aviScriptIndex += -1;
- aviScriptText += "";
- aviTarget += NULL_KEY;
- aviPath += "";
- aviScriptState += "";
- aviPrompts += "";
- osNpcMoveToTarget(unpc, osNpcGetPos(unpc) + <1,0,0>, OS_NPC_NO_FLY );
- }
- doRemoveNpc(string who)
- {
- integer idx = GetNPCIndex(who);
- if (idx <0) return;
- key u = llList2Key(aviUids, idx);
- aviNames = [] + llDeleteSubList(aviNames, idx, idx);
- aviUids = [] + llDeleteSubList(aviUids, idx, idx);
- aviNodes = [] + llDeleteSubList(aviNodes, idx, idx);
- aviPrevNodes = [] + llDeleteSubList(aviNodes, idx, idx);
- aviFollow = [] + llDeleteSubList(aviFollow, idx, idx); [];
- aviStatus = [] + llDeleteSubList(aviStatus, idx, idx);
- aviCurrentAnim = [] + llDeleteSubList(aviCurrentAnim, idx, idx);
- aviPath = [] + llDeleteSubList(aviPath, idx, idx);
- aviHttpId = [] + llDeleteSubList(aviHttpId, idx, idx);
- aviAlarm = [] + llDeleteSubList(aviAlarm, idx, idx);
- aviScriptIndex = [] + llDeleteSubList(aviScriptIndex, idx, idx);
- aviScriptText = [] + llDeleteSubList(aviScriptText, idx, idx);
- aviTarget = [] + llDeleteSubList(aviTarget, idx, idx);
- aviScriptState = [] + llDeleteSubList(aviScriptState, idx, idx);
- aviPrompts = [] + llDeleteSubList(aviPrompts, idx, idx);
- llOwnerSay("Removing "+who + "");
- osNpcStand(u);
- osNpcRemove(u);
- }
- doLoadAll()
- {
- integer i;
- for (i=0; i < llGetListLength(availableNames);i++)
- {
- doLoadNPC(llList2String(availableNames, i), llList2String(lastNames, i));
- }
- }
- doInitCmds()
- {
- string notecard= "__initcommands";
- integer i;
- for(i=0; i<=osGetNumberOfNotecardLines(notecard); i++) {
- string line = llStringTrim(osGetNotecardLine(notecard, i), STRING_TRIM);
- if (llStringLength(line)>0 && line != "")
- {
- list l = llParseString2List(line, [" "], []);
- line = "! "+(string)NULL_KEY+" "+llList2String(l,0)+" "+ line;
- llOwnerSay("InitCmd="+line);
- ProcessNPCCommand(line);
- }
- }
- }
- setVar(string cmd2, string cmd3)
- {
- integer i;
- for (i=0; i < llGetListLength(scriptVars); i+=2)
- {
- if (llList2String(scriptVars,i) == cmd2)
- {
- scriptVars = [] + llListReplaceList(scriptVars, [cmd3], i+1, i+1);
- return;
- }
- }
- scriptVars += cmd2;
- scriptVars += cmd3;
- }
- integer RescanAvis()
- {
- avis = osGetAvatarList();
- howmany = llGetListLength(avis);
- integer i;
- for (i =0; i < howmany; i+=3)
- {
- if (osIsNpc(llList2Key(avis, i)))
- {
- integer sep = llSubStringIndex(llList2Key(avis, i+2), " ");
- string nm = llGetSubString(llList2Key(avis, i+2), 0, sep-1 );
- doAddNpc(nm, llList2Key(avis, i));
- }
- }
- llOwnerSay(llList2CSV(aviNames));
- llOwnerSay(llList2CSV(aviStatus));
- return llGetListLength(aviUids);
- }
- LoadMapData()
- {
- integer tl = osGetNumberOfNotecardLines("__waypoints");
- integer i;
- wNodes = [];
- for (i=0; i < tl; i++)
- {
- string line = osGetNotecardLine("__waypoints",i);
- list tok = llParseStringKeepNulls(line, [","], []);
- float x = llList2Float(tok,0);
- if (x>0)
- {
- vector v = <llList2Float(tok,0), llList2Float(tok,1),llList2Float(tok,2)>;
- wNodes += v;
- wNodeNames += llList2String(tok,3);
- }
- }
- llOwnerSay("loaded "+(string)(llGetListLength(wNodes))+" waypoints");
- integer tnodes = llGetListLength(wNodes);
- wLinks = [];
- tl = osGetNumberOfNotecardLines("__links");
- for (i=0; i < tl; i++)
- {
- string line = osGetNotecardLine("__links",i);
- list tok = llParseString2List(line, [","],"");
- integer a= llList2Integer(tok,0);
- integer b = llList2Integer(tok,1);
- if (a !=b)
- wLinks += [a,b];
- }
- llOwnerSay("loaded "+(string)(llGetListLength(wLinks)/2)+" links");
- cache = [];
- }
- integer GetNPCIndex(string name) /// name is in lowercase
- {
- return llListFindList(aviNames, [llToLower(name)]);
- }
- integer GetWalkTime(float distance)
- {
- return llCeil(distance / 1.7);
- }
- integer GetNearestNode(vector pos)
- {
- integer i;
- float min = 9999991.;
- integer l =-1;
- for (i=0;i < llGetListLength(wNodes); i++)
- {
- float dist = llVecDist(pos, llList2Vector(wNodes,i));
- if (dist < min)
- {
- min = dist;
- l=i;
- }
- }
- return l;
- }
- list foundPaths;
- // Get path through LSL -- Slow
- integer GenPaths(integer a, integer tgt, string path, integer depth)
- {
- if (depth > 17)
- {
- //llOwnerSay("Bailing at " + path);
- return 0;
- }
- integer i;
- for (i=0; i < llGetListLength(wLinks); i+=2)
- {
- integer ca = llList2Integer(wLinks, i);
- integer cb = llList2Integer(wLinks, i+1);
- integer fn = -1;
- if (cb == a || ca == a)
- {
- if (cb == a)
- fn = ca;
- else if (ca == a)
- fn = cb;
- if (llSubStringIndex(path, ":"+fn+":")<0)
- {
- if (fn == tgt)
- {
- path += ""+fn+":";
- foundPaths += (path);
- return 1;
- }
- else
- {
- GenPaths(fn, tgt, path+fn+":", depth+1);
- }
- }
- }
- if (llGetListLength(foundPaths)>30)
- return 2;
- }
- return 0;
- }
- string GetGotoPath(integer nodeA, integer nodeB)
- {
- integer i;
- integer ww;
- string tmpPath = ":"+(string)nodeA+":";
- foundPaths = [];
- GenPaths(nodeA, nodeB, tmpPath, 0);
- //llOwnerSay(llList2CSV(foundPaths));
- if (llGetListLength(foundPaths) ==0)
- return "";
- integer min = 99999;
- string least = "";
- for (i=0; i < llGetListLength(foundPaths); i++)
- {
- ww = llStringLength(llList2String(foundPaths, i));
- if (ww < min)
- {
- min = ww;
- least = llList2String(foundPaths, i);
- }
- }
- //llOwnerSay(least);
- return least;
- }
- integer GetNPCIndexByUid(key name)
- {
- return llListFindList(aviUids, [name]);
- }
- string GetScriptLine(string scriptData, integer line)
- {
- list scriptLines = llParseStringKeepNulls(scriptData, ["\n",";"], []);
- return llList2String(scriptLines, line-1);
- }
- integer FindScriptLineAfter(string scriptData, string lineToFind, integer afterLine)
- {
- integer endIdx;
- list scriptLines = llParseStringKeepNulls(scriptData, ["\n",";"], []);
- string toFind = llToLower(lineToFind);
- integer foundLine = -1;
- string line;
- for (endIdx = afterLine+1;endIdx < llGetListLength(scriptLines); endIdx++)
- {
- line = llList2String(scriptLines, endIdx);
- if (llStringTrim(line, STRING_TRIM) == toFind)
- {
- foundLine =endIdx;
- jump _foundIdxOut;
- }
- }
- @_foundIdxOut;
- return foundLine;
- }
- integer FindMatchingEndif(string scriptData, integer afterLine)
- {
- integer endIdx;
- list scriptLines = llParseStringKeepNulls(scriptData, ["\n",";"], []);
- string toFind = "end-if";
- integer foundLine = -1;
- string line;
- integer ifLevel=1;
- for (endIdx = afterLine+1;endIdx < llGetListLength(scriptLines); endIdx++)
- {
- line = llStringTrim(llList2String(scriptLines, endIdx), STRING_TRIM);
- if (llGetSubString(line, 0, 1) == "if")
- {
- ifLevel++;
- }
- else if (line == "end-if")
- {
- ifLevel--;
- if (ifLevel==0)
- {
- foundLine =endIdx;
- jump _foundEIIdxOut;
- }
- }
- }
- @_foundEIIdxOut;
- return foundLine;
- }
- integer GetNodeIndexByName(string nodeName)
- {
- integer i;
- nodeName = llToLower(nodeName);
- for (i=0; i < llGetListLength(wNodeNames); i++)
- {
- if (llToLower(llList2String(wNodeNames, i)) == nodeName)
- {
- return i;
- }
- }
- return -1;
- }
- SetScriptAlarm(integer aviId, integer time)
- {
- aviAlarm = [] + llListReplaceList(aviAlarm, [llGetUnixTime() + time], aviId, aviId);
- }
- doStopNpc(integer idx, key uNPC)
- {
- aviStatus = [] + llListReplaceList(aviStatus, [""], idx, idx);
- SetScriptAlarm(idx, 0);
- list anToStop=llGetAnimationList(uNPC);
- integer stop=llGetListLength(anToStop);
- while (--stop>=0) { osNpcStopAnimation(uNPC,llList2Key(anToStop,stop)); }
- osNpcStopMoveToTarget(uNPC);
- osNpcStand(uNPC);
- }
- // Handler for all commands coming from chat
- integer ProcessNPCCommand(string inputString)
- {
- list tokens = llParseString2List(inputString, [" "], []);
- // first token should be just "!"
- //llOwnerSay("<<" + inputString);
- key sendUid = llList2Key(tokens,1);
- string npcName = llToLower(llList2String(tokens,2));
- string name2 = llToLower(llList2String(tokens,3));
- //if (npcName != name2) npcName = name2;
- integer idx = GetNPCIndex(npcName);
- if (idx <0)
- {
- return 1;
- }
- key uNPC= llList2Key(aviUids, idx);
- if (uNPC == NULL_KEY)
- {
- return 1;
- }
- if (llSubStringIndex(inputString, "$")>=0) //substiute variables
- {
- integer i;
- for (i=4; i < llGetListLength(tokens); i++)
- {
- string st = llList2String(tokens,i);
- if (llSubStringIndex(st, "$")==0)
- {
- tokens = [] + llListReplaceList(tokens, [ GetScriptVar(llGetSubString(st,1,-1) ) ], i , i);
- }
- }
- }
- string cmd1= llList2String(tokens,4);
- string cmd2= llList2String(tokens,5);
- list userData;
- if (sendUid!= NULL_KEY && (llGetAgentSize(sendUid) != ZERO_VECTOR))
- {
- if (!IsAllowed(npcName, cmd1, sendUid))
- {
- llOwnerSay("Denied '"+cmd1+"' to "+(string)sendUid+" "+llKey2Name(sendUid));
- return 1;
- }
- }
- if (llList2String(aviStatus, idx) == "prompt")
- {
- aviStatus = []+llListReplaceList(aviStatus, [""], idx, idx); // Turn off prompt in sync with the listener
- if (npcName != name2 ) // it (probably) a response to the prompt, rather than a command given to the npc
- {
- integer i;
- for (i=3; i < llGetListLength(tokens); i++)
- {
- if ( llSubStringIndex(llList2String(aviPrompts, idx), "["+llToLower(llList2String(tokens, i))+"]" ) > 0) // label existed in prompt
- {
- aviTarget = []+llListReplaceList(aviTarget, [sendUid], idx, idx);
- ScriptJump(idx, llToLower(llList2String(tokens, i)) , 1);
- return 1;
- }
- }
- return 1;
- }
- }
- if (cmd1 == "stop")
- {
- doStopNpc(idx, uNPC);
- }
- else if (cmd1 == "come")
- {
- doStopNpc(idx, uNPC);
- userData=llGetObjectDetails((key)sendUid, [OBJECT_NAME,OBJECT_POS, OBJECT_ROT]);
- osNpcStopMoveToTarget(uNPC);
- osTeleportAgent(uNPC, llList2Vector(userData, 1) + <1, 0, 0>, <1,1,1>);
- if (sendUid != NULL_KEY) // NOTE: a real avatar sent this command - stop processing our script
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, -1, idx, idx);
- }
- else if (cmd1 == "stand")
- {
- aviStatus = []+llListReplaceList(aviStatus, [""], idx, idx);
- osNpcStand(uNPC);
- osNpcStopMoveToTarget(uNPC);
- }
- else if (cmd1 == "moveto" || cmd1 == "movetov" || cmd1 == "runtovr"|| cmd1 == "movetovr" || cmd1 == "flytov" || cmd1 == "runtov" || cmd1=="walk" )
- {
- // Walk to the specified waypoint or vector
- vector v;
- string anim =""; // Specify an animation to play while walking
- if (cmd1 == "runtovr"||cmd1 == "movetovr")
- {
- // run to somewhere within the volume enclosed by v1 and v2
- vector v1 = (vector) cmd2;
- vector v2 = (vector) llList2String(tokens, 6);
- v.x= v1.x + llFrand(v2.x-v1.x);
- v.y= v1.y + llFrand(v2.y-v1.y);
- v.z= v1.z + llFrand(v2.z-v1.z);
- anim = llList2String(tokens, 7);
- }
- else if (cmd1 == "movetov" || cmd1 == "flytov" ||cmd1 == "runtov" || cmd1 =="walk")
- {
- v = (vector)cmd2;
- if (v == ZERO_VECTOR)
- {
- llOwnerSay(npcName + ": "+cmd2+" is not a good position. I am not going there!");
- return 1;
- }
- anim = llList2String(tokens, 6);
- }
- else
- v = llList2Vector(wNodes, (integer)cmd2);
- float dist = llVecDist(osNpcGetPos(uNPC), v);
- if (cmd1 == "runtovr"|| cmd1 == "runtov")
- {
- osSetSpeed(uNPC, 1.0);
- osNpcMoveToTarget(uNPC, v + <0,0,1>, OS_NPC_NO_FLY | OS_NPC_RUNNING);
- SetScriptAlarm(idx, (integer)(GetWalkTime(dist)/2.));
- }
- else
- {
- if (anim == "")
- osNpcStand(uNPC);
- osNpcStopMoveToTarget(uNPC);
- osSetSpeed(uNPC, 0.5);
- if (cmd1 == "flytov")
- osNpcMoveToTarget(uNPC, v + <0,0,1>, OS_NPC_FLY );
- else
- osNpcMoveToTarget(uNPC, v + <0,0,1>, OS_NPC_NO_FLY);
- if (anim)
- {
- llSleep(0.5);
- osNpcPlayAnimation(uNPC, anim);
- }
- SetScriptAlarm(idx, GetWalkTime(dist));
- }
- }
- else if (cmd1 == "setvar")
- {
- string cmd3 = llList2String(tokens,6);
- setVar(cmd2, cmd3);
- return 0;
- }
- else if (cmd1 == "if" || cmd1 == "if-not" || cmd1=="if-prob")
- {
- integer res = 0;
- if (cmd1 == "if-prob")
- {
- if (llFrand(1.0)<(float)cmd2)
- res = 1;
- }
- else if (cmd2 == "name-is")
- {
- integer k;
- res=0;
- for (k=6; k < llGetListLength(tokens); k++)
- {
- if (llToLower(npcName) == llToLower(llList2String(tokens,k)))
- {
- setVar("_found", npcName);
- res=1;
- }
- }
- }
- else if (cmd2 == "var-is")
- {
- integer k;
- res=0;
- for (k=6; k < llGetListLength(tokens); k+=2)
- {
- string nm = llList2String(tokens,k);
- if (nm == "") jump varIsBreak;
- string val = llList2String(tokens,k+1);
- if (GetScriptVar(nm) == val)
- res =1;
- else
- {
- res=0;
- jump varIsBreak;
- }
- }
- @varIsBreak;
- }
- else if (cmd2 == "state-is")
- {
- // If state-is <avi-name> <state-value>
- integer nwho = GetNPCIndex(llList2String(tokens,6));
- if (nwho >=0)
- {
- string what = llList2String(aviScriptState,nwho);
- integer k;
- for (k=7; k < llGetListLength(tokens); k++)
- {
- if (what == llList2String(tokens,k))
- res=1;
- }
- }
- }
- if (cmd1 == "if-not")
- res = !res;
- integer scrline = llList2Integer(aviScriptIndex, idx);
- if (scrline <0)
- {
- return 1; // wtf
- }
- if (!res)
- {
- integer foundLine = FindMatchingEndif(llList2String(aviScriptText,idx), scrline-1); /// this used to skip a line
- if (foundLine == -1)
- {
- llOwnerSay("Error: end-if not found afterr "+cmd1 + " "+cmd2 + "...");
- }
- else
- {
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [foundLine+1], idx, idx);// Go past the end-if -- runs notecards faster
- }
- }
- return 0;
- }
- else if (cmd1 == "end-if")
- {
- // Do nothing
- return 0;
- }
- else if (cmd1 == "prompt")
- {
- string prompt = llDumpList2String(llList2List(tokens, 5, -1), " ");
- aviStatus = []+llListReplaceList(aviStatus, ["prompt"], idx, idx);
- osNpcSay(uNPC, prompt);
- aviPrompts = []+llListReplaceList(aviPrompts, [llToLower(inputString)], idx, idx);
- aviTarget = []+llListReplaceList(aviTarget, [NULL_KEY], idx, idx);
- osMessageAttachments(uNPC, "prompt", [ATTACH_RIGHT_PEC], 0);
- }
- else if (cmd1 == "jump")
- {
- // Jump to a label in the notecard
- ScriptJump(idx, llToLower(cmd2), 1);
- return 0; // process next cmd immediately
- }
- else if ((cmd1 == "go" && cmd2 == "to") || cmd1 == "goto")
- {
- // Pathfinding command
- integer nearest = GetNearestNode(osNpcGetPos(uNPC));
- integer foundId =-1;
- if (cmd1 == "goto")
- {
- foundId = (integer) cmd2;
- }
- else
- {
- string where = llToLower(llStringTrim(llList2String(tokens,6) +" "+ llList2String(tokens,7) +" "+ llList2String(tokens,8), STRING_TRIM));
- integer i;
- if (where != "")
- foundId = GetNodeIndexByName(where);
- if (foundId <0)
- {
- list tmp;
- for (i=0; i < llGetListLength(wNodeNames); i++)
- if (llList2String(wNodeNames,i) != "")
- tmp += llList2String(wNodeNames, i);
- osNpcSay(uNPC, "Sorry i dont know how to get to the "+where+ ". Here's some of the places i know: " +llList2CSV(tmp));
- return 1;
- }
- }
- osNpcSay(uNPC, "Let me think... ");
- string cachekey = "f,"+(string)nearest+","+(string)foundId;
- string gotoPath ="";
- integer fidx = llListFindList(cache, [cachekey]);
- if (fidx>=0)
- {
- gotoPath = llList2String(cache, fidx+1);
- }
- else
- {
- gotoPath = GetGotoPath(nearest, foundId);
- if (gotoPath != "")
- {
- cache += cachekey;
- cache += gotoPath;
- }
- }
- if (gotoPath == "")
- {
- osNpcSay(uNPC, "I 'm dumb. i don't know how to get there ... ");
- return 1;
- }
- osNpcSay(uNPC, "If you want to go there, follow me.");
- SetScriptAlarm(idx, 0);
- aviPath = []+ llListReplaceList(aviPath, [gotoPath], idx, idx);
- aviStatus = []+llListReplaceList(aviStatus, ["pathf"], idx, idx);
- }
- else if (cmd1 == "setpath")
- {
- //Path must be in format 2:4:63:22:1 where the numbers are the waypoints numbers
- aviPath = []+ llListReplaceList(aviPath, [cmd2], idx, idx);
- SetScriptAlarm(idx, 0);
- aviStatus = []+llListReplaceList(aviStatus, ["pathf"], idx, idx);
- }
- else if (cmd1 == "waitvar")
- {
- // Wait until the value of variable named cmd2 reaches the value cmd3
- string cmd3 = llList2String(tokens,6);
- string vval = GetScriptVar(cmd2);
- if (vval == cmd3)
- {
- return 1; /// OK continue with the next line
- }
- else if (cmd3 == "NONEMPTY" && vval != "")
- {
- return 1;
- }
- integer scriptIndex = llList2Integer(aviScriptIndex, idx);
- if (scriptIndex>0)
- {
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [scriptIndex-1], idx, idx);
- }
- }
- else if (cmd1 == "increase" || cmd1 == "decrease" || cmd1 == "zero")
- {
- integer v = (integer)GetScriptVar(cmd2);
- if (cmd1=="increase") v++;
- else if (cmd1 == "decrease") v--;
- else v=0;
- setVar(cmd2, (string)v);
- return 1;
- }
- else if (cmd1 == "wait")
- {
- integer tm = (integer)cmd2;
- integer tm2 = (integer)llList2String(tokens,6);
- if (tm2>0)
- tm = (integer)(tm + llFrand(tm2));
- SetScriptAlarm(idx, tm);
- }
- else if (cmd1 == "say" || cmd1 == "shout")
- {
- // Say something on chat
- string txt = "";
- integer i;
- for (i=5; i < llGetListLength(tokens); i++)
- txt += llList2String(tokens,i) + " ";
- if (cmd1 == "shout")
- osNpcShout(uNPC, 0, txt);
- else
- osNpcSay(uNPC, txt);
- return 0;
- }
- else if (cmd1 == "saych")
- {
- // Say something on channel
- string txt = "";
- integer i;
- for (i=6; i < llGetListLength(tokens); i++)
- txt += llList2String(tokens,i) + " ";
- osNpcSay(uNPC, llList2Integer(tokens,5), txt);
- }
- else if (cmd1 == "loadnpc")
- {
- doLoadNPC(cmd2, llList2String(tokens, 6));
- }
- else if (cmd1 == "removenpc")
- {
- doRemoveNpc(cmd2);
- }
- else if (cmd1 == "exec")
- {
- list tok2 = ["!", (string)NULL_KEY, cmd2] + llList2List(tokens, 5, -1);
- //llOwnerSay(llList2CSV(tok2));
- ProcessNPCCommand(llDumpList2String(tok2, " "));
- }
- else if (cmd1 == "msgatt")
- {
- list points = [];
- integer i;
- for (i=6; i < llGetListLength(tokens); i++)
- {
- if (llList2Integer(tokens, i)>0)
- points += llList2Integer(tokens,i);
- }
- osMessageAttachments(uNPC, cmd2, points, 0);
- }
- else if (cmd1 == "teleport")
- {
- vector w = (vector) cmd2;
- if (w == ZERO_VECTOR)
- {
- integer where = GetNodeIndexByName(cmd2);
- if (where >=0)
- {
- w = llList2Vector(wNodes, where);
- osTeleportAgent(uNPC, w, <0,0,0>);
- }
- }
- else osTeleportAgent(uNPC, w, <0,0,0>);
- }
- else if (cmd1 == "use")
- {
- // Sit-on-a-poseball command
- string cmd = llStringTrim(cmd2+" "+llList2String(tokens, 6)+" "+llList2String(tokens,7), STRING_TRIM);
- osMessageAttachments(uNPC, "do "+cmd, [ATTACH_RIGHT_PEC], 0);
- }
- else if (cmd1 == "lookat")
- {
- vector v;
- if (cmd2=="me")
- {
- userData=llGetObjectDetails((key)sendUid, [OBJECT_NAME,OBJECT_POS, OBJECT_ROT]);
- v = llList2Vector(userData,1);
- }
- else
- {
- v = (vector)cmd2;
- if (v == ZERO_VECTOR)
- {
- integer midx = GetNodeIndexByName(llToLower(cmd2));
- if (midx >=0)
- {
- v = llList2Vector(wNodes, midx);
- }
- }
- }
- osNpcSetRot(uNPC, llRotBetween(<1,0,0>, v-osNpcGetPos(uNPC)));//llEuler2Rot(<0,0,ang>));
- }
- else if (cmd1 == "anim")
- {
- osNpcStopAnimation(uNPC, llList2String(aviCurrentAnim, idx));
- aviCurrentAnim = llListReplaceList(aviCurrentAnim, [cmd2], idx, idx);
- osNpcPlayAnimation(uNPC, cmd2);
- }
- else if (cmd1 == "give")
- {
- if (llGetInventoryType(cmd2) == INVENTORY_OBJECT)
- llGiveInventory(sendUid, cmd2);
- }
- else if (cmd1 == "light")
- osMessageAttachments(uNPC, "light", [ATTACH_RIGHT_PEC], 0);
- else if (cmd1 == "sound")
- osMessageAttachments(uNPC, "sound " + cmd2+" "+llList2String(tokens, 6) , [ATTACH_RIGHT_PEC], 0);
- else if (cmd1 == "batch")
- {
- // Run multiple commands from the chat, separated by ";" --- replaces any running script
- string str = llDumpList2String(llList2List(tokens, 5, llGetListLength(tokens))," ");
- aviScriptText = []+llListReplaceList(aviScriptText, str, idx, idx);
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [1], idx, idx);
- aviStatus = []+llListReplaceList(aviStatus, "", idx, idx);
- SetScriptAlarm(idx, 0);
- }
- else if (cmd1 == "follow")
- {
- aviStatus = []+llListReplaceList(aviStatus, ["follow"], idx, idx);
- if (cmd2=="me" || cmd2=="")
- {
- userData=llGetObjectDetails((key)sendUid, [OBJECT_NAME,OBJECT_POS, OBJECT_ROT]);
- aviFollow = []+llListReplaceList(aviFollow, [(key)sendUid], idx, idx);
- osNpcSay(uNPC, "Following you "+ llList2String(userData, 0));
- }
- else
- {
- key who = getAgentByName(cmd2);
- if (who != NULL_KEY)
- {
- aviFollow = []+llListReplaceList(aviFollow, [who], idx, idx);
- osNpcSay(uNPC, "Following " + cmd2);
- }
- }
- }
- else if (cmd1 == "set-state") // set a variable that indicates the current state of an NPC -- useful for scripts
- {
- aviScriptState= []+llListReplaceList(aviScriptState, [cmd2], idx, idx);
- return 0;
- }
- else if (cmd1 == "debug")
- {
- integer dd = llList2Integer(aviScriptIndex, idx);
- string scr;
- if (dd >=0)
- {
- scr = GetScriptLine(llList2String(aviScriptText,idx) , dd-1);
- }
- llOwnerSay("Status="+llList2String(aviStatus, idx)+" node = "+llList2Integer(aviNodes, idx)+
- " follow="+llList2String(aviFollow, idx)+" Alarm = "+(string)(llList2Integer(aviAlarm,idx)-llGetUnixTime())+
- " scriptIndex="+llList2Integer(aviScriptIndex, idx)+" scriptText " +scr );
- }
- else if (cmd1 == "fly" && cmd2=="with") // "fly with me" "fly with Foo"
- {
- string who = llList2String(tokens, 6);
- if (who == "me")
- {
- aviFollow = []+llListReplaceList(aviFollow, [(key)sendUid], idx, idx);
- }
- else
- {
- key w = getAgentByName(who);
- if (w != NULL_KEY)
- {
- aviFollow = []+llListReplaceList(aviFollow, [w], idx, idx);
- }
- }
- aviStatus = llListReplaceList(aviStatus, ["flyfollow"], idx, idx);
- osNpcSay(uNPC, "Flying ");
- }
- else if (cmd1 == "leave")
- {
- // Start wandering between waypoints
- osNpcStand(uNPC);
- aviNodes = []+llListReplaceList(aviNodes, [GetNearestNode(osNpcGetPos(uNPC))], idx, idx);
- aviStatus = []+llListReplaceList(aviStatus, ["wander"], idx, idx);
- aviPrevNodes = []+llListReplaceList(aviPrevNodes, [-1], idx, idx);
- }
- else if (cmd1 == "flyaround")
- {
- // Start flying about between the waypoints in the "flyTargets" list -- useful for birds
- aviStatus = []+llListReplaceList(aviStatus, ["godfly"], idx, idx);
- osNpcSay(uNPC, "Flying like an eagle!!");
- }
- else if (cmd1 == "run-notecard")
- {
- // Run the script contained in the notecard <argument>
- string stext= osGetNotecard(cmd2 );
- aviStatus= []+llListReplaceList(aviStatus, "", idx, idx);
- if (stext == "ERROR")
- {
- llOwnerSay("Notecard error "+cmd2);
- return 1;
- }
- aviScriptText = []+llListReplaceList(aviScriptText, stext, idx, idx);
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [1], idx, idx);
- SetScriptAlarm(idx, 0);
- }
- else if (cmd1 == "stop-script")
- {
- // Stop executing the script and exit
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [-1], idx, idx);
- SetScriptAlarm(idx, 0);
- }
- else if (cmd1 == "dress")
- {
- string suff = "";
- if (cmd2 != "") suff += "_"+cmd2;
- string nm = llList2String(aviNames, idx);
- llOwnerSay("Loading appearance "+"APP_"+nm+suff);
- osNpcLoadAppearance(uNPC, "APP_"+nm+suff);
- }
- else if (cmd1 == "touch")
- {
- osNpcTouch(uNPC, (key)cmd2, LINK_ROOT);
- }
- else if (cmd1 == "seen")
- {
- integer i;
- if (cmd2 == "all")
- {
- for (i=0; i < llGetListLength(seenArchive); i+=2)
- osNpcSay(uNPC, "I saw "+ llList2String(seenArchive,i) + " " + TimeAgo(llList2Integer(seenArchive,i+1) ));
- return 1;
- }
- else
- {
- for (i=0; i < llGetListLength(seenArchive); i+=2)
- {
- if (llSubStringIndex(llToLower(llList2String(seenArchive,i)), llToLower(cmd2))>=0)
- {
- osNpcSay(uNPC, "I saw "+ llList2String(seenArchive,i) + " around " + TimeAgo(llList2Integer(seenArchive,i+1) ));
- return 1;
- }
- }
- }
- osNpcSay(uNPC, "I haven't seen "+ cmd2 + " around");
- }
- else if (cmd1 == "nearest")
- {
- integer n = GetNearestNode(osNpcGetPos(uNPC));
- osNpcSay(uNPC, "Nearest waypoint is #"+n);
- }
- else if (llGetSubString(cmd1,0,0) == "@")
- return 0;
- else if (cmd1 != "")
- {
- {
- if (llGetInventoryType(cmd1+".scr") == INVENTORY_NOTECARD)
- {
- ExecScriptLine(npcName , "run-notecard "+cmd1+".scr");
- }
- else
- llMessageLinked(LINK_THIS, -1, inputString, uNPC);
- }
- }
- return 1; // 1 means that wait until next timer tick for next notecard command
- }
- integer FindNewTarget(integer curNode, integer prevNode)
- {
- integer total=llGetListLength(wLinks);
- candidateNode = [];
- integer i;
- integer a;
- integer b;
- for (i=0; i< total; i+=2)
- {
- a = llList2Integer(wLinks,i);
- b = llList2Integer(wLinks,i+1);
- if (a == curNode && prevNode != b) /// dont go back where we came from
- candidateNode += b;
- else if (b == curNode && prevNode !=a)
- candidateNode += a;
- }
- integer l = llGetListLength(candidateNode);
- if (l>0)
- {
- return llList2Integer(candidateNode, (integer)llFrand((float)l));
- }
- else
- return prevNode; // go back to where we came from if there is no other option
- }
- integer MoveToNewTarget(integer idx)
- {
- integer curNode = llList2Integer(aviNodes,idx);
- integer prevNode = llList2Integer(aviPrevNodes,idx);
- key uuid = llList2Key(aviUids, idx);
- if (uuid == NULL_KEY) return 1;
- vector pos = osNpcGetPos(uuid);
- osNpcStand(uuid);
- vector wp = llList2Vector(wNodes, curNode);
- float dist = llVecDist(pos, wp);
- if (dist>10) osTeleportAgent(uuid, wp, <1,1, 7.1>);
- integer nt = FindNewTarget(curNode, prevNode);
- if (nt <0) return 0;
- vector tgt = llList2Vector(wNodes, nt);
- // Try to stay in the right 'lane'
- vector rr = 0.5*llVecNorm(tgt - pos)*llEuler2Rot(<0,0,-PI/2>);
- tgt += rr;
- osSetSpeed(uuid, 1.0);
- osNpcMoveToTarget(uuid, tgt, OS_NPC_NO_FLY);
- SetScriptAlarm(idx, GetWalkTime( llVecDist(wp, tgt) )+4);
- aviNodes = []+llListReplaceList(aviNodes, [nt], idx, idx);
- aviPrevNodes = []+llListReplaceList(aviPrevNodes, [curNode], idx, idx);
- return 0;
- }
- integer ExecScriptLine(string aviName, string scriptline)
- {
- // The token list expects the name of the avi twice. we use 0000 as the sending-uid identifier
- string command = "! "+ (string)NULL_KEY +" " + aviName +" "+ aviName +" "+ scriptline;
- // list tokens = llParseString2List(command, [" "], [] );
- return ProcessNPCCommand(command);
- }
- string TimeAgo(integer time)
- {
- // time difference in seconds
- integer now = llGetUnixTime();
- integer timeDifference = now - time;
- // small bug fix for when timeDifference is 0
- if (timeDifference == 0)
- return "just now";
- list periods = ["second", "minute", "hour", "day", "week", "month", "year", "decade"];
- //the number equivalent to periods
- list lenghts = [1, 60, 3600, 86400, 604800, 2630880, 31570560, 315705600];
- integer v = llGetListLength(lenghts) - 1;
- integer no;
- while((0 <= v) && (no = timeDifference/llList2Integer(lenghts, v) <= 1)) --v;
- string output = llList2String(periods, v);
- //this will get the correct time in periods, then divide the timeDifference
- integer ntime = timeDifference / llList2Integer(lenghts, llListFindList(periods, [output]));
- //if integer 'no' is not equal to 1 then it should have an s at the end
- if(no != 1)
- output += "s";
- //This produces the finished output
- output = (string)ntime + " "+ output + " ago";
- return output;
- }
- giveCommands(integer n)
- {
- integer i;
- string lstr = "";
- string kstr = "";
- list lnks;
- for (i=0; i < llGetListLength(wayLinks); i+=2)
- {
- integer a = llList2Integer(wayLinks,i);
- integer b = llList2Integer(wayLinks,i+1);
- if (a == n)
- {
- lstr += (string)b+",";
- lnks += (string)llList2Key(wayKeys,b);
- }
- else if (b == n)
- {
- lstr += (string)a+",";
- lnks += (string)llList2Key(wayKeys,a);
- }
- }
- string wstr = (string)n+"|SETDATA|"+vec2str(llList2Vector(wayPoints, n));
- wstr += "|"+llList2String(wayNames, n)+"|"+lstr+"|0|"+llList2CSV(lnks);
- //llOwnerSay(wstr);
- llRegionSay(PEG_CHAN, wstr);
- }
- default
- {
- state_entry()
- {
- llSetText("NPCs", <1,1,1>,1.0);
- llListenRemove(gListener);
- gListener = llListen(channel, "", "", "");
- llOwnerSay("Listening on channel "+channel);
- ReloadConfig();
- LoadMapData();
- timerRuns=0;
- RescanAvis();
- greetedAvis = [];
- scriptVars = [];
- if (autoLoadOnReset)
- {
- llSleep(10);
- doLoadAll();
- llSleep(10); // Need to wait for their listeners attachments to start
- doInitCmds();
- llSleep(10);
- }
- llSetTimerEvent(TIMER_INTERVAL);
- }
- touch_start(integer num)
- {
- if (llDetectedKey(0) != llGetOwner()) return;
- llDialog(llGetOwner(), "Welcome", menuItems, channel);
- }
- // This checks the statuses of all avis and performs commands accordingly
- timer()
- {
- integer total = llGetListLength(aviUids);
- integer g;
- integer advanceScript;
- list startedScripts = [];
- if (curVisitors>0)
- for (g=0; g < total ; g++)
- {
- advanceScript =0;
- aviIndex = g;
- npc = llList2Key(aviUids, g);
- string status = llList2String(aviStatus, g);
- if (status == "follow" || status == "flyfollow")
- {
- // This NPC is following someone
- integer stat=llGetAgentInfo(npc);
- if (stat & AGENT_SITTING)
- {
- // We 've been sat. stop following
- return;
- }
- key who = llList2Key(aviFollow, g);
- list userData = llGetObjectDetails(who, [OBJECT_POS, OBJECT_ROT]);
- if (llGetListLength(userData) ==0)
- {
- // User left or died
- aviStatus= []+llListReplaceList(aviStatus, [ "" ], g, g);
- return;
- }
- rotation rot = llList2Rot(userData,1);
- float ang = llFrand(1.0);
- vector v = llList2Vector(userData,0) + <-1.9,0,0>*rot;
- float dist = llVecDist(osNpcGetPos(npc), v);
- if (status == "follow" && dist>50.)
- {
- osTeleportAgent(npc, v, <1,1,1>);
- }
- else if (dist>4)
- {
- //osNpcStopMoveToTarget(npc);
- if (osIsNpc(who))
- osSetSpeed(npc, .47);
- else osSetSpeed(npc, 1.0);
- if (status == "flyfollow")
- osNpcMoveToTarget(npc, v+<0,0,2.>, OS_NPC_FLY );
- else
- osNpcMoveToTarget(npc, v, OS_NPC_NO_FLY );
- }
- }
- else if (status == "wander")
- {
- if (llGetUnixTime() > llList2Integer(aviAlarm, g) +1)
- {
- integer curNode = llList2Integer(aviNodes, g);
- integer i;
- integer shouldMove =1;
- llMessageLinked(LINK_THIS, -1, "WAYPOINT " + (string)curNode+" "+llList2String(aviNames, g), npc);
- // avoid looping back to the same script while we are about to leave
- if (llList2Integer(aviPrevNodes, g)>=0)
- {
- if (llListFindList(startedScripts, curNode)>=0)
- {
- // dont start the same script simultaneously
- }
- else
- {
- string ncName = "_"+curNode+".scr";
- if (llGetInventoryType(ncName) == INVENTORY_NOTECARD)
- {
- startedScripts+= curNode;
- ExecScriptLine(llList2String(aviNames, g), "run-notecard "+ncName);
- shouldMove =0;
- }
- }
- }
- if (shouldMove>0)
- {
- MoveToNewTarget(g);
- }
- }
- }
- else if (status == "godfly")
- {
- // This NPC is flying around
- if (llGetUnixTime() > llList2Integer(aviAlarm, g) +1)
- {
- vector nd = (vector)llList2String(flyTargets, (integer)llFrand(llGetListLength(flyTargets)));
- integer flag = OS_NPC_FLY;
- osSetSpeed(npc, 0.5);
- integer theight = 10;
- vector p = osNpcGetPos(npc);
- SetScriptAlarm(g, GetWalkTime(llVecDist(p, nd))/2);
- osNpcMoveToTarget(npc, nd + <llFrand(1),llFrand(1),theight>, flag);
- }
- }
- else if (status == "pathf")
- {
- // Pathfinding - this NPC is following the path to a destination
- integer avits = llList2Integer(aviAlarm, g);
- if (llGetUnixTime() > avits)
- {
- vector p = osNpcGetPos(npc);
- string path = llList2String(aviPath, g);
- //llOwnerSay("Path="+path);
- list pnodes = llParseString2List(path, [":"], []);
- if (llGetListLength(pnodes)<1)
- {
- osNpcSay(npc, "Here we are");
- aviStatus = []+llListReplaceList(aviStatus, [ "" ], g, g);
- // continue the script (if any), since we reached our destination
- SetScriptAlarm(g, 0);
- }
- else
- {
- integer nextTgt = llList2Integer(pnodes, 0);
- string ndleft = ":"+llDumpList2String( llList2List(pnodes, 1, llGetListLength(pnodes)), ":");
- aviPath = []+llListReplaceList(aviPath, [ ndleft ], g, g);
- vector v = llList2Vector(wNodes, nextTgt);
- SetScriptAlarm(g, GetWalkTime(llVecDist(p, v)));
- osNpcMoveToTarget(npc, v + <llFrand(1.0),llFrand(1.0), 0.1> , OS_NPC_NO_FLY );
- }
- }
- return;
- }
- else if (status == "prompt")
- {
- // do nothing
- jump nexttick;
- }
- // Execute the next script line if a script is active
- integer stopNow=0;
- integer k;
- integer scriptIndex = llList2Integer(aviScriptIndex, g);
- while ( scriptIndex>0 && stopNow==0 && k++<5) // execute up to 10 lines at once if possible
- {
- //llOwnerSay("scriptIndex = "+ (string)scriptIndex);
- integer tsAlarm = llList2Integer(aviAlarm, g);
- if (tsAlarm >0 && llGetUnixTime() >= tsAlarm ) // The script should continue now
- {
- string scriptData = llList2String(aviScriptText, g);
- string scriptline = GetScriptLine(scriptData, scriptIndex);
- if (scriptline == "") // End of script
- {
- // This will prevent any further execution
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [-1], g, g);
- }
- else
- {
- // Substitute sender with the prompt target, if any
- string cmd = "! "+ (string)llList2Key(aviTarget, g) +" "+ llList2String(aviNames, g) +" "+ llList2String(aviNames, g) + " "+ scriptline;
- stopNow = ProcessNPCCommand(cmd);
- // Advance script pointer
- scriptIndex = llList2Integer(aviScriptIndex, g);
- aviScriptIndex = []+llListReplaceList(aviScriptIndex, [scriptIndex+1], g,g);
- }
- }
- scriptIndex = llList2Integer(aviScriptIndex, g);
- }
- @nexttick;
- llParticleSystem(
- [
- PSYS_SRC_PATTERN,PSYS_SRC_PATTERN_EXPLODE,
- PSYS_SRC_BURST_RADIUS,0,
- PSYS_SRC_ANGLE_BEGIN,0,
- PSYS_SRC_ANGLE_END,0,
- PSYS_SRC_TARGET_KEY,llGetKey(),
- PSYS_PART_START_COLOR,<1.000000,0.000000,0.000000>,
- PSYS_PART_END_COLOR,<1.000000,0.000000,0.000000>,
- PSYS_PART_START_ALPHA,1,
- PSYS_PART_END_ALPHA,0,
- PSYS_PART_START_GLOW,0,
- PSYS_PART_END_GLOW,0,
- PSYS_PART_BLEND_FUNC_SOURCE,PSYS_PART_BF_SOURCE_ALPHA,
- PSYS_PART_BLEND_FUNC_DEST,PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA,
- PSYS_PART_START_SCALE,<0.500000,0.500000,0.000000>,
- PSYS_PART_END_SCALE,<4.000000,4.000000,0.000000>,
- PSYS_SRC_TEXTURE,"",
- PSYS_SRC_MAX_AGE,0.5,
- PSYS_PART_MAX_AGE,2,
- PSYS_SRC_BURST_RATE,1,
- PSYS_SRC_BURST_PART_COUNT,1,
- PSYS_SRC_ACCEL,<0.000000,0.000000,0.000000>,
- PSYS_SRC_OMEGA,<0.000000,0.000000,0.000000>,
- PSYS_SRC_BURST_SPEED_MIN,0,
- PSYS_SRC_BURST_SPEED_MAX,0,
- PSYS_PART_FLAGS,
- 0 |
- PSYS_PART_EMISSIVE_MASK |
- PSYS_PART_INTERP_COLOR_MASK |
- PSYS_PART_INTERP_SCALE_MASK
- ]);
- }
- timerRuns++;
- if (timerRuns%20==0)
- {
- curVisitors = countVisitors();
- }
- }
- listen(integer chan, string name, key id, string str) { // WARNING "id" is not the uid of the NPC-sender
- string mes = str;
- integer x = llSubStringIndex(str, " ");
- if (x >=0) mes = llGetSubString(str, 0,x-1);
- if (!(osIsNpc(llGetOwnerKey(id)) || llGetOwnerKey(id)==llGetOwner()))
- {
- llOwnerSay("Denied access to "+llKey2Name(id));
- return;
- }
- //llOwnerSay("<<" + str);
- if (mes == "!") // Something that has been sent from a Listener of attached to an NPC
- {
- ProcessNPCCommand(str);
- return;
- }
- else if (mes =="FBALL")
- {
- // A poseball has been found. We have to check if it is transparent. If it is not, then we sit the NPC on it
- list tok = llParseString2List(str, [" "] , [""]);
- string npcname= llList2String( tok, 1);
- integer idx = GetNPCIndex(npcname);
- if (idx<0) return;
- key unpc = llList2Key(aviUids, idx);
- integer i;
- key ball;
- for (i=2; i < llGetListLength(tok);i++)
- {
- ball = llList2String(tok, i);
- list prop = osGetPrimitiveParams(ball, [PRIM_COLOR, 0]); /// This only works we own the poseball
- float alpha = 1.0;
- if (llGetListLength(prop)>0) alpha = llList2Float(prop, 1);
- if (alpha >0)
- {
- jump ballFound;
- }
- }
- //llOwnerSay(npcname + ": All balls transparent");
- @ballFound;
- if (ball != NULL_KEY)
- {
- osNpcStand(unpc);
- osNpcStopMoveToTarget(unpc);
- osNpcSit(unpc, ball, OS_NPC_SIT_NOW);
- aviStatus = []+llListReplaceList(aviStatus, ["sitting"], idx, idx);
- }
- }
- else if (mes == "SETVAR")
- {
- list tok = llParseString2List(str, [" "] , [""]);
- setVar(llList2String(tok,1), llList2String(tok,2));
- }
- else if (llGetSubString(mes, 0, 7) == "CLICKED|")// Message from map editor HUD
- {
- list ll = llParseString2List(str, ["|"] ,[]);
- string cmd1 = llList2String(ll, 0);
- integer num = llList2Integer(ll, 1);
- if (curPoint!= num)
- {
- prevPoint = curPoint;
- curPoint = num;
- }
- list btns = ["Close", "LinkPegs", "UnlinkPegs", "SetName"];
- llDialog(llGetOwner(), "Current peg: "+ (string)curPoint+ " Previous: "+(string)prevPoint, btns, channel);
- return;
- }
- else if (llGetSubString(mes, 0, 6) == "MRKKEY|")
- {
- list ll = llParseStringKeepNulls(str, ["|"] ,[]);
- integer num = llList2Integer(ll, 1);
- key k = llList2Key(ll, 2);
- wayKeys = [] + llListReplaceList(wayKeys, [k], num,num);
- }
- else if (llGetSubString(mes, 0, 6) == "MARKER|")
- {
- list ll = llParseStringKeepNulls(str, ["|"] ,[]);
- string cmd1 = llList2String(ll, 0);
- integer num = llList2Integer(ll, 1);
- vector pos = llList2Vector(ll, 2);
- key tk = llList2Key(ll, 4);
- wayPoints = llListReplaceList(wayPoints, [pos], num,num);
- return;
- }
- else if (mes == "ShowPegDialog")
- {
- list btns = ["Close", "RezPegs", "SaveCards", "AddPeg", "DeletePeg", "LinkPegs", "UnlinkPegs", "ScanPegs", "ClearPegs", "SetName"];
- llDialog(llGetOwner(), "First peg: "+ (string)curPoint+ " Second peg: "+(string)prevPoint, btns, 68);
- return;
- }
- if (id != llGetOwner()) return; // Admin commands follow
- if (mes == "SaveNPC")
- {
- llDialog(llGetOwner(), "Select NPC to save your appearance", llList2List(availableNames, 0,10)+ "more", channel);
- userInputState = "WAIT_APPNAME";
- }
- else if (mes == "LoadNPC")
- {
- llDialog(llGetOwner(), "Select an NPC to load", llList2List(availableNames, 0,10)+"more", channel);
- userInputState = "WAIT_AVINAME";
- }
- else if (mes == "RemoveNPC")
- {
- llDialog(llGetOwner(), "Select an NPC to delete", llList2List(availableNames, 0,10)+ "more", channel);
- userInputState = "WAIT_REMOVEAVI";
- }
- else if (mes == "UpdateNPC")
- {
- llDialog(llGetOwner(), "Select an NPC to re-save appearance ", llList2List(availableNames, 0,10)+"more", channel);
- userInputState = "WAIT_UPDATE";
- }
- else if (mes == "RemoveAll")
- {
- avis = osGetAvatarList();
- llSay(0, llList2CSV(avis));
- howmany = llGetListLength(avis);
- integer i;
- for (i =0; i < howmany; i+=3)
- {
- if (osIsNpc(llList2Key(avis, i)))
- {
- list p = llParseString2List(llKey2Name(llList2Key(avis,i)), [" "], []);
- doRemoveNpc(llList2String(p, 0));
- //osNpcStand(llList2Key(avis, i));
- //osNpcRemove(llList2Key(avis, i));
- }
- }
- aviUids = [];
- aviNames = [];
- }
- else if (mes == "LoadAll")
- {
- llSetTimerEvent(0);
- doLoadAll();
- llSetTimerEvent(TIMER_INTERVAL);
- }
- else if (mes == "InitCmds")
- {
- llSetTimerEvent(0);
- doInitCmds();
- llSetTimerEvent(TIMER_INTERVAL);
- }
- else if (mes == "TimerOnOff")
- {
- timerRunning = !timerRunning;
- llSetTimerEvent(TIMER_INTERVAL*timerRunning);
- llOwnerSay("Timer="+(string)timerRunning);
- }
- else if (mes == "DumpData")
- {
- llOwnerSay("Names="+llList2CSV(aviNames));
- llOwnerSay("Status="+llList2CSV(aviStatus));
- llOwnerSay("Nodes="+llList2CSV(aviNodes));
- llOwnerSay("PrevNodes="+llList2CSV(aviPrevNodes));
- llOwnerSay("ScriptIndex="+llList2CSV(aviScriptIndex));
- llOwnerSay("Alarm="+llList2CSV(aviAlarm));
- llOwnerSay("Curvisitors="+(string)(curVisitors)+ " Timer=" +timerRunning+" timerRuns="+(string)timerRuns);
- llOwnerSay("Vars="+llList2CSV(scriptVars));
- }
- else if (mes == "ReConfig")
- {
- ReloadConfig();
- LoadMapData();
- }
- else if (mes == "deflectTo")
- {
- list tok = llParseString2List(str, [" "] , [""]);
- deflectToNode = GetNodeIndexByName(llToLower(llList2String(tok,1)));
- llOwnerSay("Deflecting to #"+(string)deflectToNode);
- }
- else if (mes == "AddPeg")
- {
- vector v = llGetPos();
- list res = llGetObjectDetails(llGetOwner(), [OBJECT_POS]);
- wayPoints += llList2Vector(res, 0);
- llOwnerSay("Added point " + (string)(llGetListLength(wayPoints)));
- llRezObject("peg", v, ZERO_VECTOR, ZERO_ROTATION, llGetListLength(wayPoints)-1);
- giveCommands( llGetListLength(wayPoints)-1);
- return;
- }
- else if (mes == "LinkPegs")
- {
- integer i;
- for (i=0; i < llGetListLength(wayLinks); i+=2)
- {
- integer a = llList2Integer(wayLinks,i);
- integer b = llList2Integer(wayLinks,i+1);
- if ((a == curPoint && b == prevPoint ) || (b == curPoint && a== prevPoint ))
- {
- llOwnerSay("Link exists");
- return;
- }
- }
- wayLinks += curPoint;
- wayLinks += prevPoint;
- giveCommands(curPoint);
- giveCommands(prevPoint);
- }
- else if (mes == "UnlinkPegs")
- {
- integer i;
- for (i=0; i < llGetListLength(wayLinks); i+=2)
- {
- integer a = llList2Integer(wayLinks,i);
- integer b = llList2Integer(wayLinks,i+1);
- if ((a == curPoint && b == prevPoint ) || (b == curPoint && a== prevPoint ))
- {
- wayLinks = llListReplaceList(wayLinks, [], i, i+1);
- giveCommands(a);
- giveCommands(b);
- }
- }
- }
- else if (mes == "ClearPegs")
- {
- llRegionSay(PEG_CHAN, "die");
- }
- else if (mes == "ScanPegs")
- {
- llOwnerSay("Scanning pegs ordered");
- llRegionSay(PEG_CHAN, "REPORT");
- }
- else if (mes == "SetName")
- {
- llTextBox(llGetOwner(), "Set Peg #"+(string)curPoint + " name to: ", channel);
- userInputState="WAIT_PEGNAME";
- }
- else if (mes == "RezPegs")
- {
- list lines = llParseString2List(osGetNotecard("__waypoints"), ["\n"], []);
- integer i;
- wayPoints =[];
- wayNames = [];
- for (i=0; i < llGetListLength(lines); i++)
- {
- list line = llParseString2List(llList2String(lines, i), [","], []);
- vector v = < llList2Float(line, 0), llList2Float(line, 1), llList2Float(line, 2) >;
- string nname = llList2String(line, 3);
- if (v != ZERO_VECTOR)
- {
- wayPoints += v;
- wayNames += nname;
- }
- }
- wayLinks = llParseString2List( llStringTrim(osGetNotecard("__links"), STRING_TRIM) , ["\n", ","], [" "]);
- llOwnerSay(llList2CSV(wayLinks));
- llRegionSay(PEG_CHAN, "die");
- llSleep(0.5);
- vector pos = llGetPos();
- for (i=0; i < llGetListLength(wayPoints); i++)
- llRezObject("peg", pos, ZERO_VECTOR, ZERO_ROTATION, i);
- llSleep(0.5);
- for (i=0; i < llGetListLength(wayPoints); i++)
- giveCommands(i);
- }
- else if (mes == "UpdatePegs")
- {
- integer i;
- for (i=0; i < llGetListLength(wayPoints); i++)
- giveCommands(i);
- }
- else if (mes == "SaveCards")
- {
- integer i=0;
- string scriptText = "";
- if (llGetListLength(wayLinks)==0)
- {
- llOwnerSay("No links created! Not saving cards!");
- return;
- }
- for (i=0; i < llGetListLength(wayPoints); i++)
- {
- vector v = llList2Vector(wayPoints,i);
- scriptText += (string)v.x+","+(string)v.y+","+(string)v.z + "," + llList2String(wayNames, i) + "\n";
- }
- string cardName = "__waypoints";
- if (llGetInventoryType(cardName)==INVENTORY_NOTECARD)
- {
- llRemoveInventory(cardName);
- llSleep(0.5);
- }
- osMakeNotecard(cardName,scriptText);
- llOwnerSay(cardName +" Saved");
- cardName = "__links";
- if (llGetInventoryType(cardName)==INVENTORY_NOTECARD)
- {
- llRemoveInventory(cardName);
- llSleep(0.5);
- }
- scriptText = "";
- for (i=0; i < llGetListLength(wayLinks); i+=2)
- scriptText += llList2String(wayLinks,i)+ ","+llList2String(wayLinks,i+1)+ ",\n";
- osMakeNotecard(cardName,scriptText);
- llOwnerSay(cardName +" Saved");
- llSleep(1);
- LoadMapData();
- }
- else if (userInputState != "" && mes != "")// Process dialog commands
- {
- if (mes == "more")
- {
- llDialog(llGetOwner(), "Select an NPC", llList2List(availableNames, 11,-1), channel);
- }
- else
- {
- if (userInputState == "WAIT_APPNAME")
- {
- osAgentSaveAppearance(llGetOwner(), "APP_"+llToLower(mes));
- llSay(0, "Saved Appearance " + llGetOwner() + " -> APP_"+llToLower(mes));
- }
- else if (userInputState == "WAIT_PEGNAME")
- {
- wayNames = [] + llListReplaceList(wayNames, [llStringTrim(mes, STRING_TRIM)],curPoint, curPoint);
- giveCommands(curPoint);
- llOwnerSay("Waypoint " +(string)curPoint+ " name='"+mes+"'");
- }
- else if (userInputState == "WAIT_AVINAME")
- {
- doLoadNPC(mes, GetLastName(mes));
- }
- else if (userInputState == "WAIT_UPDATE")
- {
- integer idx = GetNPCIndex(mes);
- if (idx >=0)
- {
- key uu = llList2Key(aviUids, idx);
- osNpcSaveAppearance(uu, "APP_"+llToLower(mes));
- llOwnerSay("Updating APP_"+llToLower(mes) );
- }
- else llOwnerSay("Not found "+mes);
- }
- else if (userInputState == "WAIT_REMOVEAVI")
- {
- doRemoveNpc(mes);
- }
- userInputState="";
- }
- }
- }
- link_message(integer lnk, integer num, string command, key npc) // This script is in the object too.
- {
- if (num != -1) // -1 means we sent it
- {
- ProcessNPCCommand(command);
- }
- }
- changed(integer change)
- {
- if (change & (CHANGED_REGION_START | CHANGED_OWNER | CHANGED_REGION))
- {
- llResetScript();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement