„Chris.MultiNPC.lsl“ hinzufügen
This commit is contained in:
parent
ead90152d5
commit
6ef03183d0
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue