Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Auto Plant Skript
#1
Auto Plant 2.27
Automatisches erstellen von Regionen mit Objekten und Texturen.
Automatische Größenerkennung.
Es setzt 4 Terrain PBR Materialien.
Raut die Region leicht auf.
Setzt Bäume, Büsche, Farne, Todholz, Grass und Steine.

PHP-Code:
// ============================================================
// OPENSIM WALDPFLANZER SKRIPT MIT DIALOG-MENÜ
// ============================================================

// ===== GLOBALE VARIABLEN =====
integer gIntX;
integer gIntY;  
integer gIntZ;

integer gIntStartX;
integer gIntStartY;
integer gIntEndX;
integer gIntEndY;

float gFltPlantProbability;
float gFltRandMax;

// ===== START/STOP-FUNKTION =====
integer gIntRunning = FALSE;
key gKeyToucher;
integer gIntCurrentX;
integer gIntCurrentY;

// ===== PFLANZPARAMETER =====
integer PFLANZABSTAND = 6;


// ===== KOMBINIERTE LISTE FÜR ALLE OBJEKTE =====
// Format: [Name, Höhe, Priorität, X-Rotation, Y-Rotation, Z-Rotation, Z-Offset]
// Je höher die Priorität, desto wahrscheinlicher wird das Objekt ausgewählt
list ALLE_OBJEKTE = [
    
// Bäume (Priorität 30)
    
"European-Beech-tree-A", 10.0, 30, 0.0, 0.0, 0.0, 0.0,
    
"European-Beech-tree-B", 10.0, 30, 0.0, 0.0, 0.0, 0.0,
    
"European-Oak-tree", 12.0, 30, 0.0, 0.0, 0.0, 0.0,
    
    
// Büsche (Priorität 25)
    
"Buesche-1", 3.0, 25, 90.0, 0.0, 0.0, -2.00,
    
"Buesche-2", 3.0, 25, 90.0, 0.0, 0.0, -2.00,
    
"Buesche-3", 3.0, 25, 90.0, 0.0, 0.0, -2.00,
    
"Buesche-4", 3.0, 25, 90.0, 0.0, 0.0, -2.00,
    
    
// Farne (Priorität 20)
    
"Fern-1", 1.2, 20, 90.0, 0.0, 0.0, -0.70,
    
"Fern-2", 1.2, 20, 90.0, 0.0, 0.0, -0.70,
    
"Fern-3", 1.2, 20, 90.0, 0.0, 0.0, -0.70,
    
"Fern-4", 1.2, 20, 90.0, 0.0, 0.0, -0.70,
    
    
// Todholz (Priorität 15)
    
"Todholz-1", 1.5, 15, 0.0, 0.0, 0.0, -1.30,
    
"Todholz-2", 1.5, 15, 0.0, 0.0, 0.0, -1.30,
    
"Todholz-3", 1.5, 15, 0.0, 0.0, 0.0, -1.30,
    
"Todholz-4", 1.5, 15, 0.0, 0.0, 0.0, -1.30,
    
    
// Gräser (Priorität 15)
    
"Grass-1", 0.5, 15, 0.0, 0.0, 0.0, -0.10,
    
"Grass-2", 0.5, 15, 0.0, 0.0, 0.0, -0.10,
    
"Grass-3", 0.5, 15, 0.0, 0.0, 0.0, -0.10,
    
"Grass-4", 0.5, 15, 0.0, 0.0, 0.0, -0.10,
    
    
// Steine (Priorität 10)
    
"Stone-1", 0.8, 10, 0.0, 0.0, 0.0, -0.40,
    
"Stone-2", 0.8, 10, 0.0, 0.0, 0.0, -0.40,
    
"Stone-3", 0.8, 10, 0.0, 0.0, 0.0, -0.40,
    
"Stone-4", 0.8, 10, 0.0, 0.0, 0.0, -0.40
];

// ===== TERRAIN-TEXTUREN =====
float TextureLow = 10.0;
float TextureHigh = 30.0;


