„Chris.MultiNPC.lsl“ hinzufügen

This commit is contained in:
Christopher 2021-01-30 05:34:43 +00:00
parent ead90152d5
commit 6ef03183d0
1 changed files with 325 additions and 0 deletions

325
Chris.MultiNPC.lsl Normal file
View File

@ -0,0 +1,325 @@
//YEngine:lsl
yoptions;
//===================
//Version: 0.1.1
//Datum: 30.01.2021
//Git: https://clatza.dev/Christopher/OpenSim.Script.Chris.MultiNPC
//Made by: Chris Resident @ inc.li:8002
//Dependencies:
// - https://git.4creative.net/Module/OpenSim.Modules.osGetInventoryList.git
// - https://git.4creative.net/Module/OpenSim.Modules.DataValue.git
// - https://git.4creative.net/Module/OpenSim.Modules.PathFinding.git
//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 = [];
default
{
state_entry()
{
checkOSPermissions();
readAllNPCPathNC();
state running;
}
}
state running
{
state_entry()
{
llSetTimerEvent(1);
}
timer()
{
llSetTimerEvent(0);
doNextScriptStep();
llSetTimerEvent(1);
}
changed(integer change)
{
if (change & CHANGED_INVENTORY)
hardReset();
if (change & CHANGED_REGION_START)
hardReset();
}
}
//Script commands
integer script_create(integer slot, key npc, list command)
{
if(npc != NULL_KEY)
osNpcRemove(npc);
list objects = osGetSearchableObjectList(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");
m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot, npc);
return TRUE;
}
integer script_say(integer slot, key npc, list command)
{
osNpcSay(npc, 0, llList2String(command, 1));
return TRUE;
}
integer script_sit(integer slot, key npc, list command)
{
list objects = osGetSearchableObjectList(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_walk(integer slot, key npc, list command)
{
list objects = osGetSearchableObjectList(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]);
vector targetPosition = llList2Vector(targetDataList, 0);
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_touch(integer slot, key npc, list command)
{
list objects = osGetSearchableObjectList(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)
{
m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + slot + ".line", (integer)llList2String(command, 1) - 1);
return TRUE;
}
//Internal functions
doNextScriptStep()
{
integer currentNPCSlot = 0;
for (currentNPCSlot = 0; currentNPCSlot < llGetListLength(m_npcdata); currentNPCSlot++)
{
if(!checkDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot))
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");
list pathLineData = llParseString2List(currentPath, [";"], []);
string currentCommand = llList2String(pathLineData, currentLine);
list lineCommandData = llParseString2List(currentCommand, ["=", "|"], []);
if(currentState == "wait")
{
integer waitTime = getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".waittime");
if(llGetUnixTime() < waitTime)
continue;
m_npcdata = setDataEntryInDataList(m_npcdata, "npc." + currentNPCSlot + ".state", "");
}
if(currentState == "walk")
{
vector targetPosition = (vector)getDataEntryFromDataList(m_npcdata, "npc." + currentNPCSlot + ".targetPosition");
list currentNPCDataList = llGetObjectDetails(currentNPCKey, [OBJECT_POS]);
if(llGetListLength(currentNPCDataList) == 0)
hardReset();
vector currentNPCPosition = llList2Vector(currentNPCDataList, 0);
if(llVecDist(currentNPCPosition, targetPosition) >= 1)
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);
switch(llList2String(lineCommandData, 0))
{
case "create":
if(!script_create(currentNPCSlot, currentNPCKey, lineCommandData))
llSay(0, "Script execution in '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
break;
case "say":
if(!script_say(currentNPCSlot, currentNPCKey, lineCommandData))
llSay(0, "Script execution in '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
break;
case "sit":
if(!script_sit(currentNPCSlot, currentNPCKey, lineCommandData))
llSay(0, "Script execution in '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
break;
case "wait":
if(!script_wait(currentNPCSlot, currentNPCKey, lineCommandData))
llSay(0, "Script execution in '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
break;
case "stand":
if(!script_stand(currentNPCSlot, currentNPCKey, lineCommandData))
llSay(0, "Script execution in '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
break;
case "walk":
if(!script_walk(currentNPCSlot, currentNPCKey, lineCommandData))
llSay(0, "Script execution in '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
break;
case "touch":
if(!script_touch(currentNPCSlot, currentNPCKey, lineCommandData))
llSay(0, "Script execution in '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
break;
case "goto":
if(script_goto(currentNPCSlot, currentNPCKey, lineCommandData))
currentNPCSlot--;
break;
default:
llSay(0, "Unknown command '" + llList2String(lineCommandData, 0) + "' in nc '"+ currentncname +"' on line '" + currentLine + "' failed.");
}
}
}
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);
}
}
checkOSPermissions()
{
key tempnpc = NULL_KEY;
try{ tempnpc = osNpcCreate("Testi", "Test", llGetPos(), llGetOwner()); }catch(exception ex) { llSay(0, "You need to enable osNpcCreate in your ossl configuration."); }
try{ osNpcRemove(tempnpc); }catch(exception ex) { llSay(0, "You need to enable osNpcRemove in your ossl configuration."); }
try{ osMakeNotecard("Test" + llGetKey(), "Test"); }catch(exception ex) { llSay(0, "You need to enable osMakeNotecard in your ossl configuration."); }
try{ osGetNotecard("Test" + llGetKey()); }catch(exception ex) { llSay(0, "You need to enable osGetNotecard in your ossl configuration."); }
try{ osOwnerSaveAppearance("OwnerAppearance" + llGetKey()); }catch(exception ex) { llSay(0, "You need to enable osOwnerSaveAppearance in your ossl configuration."); }
llRemoveInventory("Test" + llGetKey());
llRemoveInventory("OwnerAppearance" + llGetKey());
}
hardReset()
{
integer dataListCount = llGetListLength(m_npcdata);
while(dataListCount--)
if(checkDataEntryInDataList(m_npcdata, "npc." + dataListCount))
osNpcRemove((key)getDataEntryFromDataList(m_npcdata, "npc." + dataListCount));
llResetScript();
}
//Generic Helpers
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);
}