//=================== //Version: 0.1.7.2 //Datum: 07.08.2021 //Made by: Chris Resident @ inc.li:8002 //Dependencies: // - https://github.com/Sahrea/Chris.OS.Additions //Bescheibung: // Create and controll a hord of npc at once. // Read the readme at https://clatza.dev/Christopher/OpenSim.Script.Chris.MultiNPC/src/branch/master/README.md //=================== list m_npcdata = []; readNPCPathNC(string ncName) { string nc = osStringReplace(osGetNotecard(ncName), "\n", ""); integer npcslot = getNextFreeNPCSlot(); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + npcslot, NULL_KEY); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + npcslot + ".path", nc); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + npcslot + ".ncname", ncName); } integer getNextFreeNPCSlot() { integer currentNPCSlot = 0; for (currentNPCSlot = 0; currentNPCSlot < llGetListLength(m_npcdata); currentNPCSlot++) { if(!checkDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot)) return currentNPCSlot; } return 0; } readAllNPCPathNC() { list fullInventoryItemList = osGetInventoryList(); integer fullInventoryItemListCount = llGetListLength(fullInventoryItemList); while(fullInventoryItemListCount--) { string itemElementName = llList2String(fullInventoryItemList, fullInventoryItemListCount); if(osStringEndsWith(llToLower(itemElementName), ".path", 1)) readNPCPathNC(itemElementName); } } createNPCTempStorage() { list npcKeys = []; integer currentNPCSlot = 0; for (currentNPCSlot = 0; currentNPCSlot < llGetListLength(m_npcdata); currentNPCSlot++) { key currentNPCKey = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot); npcKeys += [currentNPCKey]; } osSetPrivateDataValue("tmpNPCList." + llGetKey(), llList2CSV(npcKeys)); } removeOldNPC() { list npcdata = llCSV2List(osGetPrivateDataValue("tmpNPCList." + llGetKey())); integer count = llGetListLength(npcdata); while(count--)osNpcRemove(llList2Key(npcdata, count)); } hardReset(string message) { if(message != "") llSay(0, "Hard reset: " + message); llSetTimerEvent(0); integer dataListCount = llGetListLength(m_npcdata); while(dataListCount--) if(checkDataEntryInDataList(m_npcdata, "npc." + dataListCount)) osNpcRemove((key)getDataEntryFromDataList(m_npcdata, "npc." + dataListCount)); llResetScript(); } integer getGoToLine(integer slot, string target) { integer currentLine = 0; string currentPath = getDataEntryFromDataList(m_npcdata, "npc." + slot + ".path"); list pathLineData = llParseString2List(currentPath, [";"], []); for (currentLine = 0; currentLine < llGetListLength(pathLineData); currentLine++) { string line = llList2String(pathLineData, currentLine); if(line == target) return currentLine + 1; } return 0; } list replaceVars(integer slot, list commands) { return commands; } //Script Engine doNextScriptStep() { integer currentNPCSlot = -1; @continue; currentNPCSlot++; if(currentNPCSlot > llGetListLength(m_npcdata)) return; if(!checkDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot)) jump continue; key currentNPCKey = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot); integer currentLine = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".line"); string currentPath = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".path"); string currentState = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".state"); string currentncname = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".ncname"); vector lastPosition = (vector)getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".lastPos"); integer currentStuck = (integer)getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".stuckCounter"); list pathLineData = llParseString2List(currentPath, [";"], []); string currentCommand = llList2String(pathLineData, currentLine); list lineCommandData = llParseString2List(currentCommand, ["=", "|"], []); list lineCommands = llParseString2List(currentCommand, [" "], []); list currentNPCDataList = llGetObjectDetails(currentNPCKey, [OBJECT_POS]); vector currentNPCPosition = llList2Vector(currentNPCDataList, 0); //llOwnerSay(llKey2Name(currentNPCKey) + ": Current " + currentNPCPosition + "; Last " + lastPosition + "; " + llVecDist(currentNPCPosition, lastPosition)); if(currentState == "wait") { integer waitTime = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".waittime"); if(llGetUnixTime() < waitTime) jump continue; m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".state", ""); } if(currentState == "path") { key targetKey = llList2Key(llCSV2List(getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".walkPath")), 0); vector targetPosition = llList2Vector(llGetObjectDetails(targetKey, [OBJECT_POS]), 0); if(llGetListLength(currentNPCDataList) == 0) hardReset("target `"+targetKey+"` not found"); if(llVecDist(currentNPCPosition, lastPosition) <= 0.1) { currentStuck++; if(currentStuck >= 5) { osTeleportAgent(currentNPCKey, targetPosition, <0, 0, 0>); currentStuck = 0; } }else{ currentStuck = 0; } m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".lastPos", currentNPCPosition); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".stuckCounter", currentStuck); if(llVecDist(currentNPCPosition, targetPosition) <= 1) { list newPathList = llDeleteSubList(llCSV2List(getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".walkPath")), 0, 0); if(llGetListLength(newPathList) == 0) { m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".state", ""); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".walkPath", ""); }else{ m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".walkPath", llList2CSV(newPathList)); targetKey = llList2Key(llCSV2List(getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".walkPath")), 0); targetPosition = llList2Vector(llGetObjectDetails(targetKey, [OBJECT_POS]), 0); osNpcMoveToTarget(currentNPCKey, targetPosition, OS_NPC_NO_FLY); } } jump continue; } if(currentState == "walk") { vector targetPosition = (vector)getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".targetPosition"); if(llGetListLength(currentNPCDataList) == 0) hardReset("NPC not found"); if(llVecDist(currentNPCPosition, lastPosition) <= 0.1) { currentStuck++; if(currentStuck >= 5) osTeleportAgent(currentNPCKey, targetPosition, <0, 0, 0>); }else{ currentStuck = 0; } m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".lastPos", currentNPCPosition); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".stuckCounter", currentStuck); if(llVecDist(currentNPCPosition, targetPosition) >= 1) jump continue; m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".state", ""); } currentLine = currentLine + 1; if(currentLine >= llGetListLength(pathLineData)) { currentLine = 0; } m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".line", currentLine); if(llGetSubString(llList2String(lineCommandData, 0), 0, 0) == ":") { currentNPCSlot--; jump continue; } if(llGetSubString(llList2String(lineCommandData, 0), 0, 0) == "%") { string storageKey = llMD5String(llList2String(lineCommandData, 0), 0); string data = lineCommandData; m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".data." + storageKey, data); jump continue; } if(llList2String(lineCommandData, 0) == "create") if(!script_create(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "remove") if(!script_remove(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "say") if(!script_say(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "sit") if(!script_sit(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "wait") if(!script_wait(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "stand") if(!script_stand(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "walk") if(!script_walk(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "path") if(!script_path(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "fly") if(!script_fly(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "include") if(!script_include(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "touch") if(!script_touch(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "goto") if(!script_goto(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "appearance") if(!script_appearance(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "animation") if(!script_animation(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "stopAnimation") if(!script_StopAnimation(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "profileImage") if(!script_profileImage(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "profileText") if(!script_profileText(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "give") if(!script_give(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); if(llList2String(lineCommandData, 0) == "rez") if(!script_rez(currentNPCSlot, currentNPCKey, replaceVars(currentNPCSlot, lineCommandData))) llSay(0, "Script execution in `" + llList2String(lineCommandData, 0) + "` in nc `"+ currentncname +"` on line `" + currentLine + "` failed."); } //Script commands integer script_create(integer slot, key npc, list command) { if(npc != NULL_KEY) osNpcRemove(npc); list objects = osGetSearchableObjectPartList(llList2String(command, 4)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the position for an object with the name `" + llList2String(command, 4) + "`."); return FALSE; } if(llGetInventoryType(llList2String(command, 3) + ".appearance") != INVENTORY_NOTECARD) { llSay(0, "Cant find appearance `" + llList2String(command, 3) + "`."); return FALSE; } npc = osNpcCreate(llList2String(command, 1), llList2String(command, 2), llList2Vector(llGetObjectDetails(llList2Key(objects, 0), [OBJECT_POS]), 0), llList2String(command, 3) + ".appearance", OS_NPC_CREATOR_OWNED); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot, npc); createNPCTempStorage(); return TRUE; } integer script_remove(integer slot, key npc, list command) { if(npc != NULL_KEY) osNpcRemove(npc); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot, NULL_KEY); return TRUE; } integer script_say(integer slot, key npc, list command) { osNpcSay(npc, 0, llList2String(command, 1)); return TRUE; } integer script_rez(integer slot, key npc, list command) { vector targetPosition = <0, 0, 0>; vector currentPosition = llGetPos(); if(llList2Vector(command, 1) == <0, 0, 0>) { list objects = osGetSearchableObjectPartList(llList2String(command, 1)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the walk target `" + llList2String(command, 1) + "`."); return FALSE; } list targetDataList = llGetObjectDetails(llList2Key(objects, 0), [OBJECT_POS]); targetPosition = llList2Vector(targetDataList, 0); }else{ targetPosition = llList2Vector(command, 1); } if(llGetInventoryType(llList2String(command, 1)) != INVENTORY_OBJECT) { llSay(0, "Cant find object `" + llList2String(command, 1) + "` to rez."); return FALSE; } llSetRegionPos(targetPosition); llRezAtRoot(llList2String(command, 1), targetPosition, llGetVel(), llGetRot(), 0); llSetRegionPos(currentPosition); return TRUE; } integer script_give(integer slot, key npc, list command) { if(llGetInventoryType(llList2String(command, 1)) != INVENTORY_ALL) { llSay(0, "Cant find `" + llList2String(command, 1) + "` to give."); return FALSE; } llGiveInventory(llList2String(command, 0), llList2String(command, 1)); return TRUE; } integer script_sit(integer slot, key npc, list command) { list objects = osGetSearchableObjectPartList(llList2String(command, 1)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the sit target `" + llList2String(command, 1) + "`."); return FALSE; } osNpcSit(npc, llList2Key(objects, 0), OS_NPC_SIT_NOW); return TRUE; } integer script_stand(integer slot, key npc, list command) { osNpcStand(npc); return TRUE; } integer script_wait(integer slot, key npc, list command) { m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".state", "wait"); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".waittime", llGetUnixTime() + (integer)llList2String(command, 1)); return TRUE; } integer script_path(integer slot, key npc, list command) { key startNode = NULL_KEY; key endNode = NULL_KEY; list nodes = []; if(llGetListLength(command) >= 3) { list objects = osGetSearchableObjectPartList(llList2String(command, 1)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the path start `" + llList2String(command, 1) + "`."); return FALSE; } objects = osGetSearchableObjectPartList(llList2String(command, 2)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the path target `" + llList2String(command, 1) + "`."); return FALSE; } startNode = llList2Key(osGetSearchableObjectPartList(llList2String(command, 1)), 0); endNode = llList2Key(osGetSearchableObjectPartList(llList2String(command, 2)), 0); }else{ list objects = osGetSearchableObjectPartList(llList2String(command, 1)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the path target `" + llList2String(command, 1) + "`."); return FALSE; } list targetDataList = llGetObjectDetails(npc, [OBJECT_POS]); vector startPosition = llList2Vector(targetDataList, 0); startNode = osGetNextNode(startPosition); endNode = llList2Key(osGetSearchableObjectPartList(llList2String(command, 1)), 0); } nodes = osGetNodeListToTarget(startNode, endNode); list targetDataList = llGetObjectDetails(startNode, [OBJECT_POS]); vector targetPosition = llList2Vector(targetDataList, 0); osNpcMoveToTarget(npc, targetPosition, OS_NPC_NO_FLY); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".state", "path"); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".walkPath", llList2CSV(nodes)); return TRUE; } integer script_walk(integer slot, key npc, list command) { vector targetPosition = <0, 0, 0>; if(llList2Vector(command, 1) == <0, 0, 0>) { list objects = osGetSearchableObjectPartList(llList2String(command, 1)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the walk target `" + llList2String(command, 1) + "`."); return FALSE; } list targetDataList = llGetObjectDetails(llList2Key(objects, 0), [OBJECT_POS]); targetPosition = llList2Vector(targetDataList, 0); }else{ targetPosition = llList2Vector(command, 1); } osNpcMoveToTarget(npc, targetPosition, OS_NPC_NO_FLY); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".state", "walk"); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".targetPosition", targetPosition); return TRUE; } integer script_fly(integer slot, key npc, list command) { vector targetPosition = <0, 0, 0>; if(llList2Vector(command, 1) == <0, 0, 0>) { list objects = osGetSearchableObjectPartList(llList2String(command, 1)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the fly target `" + llList2String(command, 1) + "`."); return FALSE; } list targetDataList = llGetObjectDetails(llList2Key(objects, 0), [OBJECT_POS]); targetPosition = llList2Vector(targetDataList, 0); }else{ targetPosition = llList2Vector(command, 1); } osNpcMoveToTarget(npc, targetPosition, OS_NPC_FLY | OS_NPC_LAND_AT_TARGET ); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".state", "walk"); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".targetPosition", targetPosition); return TRUE; } integer script_touch(integer slot, key npc, list command) { list objects = osGetSearchableObjectPartList(llList2String(command, 1)); if(llGetListLength(objects) == 0) { llSay(0, "Cant find the touch target `" + llList2String(command, 1) + "`."); return FALSE; } osNpcTouch(npc, llList2Key(objects, 0), LINK_THIS); return TRUE; } integer script_goto(integer slot, key npc, list command) { integer targetLine = (integer)llList2String(command, 1); if(targetLine == 0) { targetLine = getGoToLine(slot, ":" + llList2String(command, 1)); } if(targetLine == 0) { llSay(0, "Cant find the GoTo Target `" + llList2String(command, 1) + "`."); return FALSE; } m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".line", targetLine - 1); return TRUE; } integer script_appearance(integer slot, key npc, list command) { if(llGetInventoryType(llList2String(command, 1) + ".appearance") != INVENTORY_NOTECARD) { llSay(0, "Cant find appearance `" + llList2String(command, 1) + "`."); return FALSE; } osNpcLoadAppearance(npc, llList2String(command, 1) + ".appearance"); return TRUE; } integer script_animation(integer slot, key npc, list command) { if(llGetInventoryType(llList2String(command, 1)) != INVENTORY_ANIMATION) { llSay(0, "Cant find animation `" + llList2String(command, 1) + "`."); return FALSE; } osNpcPlayAnimation(npc, llList2String(command, 1)); return TRUE; } integer script_StopAnimation(integer slot, key npc, list command) { if(llGetInventoryType(llList2String(command, 1)) != INVENTORY_ANIMATION) { llSay(0, "Cant find animation `" + llList2String(command, 1) + "`."); return FALSE; } osNpcStopAnimation(npc, llList2String(command, 1)); return TRUE; } integer script_profileImage(integer slot, key npc, list command) { if(llGetInventoryType(llList2String(command, 1)) != INVENTORY_TEXTURE) { llSay(0, "Cant find image `" + llList2String(command, 1) + "`."); return FALSE; } osNpcSetProfileImage(npc, llList2String(command, 1)); return TRUE; } integer script_profileText(integer slot, key npc, list command) { osNpcSetProfileAbout(npc, llList2String(command, 1)); return TRUE; } integer script_include(integer slot, key npc, list command) { if(llGetInventoryType(llList2String(command, 1) + ".path") != INVENTORY_NOTECARD) { llSay(0, "Cant find path `" + llList2String(command, 1) + "`."); return FALSE; } integer newLine = llList2Integer(command, 2); string newnc = osStringReplace(osGetNotecard(llList2String(command, 1) + ".path"), "\n", ""); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".path", newnc); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".line", newLine); m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".ncname", llList2String(command, 1) + ".path"); return TRUE; } //Generic Helpers integer getRealAgentCount() { list users = llGetAgentList(AGENT_LIST_EXCLUDENPC, []); return llGetListLength(users); } integer checkDataEntryInDataList(list _dataList, string _key) { integer _inListPosition = llListFindList(_dataList, [_key]); if(_inListPosition == -1)return FALSE; return TRUE; } string getDataEntryFromDataList(list _dataList, string _key) { integer _inListPosition = llListFindList(_dataList, [_key]); if(_inListPosition == -1)return ""; return llList2String(_dataList, _inListPosition + 1); } list setDataEntryInDataList(list _dataList, string _key, string _value) { integer _inListPosition = llListFindList(_dataList, [_key]); if(_inListPosition == -1){ _dataList += [_key, _value]; return _dataList; } return llListReplaceList(_dataList, [_value], _inListPosition + 1, _inListPosition + 1); } default { state_entry() { removeOldNPC(); readAllNPCPathNC(); state waitingForPlayers; } } state waitingForPlayers { state_entry() { llSetTimerEvent(0.1); } timer() { llSetTimerEvent(2); if(getRealAgentCount() != 0) state running; } } state running { state_entry() { llSetTimerEvent(0.3); } touch_start(integer i) { if(llDetectedKey(0) != llGetOwner()) return; osEasyDialog(llDetectedKey(0), "", ["Stop all", "Restart", "Start all"]); } listen( integer channel, string name, key id, string message) { if(message == "Stop all") { llSetTimerEvent(0); } if(message == "Start all") { llSetTimerEvent(0.3); } if(message == "Restart") { hardReset(""); } } timer() { if(getRealAgentCount() == 0) hardReset("region empty"); doNextScriptStep(); } changed(integer change) { if (change & CHANGED_INVENTORY) hardReset(""); if (change & CHANGED_REGION_START) hardReset(""); } on_rez(integer start_param) { hardReset(""); } }