Hallo, Gast |
Sie müssen sich registrieren bevor Sie auf unserer Seite Beiträge schreiben können.
|
Foren-Statistiken |
» Mitglieder: 23
» Neuestes Mitglied: Lilida
» Foren-Themen: 599
» Foren-Beiträge: 1.567
Komplettstatistiken
|
Aktive Themen |
Red light district
Forum: Informationen und aktuelle Meldungen
Letzter Beitrag: Cheryl Furse
Vor 2 Stunden
» Antworten: 3
» Ansichten: 69
|
Tanzball rezzen
Forum: OpenSim-Manager
Letzter Beitrag: Lilida
16.04.2024, 14:27
» Antworten: 6
» Ansichten: 476
|
Was ist ne Kaffestube ohn...
Forum: Kaffeestube
Letzter Beitrag: Susan
15.04.2024, 15:17
» Antworten: 0
» Ansichten: 197
|
Sim geht in Schlafmodus
Forum: OpenSim
Letzter Beitrag: Scarlett Candor
11.04.2024, 10:16
» Antworten: 3
» Ansichten: 437
|
C Programmierung und bull...
Forum: Scripting
Letzter Beitrag: Cheryl Furse
07.04.2024, 00:50
» Antworten: 2
» Ansichten: 298
|
Steampunk-Party mit Marlo...
Forum: Informationen und aktuelle Meldungen
Letzter Beitrag: ThunderTower
02.04.2024, 18:29
» Antworten: 0
» Ansichten: 232
|
ERÖFFNUNG FLORES SEA Wild...
Forum: Informationen und aktuelle Meldungen
Letzter Beitrag: ThunderTower
01.04.2024, 18:52
» Antworten: 3
» Ansichten: 313
|
Einladung zur SCIFI Party...
Forum: Virtual Africa
Letzter Beitrag: Cheryl Furse
31.03.2024, 13:32
» Antworten: 7
» Ansichten: 627
|
Das Ei ist hart
Forum: Kaffeestube
Letzter Beitrag: ThunderTower
30.03.2024, 16:38
» Antworten: 0
» Ansichten: 245
|
Lukas, melde dich bitte, ...
Forum: Kaffeestube
Letzter Beitrag: Tron Mcp
25.03.2024, 12:31
» Antworten: 2
» Ansichten: 305
|
|
|
PMAC POSER V2.8 BASISSCRIPT TEIL1 |
Geschrieben von: Tron Mcp - 15.02.2024, 10:55 - Forum: Animieren
- Keine Antworten
|
|
PMAC POSER V2.8 BASISSCRIPT TEIL1
Dieser Artikel enthält meine Weiterentwicklung des PMAC Posers. Ein Fork der Version 2.0
Das Script kann direkt in vorhandenen alten PMAC Poser bis 2.2 zum Austausch verwendet werden.
Was sind die Haupt Änderungen?
NPCs: NPC Rezzt nun im Gruppenkontext des Prims - damit NPCS auch auf Sims mit ausschließlich Gruppenzugang funktionieren.
Somit können NPCs auch auf gesperrten Sims eingesetzt werden, und fliegen auch nicht heraus wenn man später die Sim sperrt.
NPCs: Unterstützung für NPC Profil Foto. Fotos müssen ".bild npcname" heissen damit sie als Profilfoto im NPC Profil geladen werden.
Beispiel: die NPC Notecard heisst: ".NPC192 Donna Orphelia" so muss das Profilfoto ".bild Donna Ophelia" benannt werden.
NPCs: Unterstützung für NPC Profil Info. Notecard muss ".info npcname" heissen, damit deren Inhalt im Info Feld des Profils angezeigt wird.
Beispiel: die NPC Notecard heisst: ".NPC192 Donna Orphelia" so muss die Profilinfo ".info Donna Ophelia" benannt werden.
Die Notizkarte dafür erstellt man inworld. Leider ist die Textlänge im Simulator sehr beschränkt. Der Inhalt der Notizkare wird dann im Profil Info Textfeld dargestellt.
Menü Rechte Änderung: NPC Tänzer können nun von jedem Nutzer geholt werden
Es besteht nun die Möglichkeit vorzugeben wer auf dem Poser Rechte hat Posereigene NPCs zu laden oder zu löschen.
dafür werden folgende Variablen verwendet:
publicaccess { zugang = TRUE;} Öffentlicher Zugang
groupaccess { zugang = TRUE;} Gruppen Zugang
zugangsliste Persönlicher Zugang über UUID Liste
der Poserbesitzer hat immer Zugang
Ihr findet die Einstellmöglichkeit im Script:
list zugangsliste = ["b6a520ac-a468-4bc3-9e52-b509e88a8bce","18da7264-3260-4b63-8173-2a6fd7e93e33","798a6b1e-2186-4cf2-b733-460cb7132ae9"]; // UUIDS berechtigter AVAs
integer groupaccess = FALSE; // TRUE/FALSE - darf die Gruppe steuern?
integer publicaccess = FALSE; // TRUE/FALSE - darf jeder steuern?
Admin Rechtestruktur erweitert vom Owner auf Berechtigte
SIMCROSSING Fähigkeit: Script Reset bei Simwechsel und Region Neustart ist nun wählbar um Simcrossing Fahrzeuge mit PMAC zu ermöglichen. (Bug in Opensim kompensieren)
Gender detection von AVA,NPC und Animationen (letzter Animationsbuchstaben F f oder M m) sowie Posen Zuordnung beim Hinsetzten
ES GIBT NOCH MEHR NEUE FUNKTIONEN, ABER DIE BESCHREIBEN ICH SPÄTER IN EINEM ANDEREN ARTIKEL
Ihr müsst es aber in 2 Teilen herunterladen und im Script Editor zu einem Script zusammen setzen.
Der Code ist zu lang für einen Artikel des Forums. Dieses ist NUR der 1. Teil!
Als eindeutige Beschriftung empfehle ich: P607 PMAC 2.8 Poser UNIVERSAL + NPC 122022.lsl
TEIL1: "P607 PMAC 2.8 Poser UNIVERSAL + NPC 122022.lsl"
Code: // P607 PARAMOUR MULTI-ANIMATION CONTROLLER (PMAC) v2.8-NPC Universal VERSION
// by Aine Caoimhe (Mata Hari)(c. LACM) March 2015-February 2016
// Provided under Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International license.
// Please be sure you read and adhere to the terms of this license: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// *** THIS SCRIPT REQUIRES (AND WILL ONLY WORK) IN REGIONS WHERE THE SCRIPT OWNER HAS OSSL FUNCTION PERMISSIONS ***
// *** THIS SCRIPT MUST ALWAYS BE LOCATED IN THE ROOT PRIM OF A LINKSET ***
// NPCs: NPC Rezzt nun im Gruppenkontext des Prims - damit NPCS auch auf Sims mit ausschließlich Gruppenzugang funktionieren.
// NPCs: Unterstützung für NPC Profil Foto. Fotos müssen ".bild npcname" heissen damit sie als Profilfoto im NPC Profil geladen werden.
// NPCs: Unterstützung für NPC Profil Info. Notecard muss ".info npcname" heissen, damit deren Inhalt im Info Feld des Profils angezeigt wird.
// Menü Rechte Änderung: NPC Tänzer können nun von jedem Nutzer geholt werden
// Admin Rechtestruktur erweitert vom Owner auf Berechtigte
// SIMCROSSING Fähigkeit: Script Reset bei Simwechsel und Region Neustart ist nun wählbar um Simcrossing Fahrzeuge mit PMAC zu ermöglichen. (Bug in Opensim kompensieren)
// Gender detection von AVA,NPC und Animationen (letzter Animationsbuchstaben F f oder M m) sowie Posen Zuordnung beim Hinsetzten
// *********************************************************
// ***** GENERAL USER SETTINGS - ADJUST AS PREFERED *****
// *********************************************************
string defaultGroup="Hexdance"; // name of a group (not the full card name!) to load by default regardless of its permission setting
integer resetOnQuit=FALSE; // TRUE = when no more sitters, reset the script (will also load default group again)
// FALSE = leave most recently loaded animation active
integer ownerUseReq=FALSE; // TRUE = the owner must be the first to sit and other people can only sit while the owner is still present and seated
// FALSE = no restriction...anyone can sit and use it at any time
integer ownerOnlyMenus=FALSE; // TRUE = only the owner can access the dialog menus (can be turned off in options menu until script is reset or it is turned on again) - NOT RECOMMENDED unless ownerUseReq=TRUE
// FALSE = anyone can be the controller
integer ownerUseUnlocksPerms=TRUE; // TRUE = if owner is a current user, all users then have access to all groups and NPCs
// FALSE = only the owner can ever load an owner-only Group or NPC
integer autoOn=TRUE; // TRUE = will start in auto mode after a reset
// FALSE = will start in manual mode after a reset -- after use will remain in whatever state it was left in unless resetOnQuit=TRUE
float autoTimer=120.0; // default time to use for the autotimer (in seconds) - after use will remain at whatever timer was last set to unless resetOnQuit=TRUE;
string gs_ConfigName=".PMAC-CONFIG"; // Name of optional notecard with user defined configuration that overide the above values if present
integer showGroupsMenuFirst=FALSE; // TRUE = when first initiating dialog, show the groups menu instead of the current group's animation menu; FALSE = show current group's animation menu
integer allowSoloNPC=TRUE; // TRUE = NPCs can be left rezzed even if there are no avatars seated; FALSE = kill all NPCs if there are no remaining avatars
integer ownerOnlyRemote=TRUE; // TRUE = remote commands will only be accepted from scripted objects belonging to the same owner as the PMAC system (*** NEW IN PMAC 2.0***)
// FALSE = anyone with authority to send osMessageObject() can send a command to PMAC
integer silent=TRUE; // TRUE = PMAC will only say critical information to chat...usually only errors will be seen (*** NEW IN PMAC 2,0***)
// FALSE = PMAC will notify users of some changes
integer resetOnSimcross= FALSE; // TRUE/FALSE = restart script on Sim Restart and Simcrossing
// ***************************************
// ***** ADVANCED/BUILDER SETTINGS *****
// ***************************************
string handleName="~~~positioner"; // inventory object to rez as a handle for positioning
list handleColours=[<1.000, 0.004, 0.667>,<0.004, 0.667, 1.000>,<0.667, 1.000, 0.004>, // supply as many as you like but ideally at least as many as the expected positions in most of your menus
<1.000, 0.004, 0.004>,<0.004, 0.004, 1.000>,<1.000, 0.667, 0.004>,
<0.667, 0.004, 1.000>,<0.004, 1.000, 0.667>,<0.004, 1.000, 0.004>];
vector handleSize=<0.2,0.2,3.0>; // size of handles used in edit mode
float handleAlpha=0.5; // alpha of handles used in edit mode
string baseAn="~~~~~base_DO_NOT_DELETE_ME!!!!!"; // name of the P1 animation to use for synch
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * * * DO NOT CHANGE ANYTHING BELOW HERE UNLESS YOU KNOW WHAT YOU'RE DOING! * * *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
key user;
list positions;
list invNpc; // fullName | A/G/O | buttonName
integer invNpcStride=3;
list npcList;
integer npcPage;
list invGroups; // fullName | positions | A/G/O | buttonName
integer invGroupStride=4;
list groupList;
integer groupPage;
integer myChannel;
integer diaHandle;
string menu;
string txtDia;
list butDia;
string currentGroup;
list anData; // anName | command | A1Name | A1 Pos | A1 Rot |
integer anStride;
list anList;
list currentAn; // groupName | anName | command | A1Name | A1 Pos | A1 Rot |
integer anPage;
list editHandles;
integer rezzingHandles;
float editTimer=0.2;
string myState="INITIALIZING";
list specials; //buttonName | stringToSend
integer specPage;
integer gi_HaveConfig=0;
// NC_PROP ADDON
integer gi_NC_PROP_CHANGED=FALSE; // global integer flag to indicate if new prop values have been sent form NC_PROPS addon
string gs_NC_PROP_DATA=""; // global string containing changed props data
key toucher; // UUID des Operators
list zugangsliste = ["b6a520ac-a468-4bc3-9e52-b509e88a8bce","18da7264-3260-4b63-8173-2a6fd7e93e33","798a6b1e-2186-4cf2-b733-460cb7132ae9"]; // UUIDS berechtigter AVAs
integer groupaccess = FALSE; // TRUE/FALSE - darf die Gruppe steuern?
integer publicaccess = FALSE; // TRUE/FALSE - darf jeder steuern?
integer groupusercount; // Anzahl der zulässigen User in die ser Posergruppe
list anigenderlist = []; // Speichert gender pro Animation
// *** ERMITTLUNG DES AVA/NPC GESCHLECHTS
integer GenderDetect(key id)
{
string geschlecht = osGetGender(id);
if ( geschlecht == "female") return 1;
else if ( geschlecht == "male") return -1;
else return 0;
}
// *** GESCHLECHTSSPEZIFISCHES POSITIONIEREN von AVAs und NPCs auf Animationen.
PositioniereAva( integer aktuellerplatz, key wer)
{
integer usergeschlecht = GenderDetect(wer); // Geschlecht des aktuell zu platzierenden Users ermitteln
integer anis = llGetListLength(anigenderlist);
integer lauf = 0;
integer angender = (integer) llList2String(anigenderlist,aktuellerplatz); // Geschlecht der aktuelle Pose lesen
if (usergeschlecht == angender) return; // ich sitze schon richtig
do
{
key nutzer = llList2String(positions,lauf);
if(nutzer == NULL_KEY)
{
angender = (integer) llList2String(anigenderlist,lauf);
if (angender == usergeschlecht) // Treffer, ich wechsel auf diese Position
{
SwapAvaPositions(aktuellerplatz,lauf);
aktuellerplatz = lauf;
return;
}
}
lauf++;
} while (lauf < anis);
}
// *** ZUGANGSBERECHTIGUNGEN AUSWERTEN
integer BerechtigungsCheck(string clicker, integer selbegruppe)
{
integer zugang = FALSE;
integer personalzugang = llGetListLength(zugangsliste);
if (publicaccess) { zugang = TRUE;} // Öffentlicher Zugang
else if (selbegruppe && groupaccess) { zugang = TRUE;} // Gruppen Zugang
else if (clicker == llGetOwner()) { zugang = TRUE;} // Besitzer Zugang immer erlaubt
else if (personalzugang) // Persönlicher Zugang über UUID Liste
{
string personal;
do
{
personal = llList2String(zugangsliste, personalzugang -1 );
if( clicker == personal) { zugang = TRUE; }
personalzugang--;
}
while ( personal && (!zugang));
}
return zugang;
}
// *** PMAC FENBEDIENUNG
handleRemoteCall(string message)
{
list call=llParseString2List(message,["|"],[]);
string command=llList2String(call,0);
if (command=="PMAC_REMOTE_QUIT")
{
if (myState=="RUNNING") QuitEditMode();
else if (command=="PMAC_REMOTE_SYNCH")
{
if (myState=="RUNNING") SyncAvas();
}
else
{
user=NULL_KEY;
if (command=="PMAC_REMOTE_AUTO_OFF")
{
autoOn=FALSE;
llSensorRemove();
}
else if (command=="PMAC_REMOTE_AUTO_ON")
{
autoOn=TRUE;
float setTime=llList2Float(call,1);
if (setTime>0.0) autoTimer=setTime;
else updateAutoTimer(); // check anim to see if custom
if (myState=="RUNNING") llSensorRepeat("THIS_WILL_NEVER_RETURN_A_SENSOR_RESULT",NULL_KEY,AGENT,0.001,0.0,autoTimer);
}
else if ((command=="PMAC_REMOTE_SWAP") && (myState=="RUNNING"))
{
integer p1=llList2Integer(call,1);
integer p2=llList2Integer(call,2);
if ((p1>=llGetListLength(positions))||(p2>=llGetListLength(positions))) llOwnerSay("ERROR: remote swap calling for a position index that is out of range. There are only "+(string)llGetListLength(positions)+" and you called for "+(string)p1+" and "+(string)p2+". Did you perhaps forget that indexing begins at position 0, not positions 1?");
else SwapAvaPositions(p1,p2);
}
else if ((command=="PMAC_REMOTE_UNSIT") && (myState=="RUNNING"))
{
key keyToUnsit=llList2Key(positions,llList2Integer(call,1));
if (keyToUnsit!=NULL_KEY) llUnSit(keyToUnsit);
}
else if ((command=="PMAC_REMOTE_SET_GROUP")||(command=="PMAC_REMOTE_SET_ANIMATION"))
{
string newGroup=llList2String(call,1);
if (llListFindList(invGroups,[newGroup])==-1)
{
llOwnerSay("ERROR! Remote call to load group \""+newGroup+"\" but this group doesn't exist. Please check the name and remember not to include the .menuxxxx prefix portion");
return;
}
loadAnimGroup(newGroup);
if (command=="PMAC_REMOTE_SET_ANIMATION")
{
string anToPlay=llList2String(call,2);
if (llListFindList(anList,[anToPlay])==-1)
{
llSay(0,"ERROR! A remote call was received to play animation \""+anToPlay+"\" from group \""+newGroup+"\" but that animation cannot be found. This is a fatal error and requires the system to quit and be reset. You may need to notify the owner and ask them to reset it if it isn't configured to do so automatically on quit.");
myState="ERROR";
QuitEditMode();
}
else playAnimation(anToPlay);
}
}
}
}
}
// *** ANIMATIONS AUSWAHL MENÜ ZEIGEN
showAnMenu()
{
integer maxAn=llGetListLength(anList);
integer showStart=(anPage+1);
integer showEnd=(anPage+6);
if (showEnd>maxAn) showEnd=maxAn;
txtDia=""+"ANIMATION MENU: Select an animation\n"+currentlyPlaying()+"\nShowing animation";
if (showEnd!=showStart) txtDia+="s "+(string)showStart+" to "+(string)showEnd;
else txtDia+=" "+(string)showStart;
txtDia+=" of "+(string)maxAn+ " total animations in this group\n\n"+llDumpList2String(llList2List(anList,anPage,anPage+5),"\n");
butDia=[]+llList2List(anList,anPage,anPage+5);
while (llGetListLength(butDia)<6) { butDia=[]+butDia+["-"]; }
butDia=[]+butDia+["< PREV","ADD NPC","SYNCH","NEXT >","GROUPS","OPTIONS","QUIT"];
menu="MENU_ANIM";
startListening();
}
// *** ANIMATIONS GRUPPEN MENÜ ZEIGEN
showGroupsMenu()
{
txtDia=""+"GROUPS MENU: Select a group of animations\n"+currentlyPlaying()+"\nShowing groups "+(string)(groupPage+1)+" to "+(string)(groupPage+6)+" of "+(string)llGetListLength(groupList)+ " total groups\n\n"+llDumpList2String(llList2List(groupList,groupPage,groupPage+5),"\n");
butDia=[]+llList2List(groupList,groupPage,groupPage+5);
while (llGetListLength(butDia)<6) { butDia=[]+butDia+["-"];}
butDia=[]+butDia+["< PREV","SYNCH","NEXT >","<< BACK","OPTIONS","QUIT"];
menu="MENU_GROUPS";
startListening();
}
// *** EDIT MENÜ ZEIGEN
showEditMenu()
{
txtDia=""+"EDIT MODE ACTIVE!!!\n"+currentlyPlaying()+" (#"+(string)(llListFindList(anList,[llList2String(currentAn,1)])+1)+" of "+(string)llGetListLength(anList)+")\n\nPlease ensure you have read and are familiar with the PMAC instructions for using the edit menu, particularly if you use add-on modules. You have been warned...";
butDia=[]+["< PREV","SYNCH","NEXT >","REVERT THIS","STORE THIS","STORE ADDON","EDIT OFF","SAVE CARD","SAVE NEW"];
menu="MENU_EDIT";
startListening();
}
// *** OPTIONEN MENÜ ZEIGEN
showOptionsMenu()
{
txtDia=""+"OPTIONS MENU:\n\n";
butDia=[];
if (user==llGetOwner())
{
if (ownerOnlyMenus)
{
txtDia+="EDIT ON enters edit mode (all positions must be filled)\nMENUS UNLOCK allows other users to take control\n";
butDia=[]+butDia+["EDIT ON","MENUS UNLOCK","-"];
}
else
{
txtDia+="EDIT ON enters edit mode (all positions must be filled)\nMENUS LOCK prevents other users from taking control\n";
butDia=[]+butDia+["EDIT ON","MENUS LOCK","-"];
}
}
txtDia+="AUTO is used to enable, disable or adjust auto mode\n";
butDia=[]+butDia+["AUTO","-"];
if (llGetListLength(specials)>0)
{
txtDia+="SPECIAL access special add-on menus\n";
butDia=[]+butDia+["SPECIAL"];
}
else butDia=[]+butDia+["-"];
txtDia+="SWAP to swap positions\nUNSIT to force someone to stand up or remove a npc\n";
butDia=[]+butDia+["SWAP","UNSIT"];
if (llListFindList(positions,[NULL_KEY])>-1)
{
txtDia+="ADD NPC to have a NPC join you\n"; // ADD NPC Auswahl
butDia=[]+butDia+["ADD NPC"];
}
else butDia=[]+butDia+["-"];
butDia=[]+butDia+["<< BACK","SYNCH","QUIT"];
menu="MENU_OPTIONS";
startListening();
}
// *** SPECIALS MENÜ ZEIGEN
showSpecialsMenu()
{
txtDia=""+"SPECIALS MENU\n\nThese are options supplied by any add-ons you have installed. Please consult their instructions for details.\n";
butDia=[];
integer i=specPage;
while (llGetListLength(butDia)<9)
{
if (i<llGetListLength(specials))
{
butDia=[]+butDia+llList2String(specials,i);
txtDia+="\n"+llList2String(specials,i);
i+=2;
} else butDia=[]+butDia+["-"];
}
butDia=[]+butDia+["< PREV","CANCEL","NEXT >"];
menu="MENU_SPECIALS";
startListening();
}
// *** AUTO MENÜ ZEIGEN
showAutoMenu()
{
txtDia="AUTO MENU\n\nAuto mode is currently ";
butDia=[]+["120","300","600","30","60","90"];
if (autoOn)
{
txtDia+="ON and set to "+(string)llRound(autoTimer)+" seconds\n\nSelect a different time if you wish, or AUTO OFF to switch to manual mode";
butDia=[]+butDia+["AUTO OFF","-","CANCEL"];
}
else
{
txtDia+="OFF\n\nSelect AUTO ON to use the last preset time or pick your preferred timer";
butDia=[]+butDia+["AUTO ON","-","CANCEL"];
}
menu="MENU_SELECT_AUTO_MODE";
startListening();
}
// *** ADD NPC MENÜ ZEIGEN
showAddNpcMenu()
{
txtDia=""+"ADD NPC\n\nSelect the NPC to add. It will occupy the first available position\n\n"+llDumpList2String(llList2List(npcList,npcPage,npcPage+8),"\n");
butDia=[]+llList2List(npcList,npcPage,npcPage+8);
while (llGetListLength(butDia)<9) { butDia=[]+butDia+["-"]; }
butDia=[]+butDia+["< PREV","CANCEL","NEXT >"];
menu="MENU_ADD_NPC";
startListening();
}
// *** GESPIELTE ANIMATION WECHSELN
playAnimation(string name)
{
if (autoOn) llSensorRemove();
integer i=llGetListLength(positions);
while (--i>=0) { if (llList2Key(positions,i)!=NULL_KEY) osAvatarStopAnimation(llList2Key(positions,i),llList2String(currentAn,3+i*3));}
integer indexAn=llListFindList(anData,[name]);
list nextAn=[currentGroup]+llList2List(anData,indexAn,indexAn+anStride-1);
// Liste erstellen
anigenderlist = [];
integer nextanlaenge = llGetListLength(nextAn)/3;
integer laufvar = 1;
while (laufvar < nextanlaenge)
{
string animname = llList2String(nextAn,laufvar*3);
integer laenge = llStringLength(animname);
string buchstabe = llGetSubString(animname,laenge-1,-1);
buchstabe = llToUpper(buchstabe);
integer geschlecht = 0;
if (buchstabe == "F") geschlecht = 1;
else if (buchstabe == "M") geschlecht = -1;
anigenderlist = anigenderlist + geschlecht;
laufvar++;
}
integer have=llGetListLength(positions);
integer need=llRound(((float)llGetListLength(nextAn)-3.0)/3.0);
while(have<need) { positions=[]+positions+[NULL_KEY];have++;}
while ((have>need) && (llListFindList(positions,[NULL_KEY])>=0)) { positions=[]+llDeleteSubList(positions,llListFindList(positions,[NULL_KEY]),llListFindList(positions,[NULL_KEY]));have--;}
if (have>need)
{
llSay(0,"There are currently too many users seated. You will need to reduce the number of seated users by "+(string)(have-need)+" to play it, or select a different group of animations");
return;
}
i=llGetListLength(positions);
while (--i>=0)
{
key who=llList2Key(positions,i);
if (who!=NULL_KEY)
{
osAvatarPlayAnimation(who,llList2String(nextAn,3+i*3));
setPosition(who,getUserLink(who),llList2Vector(nextAn,4+i*3),llList2Rot(nextAn,5+i*3));
if (myState=="EDIT") setHandle(llList2Key(editHandles,i),llList2Vector(nextAn,4+i*3),llList2Rot(nextAn,5+i*3));
}
}
currentAn=[]+nextAn;
llMessageLinked(LINK_THIS,0,"GLOBAL_NEXT_AN|"+llList2String(currentAn,2),llDumpList2String(positions,"|"));
if (autoOn)
{
updateAutoTimer();
if (myState=="RUNNING") llSensorRepeat("THIS_WILL_NEVER_RETURN_A_SENSOR_RESULT",NULL_KEY,AGENT,0.001,0.0,autoTimer);
}
}
updateAutoTimer()
{
list comBlock=llParseString2List(llList2String(currentAn,2),["{","}"],[]);
integer autoSet=llListFindList(comBlock,["PMAC_SET_AUTO"]);
if (autoSet>=0)
{
if (llList2Float(comBlock,autoSet+1)>0.0) autoTimer=llList2Float(comBlock,autoSet+1);
else llOwnerSay("ERROR: the animation \""+llList2String(currentAn,1)+"\" is calling for the auto timer to be set to "+llList2String(comBlock,autoSet+1)+". Value supplied must be a non-zero float. Using the previous timer value instead.");
}
}
// *** AVATARPOSTITION MIT ANDEREN AVAS SYNCHRONISIEREN
SyncAvas()
{
integer i=llGetListLength(positions);
while (--i>=0)
{
key who=llList2Key(positions,i);
if (who!=NULL_KEY) {
osAvatarStopAnimation(who,llList2String(currentAn,3+i*3));
osAvatarPlayAnimation(who,llList2String(currentAn,3+i*3));
}
}
llMessageLinked(LINK_THIS,0,"GLOBAL_ANIMATION_SYNCH_CALLED",llDumpList2String(positions,"|"));
}
// *** AVATARPOSTITION UNTEREINANDER TAUSCHEN
SwapAvaPositions(integer indFrom,integer indTo)
{
key whoFrom=llList2Key(positions,indFrom);
if (whoFrom!=NULL_KEY)
{
osAvatarStopAnimation(whoFrom,llList2String(currentAn,3+indFrom*3));
setPosition(whoFrom,getUserLink(whoFrom),llList2Vector(currentAn,4+indTo*3),llList2Rot(currentAn,5+indTo*3));
}
key whoTo=llList2Key(positions,indTo);
if (whoTo!=NULL_KEY)
{
osAvatarStopAnimation(whoTo,llList2String(currentAn,3+indTo*3));
setPosition(whoTo,getUserLink(whoTo),llList2Vector(currentAn,4+indFrom*3),llList2Rot(currentAn,5+indFrom*3));
}
positions=[]+llListReplaceList(positions,[whoFrom],indTo,indTo);
positions=[]+llListReplaceList(positions,[whoTo],indFrom,indFrom);
SyncAvas();
}
// *** MENÜKONTROLLE DURCH ANDEREN AVA ÜBERNEHMEN
ChangeMenuUser(key who)
{
if ((user!=NULL_KEY)&&!silent) llRegionSayTo(user,0,llGetUsername(who)+" has now taken control of me");
user=who;
buildGroupList();
specials=[];
llMessageLinked(LINK_THIS,0,"GLOBAL_NEW_USER_ASSUMED_CONTROL|"+(string)user,llDumpList2String(positions,"|"));
if (llListFindList(groupList,[currentGroup])==-1) loadAnimGroup(llList2String(groupList,0));
else if (autoOn) showGroupsMenu();
else if (showGroupsMenuFirst) showGroupsMenu();
else showAnMenu();
}
// *** EDITMODUS VERLASSEN
QuitEditMode()
{
if (myState=="EDIT") removeHandles();
integer i=llGetListLength(positions);
while (--i>=0)
{
key who=llList2Key(positions,i);
if (who!=NULL_KEY)
{
if (osIsNpc(who)) osNpcRemove(who);
else
{
if (!silent) llRegionSayTo(who,0,"Quit called");
llUnSit(who);
}
}
}
}
// *** NEUE ANIMATIONSGRUPPE LADEN
loadAnimGroup(string name)
{
if (name==currentGroup) { if(user!=NULL_KEY) showAnMenu(); return;}
integer indToLoad=llListFindList(invGroups,[name])-3;
groupusercount=llList2Integer(invGroups,indToLoad+1); // Zugelassene Userzahl in der Animations Gruppe
if (groupusercount<llGetListLength(positions)) // Gruppe enthält zu wenige Animationen für sitzende User
{
integer agents;
integer a=llGetListLength(positions);
while (--a>-1) { if (llList2Key(positions,a)!=NULL_KEY) agents++;}
if (agents>groupusercount)
{
llRegionSayTo(user,0,"You cannot use animations from the "+name+" group at the moment because it is for a maximum of "+(string)groupusercount+" users and there are currently "+(string)agents+" seated. Please select a different group of animations, remove NPCs, or ask someone to stand.");
if (user!=NULL_KEY) startListening();
return;
}
}
currentGroup=name; // Erfolgreich auf neue Animations Gruppe geschalten
anData=[]+llParseString2List(osGetNotecard(llList2String(invGroups,indToLoad)),["|","\n"],[""]);
anStride=2+(3*groupusercount);
anPage=0;
anList=llList2ListStrided(anData,0,-1,anStride); // Animationsliste füllen
if (autoOn && (myState=="RUNNING"))
{
playAnimation(llList2String(anList,0));
if (user!=NULL_KEY)
{
if (!silent) llRegionSayTo(user,0,"Now automatically playing animations from "+name);
showGroupsMenu();
}
} else if (user!=NULL_KEY) showAnMenu();
}
// *** PMAC KONFIGURATIONSPARAMETER LADEN
loadConfig()
{
integer i;
float n;
string sParam;
string sValue;
list lParams=[];
for(i=0;i<osGetNumberOfNotecardLines(gs_ConfigName); i++)
{
lParams=llParseString2List(osGetNotecardLine(gs_ConfigName,i),["="],"");
if (llGetListLength(lParams)==2)
{
sParam=llStringTrim(llList2String(lParams,0),STRING_TRIM);
sValue=llStringTrim(llList2String(lParams,1),STRING_TRIM);
if ((sParam=="defaultGroup") || (sParam=="DefaultGroup")) { defaultGroup=sValue; }
else if ((sParam=="resetOnQuit")||(sParam=="ResetOnQuit")) { resetOnQuit=(sValue=="TRUE");}
else if ((sParam=="ownerUseReq")||(sParam=="OwnerUseReq")) { ownerUseReq=(sValue=="TRUE");}
else if ((sParam=="ownerOnlyMenus")||(sParam=="OwnerOnlyMenus")) { ownerOnlyMenus=(sValue=="TRUE");}
else if ((sParam=="ownerUseUnlocksPerms")||(sParam=="OwnerUseUnlockPerms")) { ownerUseUnlocksPerms=(sValue=="TRUE");}
else if ((sParam=="autoOn")||(sParam=="AutoOn")) { autoOn=(sValue=="TRUE");}
else if ((sParam=="autoTimer")||(sParam=="AutoTimerValue")) { autoTimer=(float)sValue;}
else if ((sParam=="baseAn")||(sParam=="BaseAnimation")) { baseAn=sValue;}
else if ((sParam=="showGroupsMenuFirst")||(sParam=="ShowGroupsMenuFirst")) { showGroupsMenuFirst=(sValue=="TRUE");}
else if ((sParam=="allowSoloNPC")||(sParam=="AllowSoloNPC")) { allowSoloNPC=(sValue=="TRUE");}
else if ((sParam=="ownerOnlyRemote")||(sParam=="OwnerOnlyRemote")) { ownerOnlyRemote=(sValue=="TRUE");}
else if ((sParam=="silent")||(sParam=="Silent")) { silent=(sValue=="TRUE");}
else { llOwnerSay("Warn: Unable to parse user defined configuration "+llDumpList2String(lParams,"="));}
}
else if (llGetListLength(lParams)!=0) { llOwnerSay("Warn: Skipping user defined configuration line "+(string)i+" "+llDumpList2String(lParams,"="));}
}
}
// *** ANIMTIONS GRUPPEN LISTE ERSTELLEN
buildGroupList()
{
groupList=[];
groupPage=0;
integer i;
while (i<llGetListLength(invGroups))
{
if ( ( llList2String(invGroups,i+2)=="A" ) || ( (llList2String(invGroups,i+2)=="G") && llSameGroup(user)) || (user==llGetOwner()) || (llListFindList(positions,[llGetOwner()])>=0) ) groupList=[]+groupList+[llList2String(invGroups,i+3)];
i+=invGroupStride;
}
}
// *** LISTE VERFÜGBARER NPCS ERSTELLEN für Menüauswahl
buildNpcList()
{
npcList=[];
npcPage=0;
integer i;
while (i<llGetListLength(invNpc))
{// NPCs darf nun jeder laden
npcList=[]+npcList+[llList2String(invNpc,i+2)];
i+=invNpcStride;
}
showAddNpcMenu();
}
// *** INVENTAR AUSWERTEN
buildInventoryLists()
{
invGroups=[];
invNpc=[];
integer i=llGetInventoryNumber(INVENTORY_NOTECARD);
while (--i>-1)
{
string name=llGetInventoryName(INVENTORY_NOTECARD,i);
if (llSubStringIndex(name,".menu")==0)
{
integer nameStarts=llSubStringIndex(name," ")+1;
if (llListFindList(invGroups,[llGetSubString(name,nameStarts,-1)])>-1) llOwnerSay("ERROR! You have two groups notecards where the name \""+llGetSubString(name,nameStarts,-1)+"\" is used for the button! Group button names must be unique");
else invGroups=[]+[name,(integer)(llGetSubString(name,7,nameStarts-3)),llGetSubString(name,nameStarts-2,nameStarts-2),llGetSubString(name,nameStarts,-1)]+invGroups;
}
else if (llSubStringIndex(name,".NPC")==0)
{
if (llListFindList(invNpc,[llGetSubString(name,8,-1)])>-1) llOwnerSay("ERROR! You have two NPC notecards where the NPC name is \""+llGetSubString(name,8,-1)+"\" but NPC names must be unique");
else invNpc=[]+[name,llGetSubString(name,6,6),llGetSubString(name,8,-1)]+invNpc;
}
else if (llSubStringIndex(name,gs_ConfigName)==0) { gi_HaveConfig=1;}
}
}
// *** ANIMATIONS GRUPPEN NOTECARD SPEICHERN
saveCard(string cardName)
{
if (llGetInventoryType(cardName)==INVENTORY_NOTECARD)
{
llRemoveInventory(cardName);
llSleep(0.25);
}
integer i;
integer l=llGetListLength(anData);
string dataToStore;
while (i<l)
{
dataToStore+=llDumpList2String(llList2List(anData,i,i+anStride-1),"|")+"\n";
i+=anStride;
}
osMakeNotecard(cardName,dataToStore);
llMessageLinked(LINK_THIS,0,"GLOBAL_EDIT_STORE_TO_CARD|"+cardName,llDumpList2String(positions,"|"));
}
// *** DIE LINKNUMMER DES AVATARS HERAUSFINDEN UND ZURÜCKMELDEN
integer getUserLink(key who)
{
integer ret=FALSE;
if (who!=NULL_KEY)
{
integer link=llGetNumberOfPrims();
while ((link>1) && (ret==FALSE))
{
key this=llGetLinkKey(link);
if(this==who) ret=link;
link--;
}
}
return ret;
}
// *** MENÜ DIALOG MIT USER INITIALISIEREN
startListening()
{ llDialog(user,txtDia,llList2List(butDia,9,11)+llList2List(butDia,6,8)+llList2List(butDia,3,5)+llList2List(butDia,0,2),myChannel);}
// *** RÜCKMELDUNG AUTOMODE TIMER EINSTELLUNG UND AKTUELLER ANIMATION
string currentlyPlaying()
{
string strToReturn="Currently playing: "+llList2String(currentAn,0)+" > "+llList2String(currentAn,1);
if (autoOn) strToReturn+="\nAUTO mode is on and set to "+(string)llRound(autoTimer)+" seconds";
return strToReturn;
}
// *** NACH AVA POSITIONSEINSTELLUNG DIE NEUEN ORTSWERTE ZURÜCKSCHREIBEN
persistChanges()
{
integer u=llGetListLength(positions);
while(--u>=0)
{
list avData=getPosition(llList2Key(positions,u),getUserLink(llList2Key(positions,u)));
vector pos=llList2Vector(avData,0);
rotation rot=llList2Rot(avData,1);
string strPos="<"+trimF(pos.x)+","+trimF(pos.y)+","+trimF(pos.z)+">";
string strRot="<"+trimF(rot.x)+","+trimF(rot.y)+","+trimF(rot.z)+","+trimF(rot.s)+">";
currentAn=[]+llListReplaceList(currentAn,[strPos,strRot],4+u*3,5+u*3);
}
integer anIndex=llListFindList(anData,llList2List(currentAn,1,1));
if(gi_NC_PROP_CHANGED)
{ // NC_PROPS
string old_cmd=llList2String(currentAn,2);
integer NC_PROP_data_start=llSubStringIndex(old_cmd,"NC_PROP{")+8; // find start
// test is little weird, as i added +8 to compensate for search string length
if (NC_PROP_data_start != 7)
{ // search ending delimiter in rest of string
integer NC_PROP_data_end=NC_PROP_data_start+llSubStringIndex(llGetSubString(old_cmd, NC_PROP_data_start,-1),"}");
string new_cmd=llGetSubString(old_cmd, 0, NC_PROP_data_start -1) + gs_NC_PROP_DATA + llGetSubString(old_cmd, NC_PROP_data_end,-1);
currentAn=[]+llListReplaceList(currentAn,[new_cmd],2,2);
}
gi_NC_PROP_CHANGED=FALSE;
}
anData=[]+llListReplaceList(anData,llList2List(currentAn,1,-1),anIndex,anIndex+anStride-1);
llMessageLinked(LINK_THIS,0,"GLOBAL_EDIT_PERSIST_CHANGES",llDumpList2String(positions,"|"));
}
// *** HANDLES ZUR AVA POSITIONEN EDIT REZZEN
rezHandles()
{
if (llGetListLength(editHandles)<llGetListLength(positions)) llRezObject(handleName,llGetPos(),ZERO_VECTOR,ZERO_ROTATION,0);
else
{
rezzingHandles=FALSE;
integer h=llGetListLength(editHandles);
while (--h>=0) { osSetPrimitiveParams( llList2Key(editHandles,h),[PRIM_SIZE,handleSize,PRIM_COLOR,ALL_SIDES,llList2Vector(handleColours,h%llGetListLength(handleColours)),handleAlpha,PRIM_TEXT,"pos "+(string)(h+1),llList2Vector(handleColours,h%llGetListLength(handleColours)),1.0,PRIM_NAME,"pos "+(string)(h+1)]); }
playAnimation(llList2String(currentAn,1));
llSetTimerEvent(editTimer);
SyncAvas();
showEditMenu();
}
}
// *** HANDLES ZUR AVA POSITIONEN EDIT ENTFERNEN
removeHandles()
{
llSetTimerEvent(0.0);
myState="RUNNING";
llMessageLinked(LINK_THIS,0,"GLOBAL_NOTICE_LEAVING_EDIT_MODE",llDumpList2String(positions,"|"));
integer l=llGetListLength(editHandles);
while (--l>=0) { osMessageObject(llList2Key(editHandles,l),"HANDLE_DIE");}
editHandles=[];
showOptionsMenu();
}
// *** HANDLES ZUR AVA POSITIONEN EDIT VERSCHIEBEN/POSITIONIEREN
setHandle(key prim, vector relPos, rotation relRot)
{
vector pos=relPos*llGetRot()+llGetPos();
rotation rot=relRot*llGetRot();
osSetPrimitiveParams(prim,[PRIM_POSITION,pos,PRIM_ROTATION,rot]);
}
// *** AVATAR AN ANDERE POSITION FÜR NEUE ANIMATION BEFÖRDERN
setPosition(key who, integer link, vector pos, rotation rot)
{
vector size = llGetAgentSize(who);
float fAdjust = ((((0.008906 * size.z) + -0.049831) * size.z) + 0.088967) * size.z;
llSetLinkPrimitiveParamsFast(link,[PRIM_POS_LOCAL, ((pos + <0.0, 0.0, 0.4>) - (llRot2Up(rot) * fAdjust)), PRIM_ROT_LOCAL, rot]);
}
// *** AKTUELLE AVATARPOSITION ERMITTELN
list getPosition(key who, integer link)
{
vector size = llGetAgentSize(who);
float fAdjust = ((((0.008906 * size.z) + -0.049831) * size.z) + 0.088967) * size.z;
list avData=llGetLinkPrimitiveParams(link,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
vector avPos=llList2Vector(avData,0);
rotation avRot=llList2Rot(avData,1);
vector avPosUnadjusted=(avPos - <0.0, 0.0, 0.4>) + (llRot2Up(avRot) * fAdjust);
return [avPosUnadjusted,avRot];
}
// *** REGIONS POSITION IN RELATIVE POSITION UMRECHNEN
list regToRel(vector regionPos,rotation regionRot)
{
vector relPos=(regionPos - llGetPos()) / llGetRot();
rotation relRot=regionRot/ llGetRot();
return [relPos,relRot];
}
// *** RELATIVE POSITION IN REGIONS POSITION UMRECHNEN
list relToReg(vector refPos,rotation refRot)
{
vector regionPos=refPos*llGetRot()+llGetPos();
rotation regionRot=refRot*llGetRot();
return [regionPos,regionRot];
}
// *** HILFSFUNKTION ZUR POSITIONS BERECHNUNG
string trimF(float value)
{
integer newVal=llRound(value*10000);
integer negFlag=FALSE;
if (newVal<0) { negFlag=TRUE; newVal*=-1; }
integer strLength;
string retStr;
if (newVal==0) retStr="0";
else if (newVal<10) retStr="0.000"+(string)newVal;
else if (newVal<100) retStr="0.00"+(string)newVal;
else if (newVal<1000) retStr="0.0"+(string)newVal;
else if (newVal<10000) retStr="0."+(string)newVal;
else
{
retStr=(string)newVal;
strLength=llStringLength(retStr);
retStr=llGetSubString(retStr,0,strLength-5)+"."+llGetSubString(retStr,strLength-4,strLength-1);
}
while (llGetSubString(retStr,strLength,strLength)=="0")
{
retStr=llGetSubString(retStr,0,strLength-1);
strLength-=1;
}
if (negFlag) retStr="-"+retStr;
return retStr;
}
// NPC im GRUPPENKONTEXT rezzen, auch für public gesperrte Sims. Mit NPC Userprofilinfo und Profilbild
key npc_rezzer(string npcnotecard, key sittarget, vector npcPos)
{
string npc_name = llGetSubString(npcnotecard,8,-1); // NPC Namen ermitteln
key npctorez = osNpcCreate(npc_name, "" , npcPos, npcnotecard, 8 | OS_NPC_NOT_OWNED | OS_NPC_SENSE_AS_AGENT | OS_NPC_OBJECT_GROUP );
osNpcSit(npctorez,sittarget,OS_NPC_SIT_NOW);
if (llGetInventoryKey(".bild " + npc_name)) osNpcSetProfileImage(npctorez,".bild "+ npc_name); // Testen ob Profilbild vorhanden - dann laden
if (llGetInventoryKey(".info " + npc_name) != (string)NULL_KEY )
{
string info = (string) osGetNotecard(".info " + npc_name);
osNpcSetProfileAbout(npctorez, info); // Testen ob Profilinfo Notecard vorhanden - dann laden
}
return npctorez;
}
// *** HAUPTMENÜ
default
{
// *** INITIALISIERUNG UND GRUNDLIEGENDE ÜBERPRÜFUNG
state_entry()
{
if (llGetAttached()) return;
if (llGetLinkNumber()>1)
{
myState="ERROR";
llOwnerSay("ERROR! The main PMAC controller script must always be located in the root prim of a linkset!");
return;
}
myChannel=0x80000000|(integer)("0x"+(string)llGetKey());
user=NULL_KEY;
buildInventoryLists();
if (gi_HaveConfig) loadConfig();
if (llGetInventoryType(baseAn)!=INVENTORY_ANIMATION)
{
llOwnerSay("ERROR! Unable to find the base priority 1 animation to use for synch: "+baseAn);
myState="ERROR";
return;
}
if (llListFindList(invGroups,[defaultGroup])==-1)
{
myState="ERROR";
llOwnerSay("ERROR! Unable to find the specified default group \""+defaultGroup+"\" in inventory. Make sure you supplied the simple group name, not the full card name");
return;
}
loadAnimGroup(defaultGroup);
integer i=llList2Integer(invGroups,llListFindList(invGroups,[defaultGroup])-2);
positions=[];
while (--i>=0) { positions=[]+positions+[NULL_KEY]; }
currentAn=[]+[currentGroup]+llList2List(anData,0,anStride-1);
myState="READY";
llMessageLinked(LINK_THIS,0,"GLOBAL_SYSTEM_RESET",NULL_KEY);
llSitTarget(<0.0,0,0.001>,ZERO_ROTATION);
if (!silent) llOwnerSay("Initialization complete and ready to use");
}
// *** INITIALER RESET BEIM REZZEN DES POSERS
on_rez(integer num) {llResetScript();}
// *** HILFSOBJEKTE FÜR EDITMODUS REZZEN
object_rez(key id)
{
if (!rezzingHandles) return;
editHandles=[]+editHandles+[id];
rezHandles();
}
// ***
sensor(integer num)
{
llOwnerSay("ERROR! Sensor event inexplicably returned a result!");
llSensorRemove();
autoOn=FALSE;
}
// ***
no_sensor()
{
if (!autoOn)
{
llOwnerSay("ERROR! Sensor repeat triggered but auto mode is off. Figure out how this can happen and fix. Sensor removed");
llSensorRemove();
return;
}
if (myState!="RUNNING")
{
llOwnerSay("ERROR! Sensor repeat triggered while not in normal running state: Please figure out how this happened and fix. Sensor removed and auto turned off.\nState was=: "+myState);
autoOn=FALSE;
llSensorRemove();
return;
}
integer i=llListFindList(anList,[llList2String(currentAn,1)]);
if (i==-1) i=0;
else
{
i++;
if (i>=llGetListLength(anList)) i=0;
}
playAnimation(llList2String(anList,i));
}
// *** PERIODISCHE PRÜFUNG EDIT MODUS ; ansonsten TIMER löschen
timer()
{
if(myState=="EDIT")
{
llSetTimerEvent(0.0);
integer l=llGetListLength(positions);
while (--l>-1)
{
key who=llList2Key(positions,l);
if (who==NULL_KEY)
{
llOwnerSay("ERROR! NULL_KEY user while processing timer event edit mode. Leaving edit mode without saving changes.");
removeHandles();
return;
}
if (llGetAgentSize(who)==ZERO_VECTOR)
{
llOwnerSay("ERROR! Cannot detect user in region while processing timer event edit mode. Leaving edit mode without saving changes");
removeHandles();
return;
}
list handleData=llGetObjectDetails(llList2Key(editHandles,l),[OBJECT_POS,OBJECT_ROT]);
if (llGetListLength(handleData)==0)
{
llOwnerSay("ERROR! Unable to detect a handle! Leaving edit mode without saving changes");
removeHandles();
return;
}
handleData=[]+regToRel(llList2Vector(handleData,0),llList2Rot(handleData,1));
setPosition(who,getUserLink(who),llList2Vector(handleData,0),llList2Rot(handleData,1));
}
llSetTimerEvent(editTimer);
} else llSetTimerEvent(0.0);
}
// *** ABHANDLUNG DES PMAC REMOTEKOMMANDOS
dataserver(key qid, string message)
{
if ((ownerOnlyRemote) && (llGetOwnerKey(qid)!=llGetOwner())) return;
if (llSubStringIndex(message,"PMAC_REMOTE_")==0) handleRemoteCall(message);
}
// *** NACHRICHTEN VON LINKOBJEKTEN AUSWERTEN
link_message(integer sender,integer flag,string message,key command)
{
if (flag!=-1) return;
if (message=="MAIN_RESUME_MAIN_DIALOG") showOptionsMenu();
else if (llSubStringIndex(message,"MAIN_REGISTER_MENU_BUTTON")==0)
{
string buttonName=llList2String(llParseString2List(message,["|"],[]),1);
integer locationToAdd=llListFindList(specials,[buttonName]);
if (locationToAdd==-1) specials=[]+specials+[buttonName,command];
else specials=[]+llListReplaceList(specials,[buttonName,command],locationToAdd,locationToAdd+1);
specials=[]+llListSort(specials,2,TRUE);
}
else if (llSubStringIndex(message,"MAIN_UNREGISTER_MENU_BUTTON")==0)
{
string buttonName=llList2String(llParseString2List(message,["|"],[]),1);
integer locationToKill=llListFindList(specials,[buttonName,command]);
if (locationToKill==-1) return;
else specials=[]+llDeleteSubList(specials,locationToKill,locationToKill+1);
specials=[]+llListSort(specials,2,TRUE);
}
else if (llSubStringIndex(message,"NC_PROP_UPDATE")==0)
{ // NC_PROP addon
gi_NC_PROP_CHANGED=TRUE;
gs_NC_PROP_DATA=llGetSubString(message,15,-1);
}
else if (llSubStringIndex(message,"PMAC_REMOTE_")==0) handleRemoteCall(message);
}
// *** ANZAHL SITZENDER USER HAT SICH GEÄNDERT; ODER BESITZERWECHSEL DES POSERS
changed (integer change)
{
if (change & CHANGED_LINK)
{
if (llGetLinkNumber()>1)
{
llOwnerSay("ERROR! You have changed the linkset and the PMAC main script is no longer located in the root prim!");
myState="ERROR";
return;
}
integer i=llGetNumberOfPrims();
integer l=llGetObjectPrimCount(llGetKey());
list seated;
integer realAvi;
while (i>l)
{
key who=llGetLinkKey(i);
if ((myState=="ERROR") || (myState=="INITIALIZING"))
{
if (osIsNpc(who)) osNpcRemove(who);
else
{
if (myState=="ERROR") llRegionSayTo(who,0,"Sorry, I have encountered an error and must shut down until it is corrected");
else llRegionSayTo(who,0,"Sorry, you cannot sit while I am initializing. Please wait a moment and try again.");
llUnSit(who);
}
}
else
{
seated=[]+[who]+seated;
if (!osIsNpc(who)) realAvi++;
if (llListFindList(positions,[who])==-1)
{ // new sitter
integer indexToSit=llListFindList(positions,[NULL_KEY]);
if (ownerUseReq && (who!=llGetOwner()) && (llListFindList(positions,[llGetOwner()])==-1))
{
llRegionSayTo(who,0,"Sorry, the system is set to require that the owner is using me before anyone else may sit.");
llUnSit(who);
}
else if (indexToSit==-1)
{
llRegionSayTo(who,0,"Sorry, there are no available positions for you to occupy. Please wait for someone to stand");
llUnSit(who);
}
else
{
positions=[]+llListReplaceList(positions,[who],indexToSit,indexToSit);
llSleep(0.2);
list anToStop=llGetAnimationList(who);
osAvatarPlayAnimation(who,baseAn);
integer stop=llGetListLength(anToStop);
key dontStop=llGetInventoryKey(baseAn);
while (--stop>-1) { osAvatarStopAnimation(who,llList2Key(anToStop,stop)); }
if (myState=="READY")
{
if ((osIsNpc(who)) && (!allowSoloNPC))
{
llSay(0,"Sorry, an NPC cannot sit until there is a human user in control. Unsitting your NPC.");
llUnSit(who);
positions=[]+llListReplaceList(positions,[NULL_KEY],indexToSit,indexToSit);
osAvatarStopAnimation(who,baseAn);
}
else
{
myState="RUNNING";
llMessageLinked(LINK_THIS,0,"GLOBAL_START_USING",llDumpList2String(positions,"|"));
playAnimation(llList2String(currentAn,1));
}
}
else { playAnimation(llList2String(currentAn,1));}
PositioniereAva(indexToSit, who); // Geschlechtsspezifische Positionierung
}
}
}
i--;
}
i=llGetListLength(positions);
while (--i>=0)
{
key who=llList2Key(positions,i);
if (who!=NULL_KEY)
{
if ((!realAvi)&&osIsNpc(who))
{
if (!allowSoloNPC)
{
osNpcRemove(who);
positions=[]+llListReplaceList(positions,[NULL_KEY],i,i);
}
}
else if (llListFindList(seated,[who])==-1)
{
if (myState=="EDIT")
{
llOwnerSay("WARNING! Someone stood! Leaving edit mode and no changes will be stored to card");
removeHandles();
if (who!=llGetOwner())showOptionsMenu();
}
if (llGetAgentSize(who)!=ZERO_VECTOR)
{
osAvatarPlayAnimation(who,"stand");
osAvatarStopAnimation(who,llList2String(currentAn,3+i*3));
osAvatarStopAnimation(who,baseAn);
if (who==user) user=NULL_KEY;
}
positions=[]+llListReplaceList(positions,[NULL_KEY],i,i);
llMessageLinked(LINK_THIS,0,"GLOBAL_USER_STOOD|"+(string)i+"|"+(string)who,llDumpList2String(positions,"|"));
}
}
}
if (!realAvi)
{
if (diaHandle)
{
llListenRemove(diaHandle);
diaHandle=FALSE;
}
if (llGetListLength(seated)<1)
{
if (autoOn) llSensorRemove();
myState="READY";
llMessageLinked(LINK_THIS,0,"GLOBAL_SYSTEM_GOING_DORMANT",NULL_KEY);
if (resetOnQuit) llResetScript();
}
}
}
else if (change & CHANGED_REGION_START) {if(resetOnSimcross) llResetScript();}
else if (change & CHANGED_OWNER) llResetScript();
}
// *** MENÜ DURCH BERÜHREN DES POSERS ANGEFORDERT
touch_start(integer num)
{
toucher=llDetectedKey(0);
integer gruppe = llDetectedGroup(0);
integer access = BerechtigungsCheck(toucher,gruppe);
if (osIsNpc(llDetectedKey(0))) return;
if (myState=="ERROR")
{
if (toucher==llGetOwner()) llOwnerSay("PMAC somehow entered ERROR state. Please check your chat log for one or more messages indicating the nature of the error, correct it, then reset the script");
else llRegionSayTo(toucher,0,"Sorry, I encountered an error and am waiting for the owner to correct the issue and restart me");
}
else if (myState=="INITIALIZING") llRegionSayTo(toucher,0,"Please wait until initialization is complete, then try again");
// else if (myState=="READY") llRegionSayTo(toucher,0,"Please sit to begin using me");
else if (myState=="EDIT")
{
if (toucher!=llGetOwner()) llRegionSayTo(toucher,0,"Sorry, the owner is currently editting positions and must remain in control of the dialog until this is complete.");
else startListening();
}
else if (myState=="RUNNING")
{
if ((!access) && (llListFindList(positions,[toucher])==-1)) llRegionSayTo(toucher,0,"Only current users may access the controls. Please sit, then try again");
else if ((!access) &&(ownerOnlyMenus && (toucher!=llGetOwner()))) { if (!silent) llRegionSayTo(toucher,0,"Sorry, this item is currently set to only allow the owner to access the controls.");}
else if (toucher!=user)
{
if (user==NULL_KEY)
{
if (!diaHandle) diaHandle=llListen(myChannel,"",NULL_KEY,"");
ChangeMenuUser(toucher);
}
else llDialog(toucher,"Please confirm that you want to take control of me",["TAKE CONTROL","CANCEL"],myChannel);
}
else startListening();
}
}
TEIL2: "P607 PMAC 2.8 Poser UNIVERSAL + NPC 122022.lsl" befindet sich im nächsten Artikel!!!!!!!
|
|
|
Probleme bei Mesh Häuser, Höhlen und dergleichen |
Geschrieben von: Trawell - 09.02.2024, 12:46 - Forum: Serversoftware
- Antworten (5)
|
|
Hi
und das nächste Fehlverhalten fällt mir gerade auf.
Bei Höhlen, Ruinen und solches kann ich nicht durchlaufen.
Die Eigenschaft sind weder Prim noch Konvexe Hülle (Prim steht gar nicht zur Auswahl), sondern sind bei Keiner.
Also genau gleich eingestellt wie beim Windows Server.
Ich gehe mal davon aus das dies eine Einstellung in einer der Ini Dateien sein könnte?
Eventuell hat jemand eine Idee.
Viele Grüße
Trawell
|
|
|
Fehler nach OAR Import und Region Neustart |
Geschrieben von: Trawell - 09.02.2024, 12:20 - Forum: Serversoftware
- Keine Antworten
|
|
Hallo zusammen,
ich bin grad am Testen einer Linux Installation.
Nach dem Laden einer OAR habe ich bemerkt, das dieser Opensimulator Prozess fast 7 GB RAM braucht, was ich etwas hoch finde.
Nun, könnte ja sein das dies vom Hochladen der OAR kommt.
Also starte ich die Region neu und habe folgenden Fehler:
[WARNING]: EOC marker not found. Codestream is corrupted.
Kann mir jemand sagen woher das kommt und wie ich dies beheben könnte?
Irgendwas hab ich gelesen wegen JPEG Formaten, schnall das aber grad nicht.
Zudem wenn ich die Map Generierung von Warp3dImageModule auf MapImageModule ändere, habe ich diesen Fehler nicht.
Vielen Dank und Grüße
Trawell
|
|
|
Apples Edge KI |
Geschrieben von: Cheryl Furse - 07.02.2024, 12:12 - Forum: Informationen und aktuelle Meldungen
- Keine Antworten
|
|
Hallo zusammen
gestern stand im Handelsblatt ein zweiseitiger Artikel über die KI Geheimpläne von Apple. Hier online nur die ersten Zeilen. Muss man aboniert haben um es zu lesen. Ist Bezahlschranke.
https://www.handelsblatt.com/technik/it-...10138.html
Habe aber die Papierausgabe gelesen. Hier mal etwas zusammengefasst, wie apple neue wege geht.
Da apple immer ein optimiertes rundum Paket aus Hardware und Software, wird es jetzt genauso bei KI laufen. Durch die 3 nm M Prozessoren wird es jetzt auch hardwaremässig möglich sein, wie auch bei dem spatialen Computer VisionPro. (also das was die meisten nur als headset sehen ist aber ein kompletter Computer ohne Monitor, Keyboard oder Maus. Die Skibrille ist also kein headset sondern ein neuartiger Computer)
Bei der KI wird es genauso laufen und KI wird nur noch lokal sein ohne, dass es eine Internetanbindung braucht. Also genau das was auch bei GPT4all schon möglich ist. Bei apple wird es aber weiter gehen. AI ist dann nicht einfach ein "assistent" sondern wird automatisch die Programme bedienen. Wenn apple schon soweit ist mit der AI dass es auch mathematische Modelle entwickeln kann und selber rechnen und entwickeln kann, also auch Analysen machen kann als AGI, dann wird es eine eigene Intelligenz sein. ChatGPT ist nur ein Sprachmodell, was in Wirklichkeit nicht intelligent ist sondenr nur so tut als ob. Es kann nicht selber rechnen und analysen machen. Es folgt nur einem Model, was man vorher trainiert hat. Es besteht zwar den Touring test, aber ist nur eine Simulation.
Apples Pläne gehen weiter. Und das rein nur mit dem lokalen Computer ohne Internetanbindung. Also im Sinne von dezentralität wie opensim ...
Wahrscheinlich läuft es darauf hinaus, dass man dann mit VisionPro eine Holofigur im AR sieht und mit ihr spricht, die dann alles ausführt. Man sagt dann einfach nur "mach dieses oder jenes" und die KI führt dann jeweils passend die Programme aus, die es ermöglicht.
Man klickt dann also nicht mehr auf ein Prgramm start button sondern die KI macht dann alles so wie sie es braucht und nutzt die Programme für ihrne Auftrag.
Wir kennen ja mittlerweile schon KI programme wie Genie die dann text to 3D mesh objekte generiert. Also wir sagen einfach was wir haben wollen als mesh modell und das programm generiert es in fast realtime.
Das würde dann mit Apples edge KI alles voll integriert sein und alles komplett lokal nur auf dem Computer passieren. Keine Internetanbindung. Für aufwändigere sachen auf eigener cloud abgelegt. Speicher braucht es auch und würde dann von anderen eigenen Geräten abrufbar sein. Es wäre aber nur eigener Zugriff und von keinem anderen möglich.
Die tests laufen schon seit dem M1 Max und seit dem M3 mit 3 nm technologie ist es jetzt Spruchreif und ausgereift. Bis jetzt hat Apple noch hinter dem Berg gehalten und nichts nach aussen dringen lassen. Hat erstmal alle anderen mit stümperhafter Software machen lassen, aber kommt bald selbst auf dem Markt mit ausgereifter KI
Ist ähnlich wie es beim iphone war oder jetzt visionPro als eigenem Computer und nicht nur als Headset, was Kopfschmerzen verursacht bei längerem Gebrauch.
wird spannend werden und ganz im Sinne der Dezentralität ohne Internet Abhängigkeit.
|
|
|
Vorsicht ANYDESK wurde gehackt- Risiko das euer Rechner übernommen wird |
Geschrieben von: Tron Mcp - 04.02.2024, 14:58 - Forum: Sicherheitssoftware und Hersteller
- Antworten (10)
|
|
ANYDESK Gehackt, Gefahr das eure Rechner übernommen werden, wenn ihr eine der bisherigen Versionen installiert habt.
Gestern, 03.02.2024 kamen erste Meldungen auf verschiendenen Portalen:
Der Anbieter von Remotelösungen Anydesk wurde gehackt. Der Vorfall scheint noch nicht abgeschlossen zu sein.
https://www.golem.de/news/cyberangriff-f...81848.html
Wenn ihr Anydesk installiert habt, solltet ihr es umgehen deinstallieren und abwarten bis Entwarnung gegeben, sowie eine neue Version verfügbar ist.
Warum ist das für euch gefährlich?
Nun Anydesk ist eine "Man in the Middle Lösung".
Jeder Rechner der das installiert hat meldet sich periodisch bei Anydesk das er verfügbar wäre.
Sobald jemand eine Verbindung zu euch aufnehmen will, meldet er sich bei Anydesk an, und diese vermittlen weiter.
Das ist der Grund warum es auch bei aktivierter NAT daheim noch funktioniert.
Für beide Seiten sieht es so aus wie wenn sie zu Anydesk initial die verbindung aufnehmen.
ABER: In diesem Falle bedeutet das, das die erfolgreichen Angreifer versuchen könnten als Anydesk ausgegeben auf euren Rechner zugreifen.
Deswegen hat Anydesk auch die bisher genutzen Zertifikate für ungültig erklärt.
Aber sie sind noch am kämpfen, und die Nachrichtenlage ist noch nicht vertrauenswert.
Wie bekommt ihr das unter Linux deinstalliert?
1. Der laufende Client muss gestoppt werden. Dieses geschieht in Mint über das in der rechten unteren Ecke eingeblendeten Logo. Rechtsklick drauf - beenden.
Nun verschwindet das Logo. Danach wäre euer Rechner sicher, aber beim nächsten Rechnerstart habt ihr wieder die unsichere Version laufen.
2. Nun deinstalieren wir die Software indem wir über "LM - Internet" - dann Rechtsklick auf Anydesk ausführen. Wir sehen die Option "deinstallieren" und klicken drauf.
Nun erfolgt die Passwort Abfrage eures Users, und anschließend die Deinstallation.
Wenn es eine Fehlermeldung gibt, dann öfnet man die Konsole, und meldet sich mit "su root" an und gibt sein root Passwort ein.
Danach gibt man diese Zeile ein: apt --fix-broken install und bestätigt alle Anfragen.
Nun sollte die obige Deinstallation gehen.
Anmerkung zu Anydesk:
Die Lösung an sich ist super, und extrem zuverlässig. Dumm finde ich die Informationsblockade durch Anydesk.
Die hätten von sich aus schneller warnen müssen, da es alle ihre Kunden betrifft. Das hätte Vertrauen geschaffen.
Dennoch werde ich es wieder einsetzten sobald es wieder sicher ist.
|
|
|
Maria und Lukas suchen .... |
Geschrieben von: ThunderTower - 02.02.2024, 18:06 - Forum: malugrid.eu
- Keine Antworten
|
|
Hallo liebe Leser,
Maria und Lukas suchen für unsere Rumpelbude einen männlichen oder weiblichen DJ!
Welcher DJ hat Interesse bei uns an verschiedenen Wochenenden ab 20:00 Uhr aufzulegen?
Wir lieben so diese Richtungen:
Rock, Softrock, Rock Classics, Blues, Gothic, Oldies, Pop, Schlager, Disco, House usw.
Personen unter 18 Jahren dürfen sich bei uns NICHT aufhalten und werden sofort entfernt.
Unser Dresscode für Damen und Herren:
Angemessen, entsprechend zum Club
Mit eigenem Live Stream (lizensiert) und bei Interesse bitte PN hier im Forum oder schreibt uns einfach Inworld an.
Vielen Dank
|
|
|
|