~Fiona's Script Library~
kick.lsl
| 4.23 KB
// Copyright 2025 Fiona Sweet - Free to use for any purpose
// StageGuard.lsl — OpenSim/LSL
// Put this in an invisible prim that surrounds your stage.
// Set the prim to PHANTOM. The script turns on volume-detect.
// =================== CONFIG ===================
list ALLOWED = [
// Add avatar UUIDs here (strings)
"78e7a55f-5c3d-4e5f-9a20-2026adba8660", //Niki Stark
"ededfb98-67d2-46ac-ab74-6a67f7660667" //Prim
];
integer ALLOW_OWNER = FALSE; // let the prim's owner always pass
integer ALLOW_ESTATE = FALSE; // let estate managers/owners pass (requires os* estate checks)
integer ALLOW_GROUP = FALSE; // if TRUE, allow avatars in the prim's group
vector SAFE_POS = <86.0, 151.0, 30.0>; // where to send unauthorized avatars
integer SHOW_DEBUG = FALSE; // TRUE shows renter/allowed hint hovertext
string DENY_MSG = "Sorry, the stage is restricted. Teleporting you back to the audience area.";
// Optional: if your grid doesn’t allow osTeleportAgent or you want a fallback,
// set USE_PUSH_FALLBACK = TRUE to gently push people out instead of teleporting.
integer USE_PUSH_FALLBACK = FALSE;
float PUSH_STRENGTH = 10.0;
// ==============================================
// ---- internal state ----
integer gArmed = TRUE; // touch to toggle on/off
integer isAllowed(key av)
{
// skip non-avatars
if (llGetAgentSize(av) == ZERO_VECTOR) return TRUE;
// Owner bypass
if (ALLOW_OWNER && av == llGetOwner()) return TRUE;
// Estate manager/owner bypass (OpenSim OSSL)
// Not all grids expose an API for this in LSL; commonly you’d whitelist staff in ALLOWED.
// If you have osIsEstateManager, uncomment this block:
// if (ALLOW_ESTATE && osIsEstateManager(av)) return TRUE;
// Group check
if (ALLOW_GROUP && llSameGroup(av)) return TRUE;
// Explicit allow list
if (~llListFindList(ALLOWED, [ (string)av ])) return TRUE;
return FALSE;
}
teleportOut(key av)
{
// Teleport (preferred)
if (!USE_PUSH_FALLBACK)
{
// OSSL: requires sufficient threat level (usually estate powers).
osTeleportAgent(av, SAFE_POS, ZERO_VECTOR);
llInstantMessage(av, DENY_MSG);
return;
}
// Fallback push (no OSSL)
vector dir = llVecNorm(SAFE_POS - llGetPos());
if (dir == ZERO_VECTOR) dir = <1,0,0>;
llPushObject(av, dir * PUSH_STRENGTH, ZERO_VECTOR, FALSE);
llInstantMessage(av, DENY_MSG);
}
refreshDebug()
{
if (SHOW_DEBUG)
{
string txt = "StageGuard: " + (gArmed ? "ARMED" : "DISARMED")
+ "\nAllowed: " + (string)llGetListLength(ALLOWED)
+ (ALLOW_GROUP ? " + group" : "")
+ (ALLOW_OWNER ? " + owner" : "")
+ (ALLOW_ESTATE ? " + estate" : "");
llSetText(txt, <1,1,0>, 1.0);
}
else llSetText("", ZERO_VECTOR, 0.0);
}
default
{
state_entry()
{
// make sure we're a volume detector
llVolumeDetect(TRUE);
refreshDebug();
}
on_rez(integer p)
{
llResetScript();
}
// Touch to arm/disarm quickly (for builders)
touch_start(integer n)
{
key who = llDetectedKey(0);
// Only owner can toggle
if (who != llGetOwner()) return;
gArmed = !gArmed;
llOwnerSay("StageGuard is now " + (gArmed ? "ARMED" : "DISARMED") + ".");
refreshDebug();
}
// When someone enters the stage volume
collision_start(integer n)
{
if (!gArmed) return;
integer i;
for (i = 0; i < n; ++i)
{
key av = llDetectedKey(i);
// ignore non-avatars (objects)
if (llGetAgentSize(av) == ZERO_VECTOR)
jump next;
if (!isAllowed(av))
{
teleportOut(av);
}
@next;
}
}
// Keep sweeping while they remain in the volume (optional safety)
collision(integer n)
{
if (!gArmed) return;
integer i;
for (i = 0; i < n; ++i)
{
key av = llDetectedKey(i);
if (llGetAgentSize(av) == ZERO_VECTOR)
jump next2;
if (!isAllowed(av))
{
teleportOut(av);
}
@next2;
}
}
}