key Terrain_Dirt = "1e78c37b-90a1-40d3-a913-31c965309679";
key Terrain_Grass = "a9b4d0d5-5679-4fd5-b9e3-ac4367ea9b95";
key Terrain_Mountain = "795204d3-bd28-467c-b526-08b95090841e";
key Terrain_Rock = "4b012b05-a357-46af-8e6e-e8a9aa501a8c";

// key Terrain_Dirt = "9dc31f61-e30b-44bf-91dc-e4f6a8735407";
// key Terrain_Grass = "16620c30-5efd-451a-ab10-6fb3e69ad59a";
// key Terrain_Mountain = "5abbc6ef-7cb9-4340-9950-6dc61b21c99c";
// key Terrain_Rock = "429726cd-34e4-4bc9-a669-a94f2f69f11e";


// ===== DIALOG-MENÜ VARIABLEN =====
integer MENU_CHANNEL;
integer listenHandle;
string MENU_TEXT = "\nWähle eine Aktion:";
list 
MENU_BUTTONS = ["? Pflanzen", "? Terrain", "❌ Schließen"];

// ===== HILFSFUNKTIONEN =====
float getObjectHeight(string objectName)
{
    
integer index = llListFindList(ALLE_OBJEKTE, [objectName]);
    if (
index != -1)
        return 
llList2Float(ALLE_OBJEKTE, index + 1);
    return 
4.0; // Fallback-Höhe
}

float getObjectRotationX(string objectName)
{
    
integer index = llListFindList(ALLE_OBJEKTE, [objectName]);
    if (
index != -1)
        return 
llList2Float(ALLE_OBJEKTE, index + 3);
    return 
0.0; // Fallback-Rotation
}

float getObjectRotationY(string objectName)
{
    
integer index = llListFindList(ALLE_OBJEKTE, [objectName]);
    if (
index != -1)
        return 
llList2Float(ALLE_OBJEKTE, index + 4);
    return 
0.0; // Fallback-Rotation
}

float getObjectRotationZ(string objectName)
{
    
integer index = llListFindList(ALLE_OBJEKTE, [objectName]);
    if (
index != -1)
        return 
llList2Float(ALLE_OBJEKTE, index + 5);
    return 
0.0; // Fallback-Rotation
}

float getObjectZOffset(string objectName)
{
    
integer index = llListFindList(ALLE_OBJEKTE, [objectName]);
    if (
index != -1)
        return 
llList2Float(ALLE_OBJEKTE, index + 6);
    return 
0.0; // Fallback-Z-Offset
}

rotation getRotation(float gradX, float gradY, float gradZ)
{
    return 
llEuler2Rot(<gradX * DEG_TO_RAD, gradY * DEG_TO_RAD, gradZ * DEG_TO_RAD>);
}

// ===== TERRAIN-FUNKTIONEN =====
setTerrain()
{
    list 
textures = [Terrain_Dirt, Terrain_Grass, Terrain_Mountain, Terrain_Rock];
    
integer types = 2;
    
osSetTerrainTextures(textures, types);
    
    
osSetTerrainTexture(0, Terrain_Dirt);
    
osSetTerrainTextureHeight(0, TextureLow, TextureHigh);
    
osSetTerrainTexture(1, Terrain_Grass);
    
osSetTerrainTextureHeight(1, TextureLow, TextureHigh);
    
osSetTerrainTexture(2, Terrain_Mountain);
    
osSetTerrainTextureHeight(2, TextureLow, TextureHigh);
    
osSetTerrainTexture(3, Terrain_Rock);
    
osSetTerrainTextureHeight(3, TextureLow, TextureHigh);
    
    
llModifyLand(LAND_NOISE, 0);
    
osTerrainFlush();
    
    
llOwnerSay("✅ Terrain-Texturen wurden gesetzt und aufgeraut!");
}

