From c248416be283495c2763b88338090f24c27bd0a7 Mon Sep 17 00:00:00 2001 From: Christopher Date: Sat, 7 Aug 2021 22:45:13 +0200 Subject: [PATCH] add X engine version and examples --- Chris.MultiNPC.X.lsl | 753 +++++++++++++++++++++++++++++++++ Chris.MultiNPC.lsl | 3 +- Examples/DemoArea.txt | 5 + Examples/Farmer.txt | 9 + Test.path => Examples/Test.txt | 0 Examples/Wanderer.txt | 14 + 6 files changed, 782 insertions(+), 2 deletions(-) create mode 100644 Chris.MultiNPC.X.lsl create mode 100644 Examples/DemoArea.txt create mode 100644 Examples/Farmer.txt rename Test.path => Examples/Test.txt (100%) create mode 100644 Examples/Wanderer.txt diff --git a/Chris.MultiNPC.X.lsl b/Chris.MultiNPC.X.lsl new file mode 100644 index 0000000..43ff7f2 --- /dev/null +++ b/Chris.MultiNPC.X.lsl @@ -0,0 +1,753 @@ +//=================== +//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(""); + } +} \ No newline at end of file diff --git a/Chris.MultiNPC.lsl b/Chris.MultiNPC.lsl index af4c4ab..8772a19 100644 --- a/Chris.MultiNPC.lsl +++ b/Chris.MultiNPC.lsl @@ -2,9 +2,8 @@ yoptions; //=================== -//Version: 0.1.7.1 +//Version: 0.1.7.2 //Datum: 07.08.2021 -//UpdateRAW: https://clatza.dev/Christopher/OpenSim.Script.Chris.MultiNPC/raw/branch/master/Chris.MultiNPC.lsl //Made by: Chris Resident @ inc.li:8002 //Dependencies: // - https://github.com/Sahrea/Chris.OS.Additions diff --git a/Examples/DemoArea.txt b/Examples/DemoArea.txt new file mode 100644 index 0000000..1a07e46 --- /dev/null +++ b/Examples/DemoArea.txt @@ -0,0 +1,5 @@ +create=Node|Test|Chris|NPC.Demo.PathNode.1; +:restart; +path=NPC.Demo.PathNode.6; +path=NPC.Demo.PathNode.1; +goto=restart; diff --git a/Examples/Farmer.txt b/Examples/Farmer.txt new file mode 100644 index 0000000..fbec0b4 --- /dev/null +++ b/Examples/Farmer.txt @@ -0,0 +1,9 @@ +create=Farmer|Boy|Chris|NPC.Path.Wegpunkt.1; +:restart; +path=NPC.Path.SFRiceField.1; +rez=SF Water; +path=NPC.Path.SFRiceField.2; +rez=SF Water; +path=NPC.Path.SFRiceField.3; +rez=SF Water; +goto=restart; \ No newline at end of file diff --git a/Test.path b/Examples/Test.txt similarity index 100% rename from Test.path rename to Examples/Test.txt diff --git a/Examples/Wanderer.txt b/Examples/Wanderer.txt new file mode 100644 index 0000000..0145fd6 --- /dev/null +++ b/Examples/Wanderer.txt @@ -0,0 +1,14 @@ +create=Chris|Resident|Chris|NPC.PathNode.Landepunkt.Landepunkt; +path=NPC.PathNode.Landepunkt.Landepunkt|NPC.PathNode.Landepunkt.Cafe.Spiel; +:restart; +sit=Cafe - Stuhl - Spiel - 1; +wait=25; +stand=1; +path=NPC.PathNode.Landepunkt.Cafe.Spiel|NPC.PathNode.Flughafen.Pizzaria; +sit=NPCPizzaSitz3; +wait=25; +stand=1; +path=NPC.PathNode.Flughafen.Pizzaria|NPC.PathNode.Club.Tanzflche; +wait=60; +path=NPC.PathNode.Flughafen.Pizzaria|NPC.PathNode.Landepunkt.Cafe.Spiel; +goto=restart;