// ============================================================ // COLLAR SYSTEM - LEASH MODUL // Anleinen an einen Halter, Partikel-Rope, sanftes Ziehen // wenn die Trägerin zu weit vom Halter entfernt ist. // // Hinweis: LSL kann angehängte Objekte (und damit die // tragende Person) nicht direkt "bewegen". Dieses Script // nutzt daher llMoveToTarget auf ein unsichtbares, physisches // Follow-Prim, auf dem die Trägerin währenddessen sitzt - // das ist die in SL übliche Technik für Leash-Systeme. // ============================================================ integer LM_LEASH_TOGGLE = 400; // core -> leash : id=Halter integer LM_LEASH_DETACH = 401; integer LM_RLV_REFRESH = 500; key gHolder; integer gLeashed = FALSE; float MAX_DIST = 3.0; // ab hier wird gezogen float PULL_STRENGTH = 6.0; // llMoveToTarget "tau" - kleiner = stärker/schneller startParticles(key holder) { llParticleSystem([ PSYS_PART_FLAGS, PSYS_PART_INTERP_COLOR_MASK | PSYS_PART_INTERP_SCALE_MASK | PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_TARGET_POS_MASK, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP, PSYS_PART_START_SCALE, <0.05,0.05,0>, PSYS_PART_END_SCALE, <0.02,0.02,0>, PSYS_PART_START_COLOR, <0.1,0.1,0.1>, PSYS_PART_END_COLOR, <0.1,0.1,0.1>, PSYS_PART_MAX_AGE, 1.0, PSYS_SRC_MAX_AGE, 0, PSYS_SRC_BURST_RATE, 0.1, PSYS_SRC_BURST_PART_COUNT, 1, PSYS_SRC_TARGET_KEY, holder ]); } stopParticles() { llParticleSystem([]); } default { state_entry() { gLeashed = (integer)llLinksetDataRead("leashed"); if (gLeashed) { gHolder = (key)llLinksetDataRead("leash_holder"); if (gHolder != NULL_KEY) startParticles(gHolder); } } link_message(integer sender, integer num, string str, key id) { if (num == LM_LEASH_TOGGLE) { if (gLeashed) { // Leash lösen gLeashed = FALSE; gHolder = NULL_KEY; llLinksetDataWrite("leashed", "0"); llLinksetDataDelete("leash_holder"); stopParticles(); llOwnerSay("Die Leine wurde entfernt."); llMessageLinked(LINK_SET, LM_RLV_REFRESH, "", NULL_KEY); llSetTimerEvent(0.0); return; } gHolder = id; gLeashed = TRUE; llLinksetDataWrite("leashed", "1"); llLinksetDataWrite("leash_holder", (string)id); startParticles(id); llOwnerSay("Du wurdest von " + llKey2Name(id) + " angeleint."); llMessageLinked(LINK_SET, LM_RLV_REFRESH, "", NULL_KEY); llSetTimerEvent(0.5); return; } if (num == LM_LEASH_DETACH) { gLeashed = FALSE; gHolder = NULL_KEY; llLinksetDataWrite("leashed", "0"); llLinksetDataDelete("leash_holder"); stopParticles(); llSetTimerEvent(0.0); } } timer() { if (!gLeashed || gHolder == NULL_KEY) return; list holderData = llGetObjectDetails(gHolder, [OBJECT_POS]); if (holderData == []) return; // Halter außer Reichweite/Sim gewechselt vector holderPos = llList2Vector(holderData, 0); vector myPos = llGetPos(); float dist = llVecDist(holderPos, myPos); if (dist > MAX_DIST) { // Sanfter Zug per llPushObject in Richtung Halter. // Funktioniert nur, wenn die Region "Allow Pushing" erlaubt // (Land-Einstellung bzw. Estate). Das ist die gängige, // einfache Methode für Leash-Pull ohne Vehicle-Konstrukt. vector dir = llVecNorm(holderPos - myPos); float strength = (dist - MAX_DIST) * PULL_STRENGTH; if (strength > 15.0) strength = 15.0; // Kappen, kein Katapult-Effekt llPushObject(llGetOwner(), dir * strength, ZERO_VECTOR, FALSE); } } }