// ===== PFLANZEN-FUNKTIONEN =====
plantOneTree()
{
    if (!
gIntRunning) return;
    
    if (
gIntCurrentX >= gIntEndX || gIntCurrentY >= gIntEndY)
    {
        
gIntRunning = FALSE;
        
llOwnerSay("✅ Pflanzvorgang abgeschlossen!");
        
llSetText("Fertig - Klicke für neues Menü", <0,1,0>, 1.0);
        
llSetTimerEvent(0.0);
        return;
    }
    
    
gIntX = gIntCurrentX;
    
gIntY = gIntCurrentY;
    
    
llSetRegionPos(<gIntX, gIntY, gIntZ>);
    
llSetText("X: " + (string)gIntX + " Y: " + (string)gIntY, <1,1,1>, 1.0);
    
    
// 1. Zufällig entscheiden, ob überhaupt etwas gepflanzt wird
    
float fltDoIRez = llFrand(1.0);
    if (
fltDoIRez >= gFltPlantProbability) 
    {
        
gIntCurrentY += PFLANZABSTAND;
        if (
gIntCurrentY >= gIntEndY)
        {
            
gIntCurrentY = gIntStartY + (PFLANZABSTAND / 2);
            
gIntCurrentX += PFLANZABSTAND;
        }
        return;
    }
    
    
// ===== GEWICHTETE AUSWAHL MIT ÜBERSPRINGEN FEHLENDER OBJEKTE =====
    
    // 1. Liste der verfügbaren Objekte erstellen (nur die, die im Inventar sind)
    
list verfuegbareObjekte = [];
    
integer listLength = llGetListLength(ALLE_OBJEKTE) / 7;
    
integer i;
    
    for (
i = 0; i < listLength; i++)
    {
        
string objName = llList2String(ALLE_OBJEKTE, i * 7);
        
// Prüfen, ob Objekt im Inventar existiert
        
if (llGetInventoryType(objName) == INVENTORY_OBJECT)
        {
            
float objHeight = llList2Float(ALLE_OBJEKTE, (i * 7) + 1);
            
integer objPriority = llList2Integer(ALLE_OBJEKTE, (i * 7) + 2);
            
float objRotationX = llList2Float(ALLE_OBJEKTE, (i * 7) + 3);
            
float objRotationY = llList2Float(ALLE_OBJEKTE, (i * 7) + 4);
            
float objRotationZ = llList2Float(ALLE_OBJEKTE, (i * 7) + 5);
            
float objZOffset = llList2Float(ALLE_OBJEKTE, (i * 7) + 6);
            
verfuegbareObjekte += [objName, objHeight, objPriority, objRotationX, objRotationY, objRotationZ, objZOffset];
        }
        
// Wenn nicht im Inventar: einfach überspringen
    
}
    
    
// Falls keine Objekte verfügbar sind
    
if (llGetListLength(verfuegbareObjekte) == 0)
    {
        
llOwnerSay("⚠️ Keine Objekte im Inventar gefunden!");
        
gIntRunning = FALSE;
        
llSetTimerEvent(0.0);
        return;
    }
    
    
// 2. Gesamtgewicht der verfügbaren Objekte berechnen
    
integer availableCount = llGetListLength(verfuegbareObjekte) / 7;
    
integer totalWeight = 0;
    for (
i = 0; i < availableCount; i++)
    {
        
totalWeight += llList2Integer(verfuegbareObjekte, (i * 7) + 2);
    }
    
    
// 3. Zufällige Auswahl basierend auf Gewicht
    
integer randomWeight = (integer)llFrand(totalWeight);
    
integer selectedIndex = 0;
    
integer cumulativeWeight = 0;
    
    for (
i = 0; i < availableCount; i++)
    {
        
integer priority = llList2Integer(verfuegbareObjekte, (i * 7) + 2);
        
cumulativeWeight += priority;
        if (
randomWeight < cumulativeWeight)
        {
            
selectedIndex = i;
            
i = availableCount; // Schleife manuell beenden (statt break)
        
}
    }
    
    
// 4. Objekt auswählen und pflanzen
    
string gStrObjectName = llList2String(verfuegbareObjekte, selectedIndex * 7);
    
float objectHeight = llList2Float(verfuegbareObjekte, (selectedIndex * 7) + 1);
    
float rotationX = llList2Float(verfuegbareObjekte, (selectedIndex * 7) + 3);
    
float rotationY = llList2Float(verfuegbareObjekte, (selectedIndex * 7) + 4);
    
float rotationZ = llList2Float(verfuegbareObjekte, (selectedIndex * 7) + 5);
    
float zOffset = llList2Float(verfuegbareObjekte, (selectedIndex * 7) + 6);
    
    
// Position und Rotation setzen
    
vector vecNowPos = llGetPos();
    
float fltLandHeight = osGetTerrainHeight((integer)vecNowPos.x, (integer)vecNowPos.y);
    
    
integer intNewX = (integer)vecNowPos.x;
    
integer intNewY = (integer)vecNowPos.y;
    
integer intNewZ = (integer)fltLandHeight;
    
    
vecNowPos = <intNewX, intNewY, intNewZ>;
    
llSetRegionPos(vecNowPos);
    
    
// Rotation basierend auf Objekt-Einstellungen
    
rotation objectRotation = getRotation(rotationX, rotationY, rotationZ);
    
    
// Objekt rezzieren mit Höhenanpassung
    
llRezObject(gStrObjectName, 
                
llGetPos() + <0.0, 0.0, objectHeight + zOffset>,
                <
0.0, 0.0, 0.0>,
                
objectRotation,
                
0);
    
llModifyLand(LAND_NOISE, 0); // Dabei direkt das Terrain aufrauhen.
    
llSleep(0.1);
    
    
// Debug-Ausgabe (optional - auskommentieren wenn nicht benötigt)
    // llOwnerSay("? " + gStrObjectName + " | X-Rot: " + (string)rotationX + "° | Y-Rot: " + (string)rotationY + "° | Z-Rot: " + (string)rotationZ + "° | Z-Off: " + (string)zOffset);
    
    // Zur nächsten Position
    
gIntCurrentY += PFLANZABSTAND;
    if (
gIntCurrentY >= gIntEndY)
    {
        
gIntCurrentY = gIntStartY + (PFLANZABSTAND / 2);
        
gIntCurrentX += PFLANZABSTAND;
    }
}

startPlanting()
{
    
vector regionSize = osGetRegionSize();
    
gIntStartX = 0;
    
gIntStartY = 0;
    
gIntEndX = (integer)regionSize.x;
    
gIntEndY = (integer)regionSize.y;
    
    
gFltPlantProbability = .7; // 70% Wahrscheinlichkeit für Bewuchs
    
gIntZ = 0;
    
    
gIntRunning = TRUE;
    
gIntCurrentX = gIntStartX + (PFLANZABSTAND / 2);
    
gIntCurrentY = gIntStartY + (PFLANZABSTAND / 2);
    
    
// Anzahl der verfügbaren Objekte zählen
    
integer availableCount = 0;
    
integer listLength = llGetListLength(ALLE_OBJEKTE) / 7;
    
integer i;
    for (
i = 0; i < listLength; i++)
    {
        
string objName = llList2String(ALLE_OBJEKTE, i * 7);
        if (
llGetInventoryType(objName) == INVENTORY_OBJECT)
            
availableCount++;
    }
    
    
llOwnerSay("? Starte Pflanzvorgang mit " + (string)availableCount + " verfügbaren Objekten...");
    
llSetText("? Pflanze... Klicke zum Stoppen", <1,1,0>, 1.0);
    
    
llSetTimerEvent(2.0);
}

// ===== HAUPTTEIL DES SKRIPTS =====
default
{
    
state_entry()
    {
        
MENU_CHANNEL = -1 - (integer)("0x" + llGetSubString((string)llGetKey(), -7, -1));
        
llOwnerSay("? Waldpflanzer bereit. Klicke für Menü.");
        
llSetText("Bereit - Klicke für Menü", <0,1,0>, 1.0);
        
llSetTimerEvent(0.0);
    }
    
    
touch_start(integer num_detected)
    {
        if (
gIntRunning)
        {
            
gIntRunning = FALSE;
            
llSetTimerEvent(0.0);
            
llListenRemove(listenHandle);
            
llOwnerSay("⏹️ Pflanzvorgang wurde gestoppt!");
            
llSetText("Gestoppt - Klicke für neues Menü", <1,0,0>, 1.0);
            return;
        }
        
        
key toucher = llDetectedKey(0);
        
llListenRemove(listenHandle);
        
listenHandle = llListen(MENU_CHANNEL, "", toucher, "");
        
llDialog(toucher, MENU_TEXT, MENU_BUTTONS, MENU_CHANNEL);
        
llSetTimerEvent(60.0);
    }
    
    
listen(integer channel, string name, key id, string message)
    {
        
llSetTimerEvent(0.0);
        
llListenRemove(listenHandle);
        
        if (
message == "? Pflanzen")
        {
            
llOwnerSay("? Starte Pflanzvorgang...");
            
startPlanting();
        }
        else if (
message == "? Terrain")
        {
            
setTerrain();
            
llDialog(id, "✅ Terrain-Texturen wurden aktualisiert.", ["OK"], MENU_CHANNEL);
        }
        else if (
message == "❌ Schließen")
        {
            
llOwnerSay("Menü geschlossen.");
        }
        else if (
message == "OK")
        {
            
llOwnerSay("✅ OK.");
        }
    }
    
    
timer()
    {
        if (
gIntRunning)
        {
            
plantOneTree();
        }
        else
        {
            
llSetTimerEvent(0.0);
        }
    }
} 

Fazit: Es wird ein Zufallswald erstellt und ist noch nicht ganz fertig, zur Demo ist das aber schon gut genug.
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



Zitieren


Nachrichten in diesem Thema
Auto Plant Skript - von Manfred Aabye - 21.07.2026, 07:49
RE: Auto Plant Skript - von Ezry Aldrin - 21.07.2026, 18:52
RE: Auto Plant Skript - von Manfred Aabye - 21.07.2026, 20:00
RE: Auto Plant Skript - von Ezry Aldrin - 21.07.2026, 22:42
RE: Auto Plant Skript - von Manfred Aabye - 22.07.2026, 00:13
RE: Auto Plant Skript - von Ezry Aldrin - 22.07.2026, 00:40
RE: Auto Plant Skript - von Manfred Aabye - 22.07.2026, 18:50
RE: Auto Plant Skript - von Mareta Dagostino - 22.07.2026, 20:36
RE: Auto Plant Skript - von Manfred Aabye - 23.07.2026, 11:26
RE: Auto Plant Skript - von Mareta Dagostino - 23.07.2026, 20:26
RE: Auto Plant Skript - von Manfred Aabye - 24.07.2026, 18:20
RE: Auto Plant Skript - von Ezry Aldrin - 24.07.2026, 21:34
RE: Auto Plant Skript - von Manfred Aabye - 25.07.2026, 07:59
RE: Auto Plant Skript - von Manfred Aabye - 26.07.2026, 09:42
RE: Auto Plant Skript - von Ezry Aldrin - 28.07.2026, 21:30
RE: Auto Plant Skript - von Ezry Aldrin - 28.07.2026, 23:07

Möglicherweise verwandte Themen…
Thema Verfasser Antworten Ansichten Letzter Beitrag
  skript für opensim gesucht hajo drechsler 3 2.022 18.12.2025, 15:47
Letzter Beitrag: hajo drechsler
  Skript stoppt bei Neustart und Daten weg Manfred Aabye 0 1.177 16.11.2025, 13:43
Letzter Beitrag: Manfred Aabye
  ATM Money Skript LSL Manfred Aabye 0 2.500 03.11.2024, 14:29
Letzter Beitrag: Manfred Aabye
  Secure Skript Manfred Aabye 6 7.338 26.04.2022, 18:51
Letzter Beitrag: Manfred Aabye
  YEngine Skript Restart Manfred Aabye 6 6.634 15.03.2022, 12:43
Letzter Beitrag: Manfred Aabye

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste