MLPV2 Ball Script with more flexible parameters
- MLPV2
- Back to MLPV2_Addons
<lsl>// ~capture Script V1.01 // drop into a ball // //MLPV2.4z9 //Chaz edit 2012 to give control over (1) how visible adjusting beams are, (2) how high up balls rez, and (3) and over floating text on balls //that's the only change, to make these parameters easily accessible and put them all in one section near top of script
// MLPV2 Version 2 by Learjeff Innis. Based on
// MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
// To make ball phantom, put "*" as the first character in the ball's description // or just make the ball phantom (which really works better for HUDs). // The rest of the description, if any, is used for the sit pie menu and floating text. // To make this take effect, use STOP to unrez the balls, and then select any pose.
// v2.4j - cancel old listen on rez // v2.4m - handle control keys! To enable, begin ~ball description with a plus sign ("+"), following "*" if any. // v2.4p - page up & down to enable/disable adjustment // v2.4x - moved SitTarget to top.
//chaz adjustable parameters start float AdjustBeamTransparency = 0.4; //0.1 is practically invisible; 1.0 is solid (0.0 <= alpha <= 1.0) string BallFloatingText = "";//any floating text to display above the balls vector SitTarget = <0.,0.,-.5>; // Change this to <0.,0.,-.15> or lower, to raise balls above cushion //chaz adjustable parameters end
vector SitTargetRef = <0.,0.,.1>; // Don't change this, unless you're replacing earlier versions
// with a custom SitTarget. In that case, set to match SitTarget.
integer ADJUSTABLE = FALSE; float DELTA = 0.01; // cm to move float EPSILON = 0.005; // cm position error tolerance, should be about half delta vector Offset; vector BallPos; rotation BallRot;
key NullKey = NULL_KEY;
integer Chan; integer Group; integer visible = TRUE; integer Adjusting; key Avatar; string Name; integer ListenHandle;
integer ControlsActive;
// 15 color support, thanks to Liz Silverstein // Color is passed as a string by object chat (from menu via poser*)
list colors = [ <0.0,0.0,0.0>, // 0 = HIDE
<0.835,0.345,0.482>, // 1 = PINK <0.353,0.518,0.827>, // 2 = BLUE <0.635,0.145,0.282>, // 3 = PINK2 - Dark pink <0.153,0.318,0.627>, // 4 = BLUE2 - Dark blue <0.128,0.500,0.128>, // 5 = GREEN <1.000,0.000,1.000>, // 6 = MAGENTA <1.000,0.000,0.000>, // 7 = RED <1.000,0.500,0.000>, // 8 = ORANGE <1.000,1.000,1.000>, // 9 = WHITE <0.0,0.0,0.0>, // 10 = BLACK <1.0,1.0,0.0>, // 11 = YELLOW <0.0,0.8,0.8>, // 12 = CYAN <0.5,0.0,0.0>, // 13 = RED2 <0.0,0.5,0.5>, // 14 = TEAL <0.0,0.25,0.25>]; // 15 = GREEN2
handle_control(key id, integer level, integer change) {
if (Avatar == NullKey) { return; } if ((level & CONTROL_UP) && (level & CONTROL_DOWN)) { ControlsActive = ! ControlsActive; if (ControlsActive) { control_active(); } else { control_ready(); } return; } if (!ControlsActive) { return; }
if (level & CONTROL_UP) { Offset.z += DELTA; } else if (level & CONTROL_DOWN) { Offset.z -= DELTA; } else if (level & CONTROL_LEFT) { Offset.y += DELTA; } else if (level & CONTROL_RIGHT) { Offset.y -= DELTA; } else if (level & CONTROL_FWD) { Offset.x += DELTA; } else if (level & CONTROL_BACK) { Offset.x -= DELTA; } else { return; }
llSetPos(BallPos + Offset * BallRot + SitTargetRef - SitTarget);
}
// enter "control ready" state. control_ready() {
ControlsActive = 0; integer controls = CONTROL_UP | CONTROL_DOWN;
llTakeControls(controls, TRUE, FALSE); llInstantMessage(Avatar, "Allow adjusting your position by pressing Pgup and Pgdn keys at the same time");
}
control_active() {
integer controls = CONTROL_UP | CONTROL_DOWN | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_FWD | CONTROL_BACK;
llTakeControls(controls, TRUE, FALSE); llInstantMessage(Avatar, "Adjust your position using Pgup/Pgdn, Up/Down arrow, and shift-left/right arrow keys\nDisable by pressing Pgup and Pgdn keys at the same time"); BallPos = llGetPos() + SitTarget - SitTargetRef; BallRot = llGetRot();
}
render() {
if (!visible || (Avatar != NullKey && !Adjusting)) { // hidden llSetScale(<0.01,0.01,0.01>); llSetAlpha(0.0, ALL_SIDES); llSetText(BallFloatingText,<1.0,1.0,1.0>,0.0); } else if (Avatar != NullKey && Adjusting) { // sitting and adjusting llSetAlpha(AdjustBeamTransparency,ALL_SIDES); llSetText("Adjust",<1.0,1.0,1.0>,1.0); llSetScale(<0.1,0.1,5.0>); } else { // shown llSetAlpha(1.0, ALL_SIDES); llSetScale(<0.2,0.2,0.2>); if (Adjusting) { llSetText("Adjust",<1.0,1.0,1.0>,1.0); } else { //chaz edit llSetText(BallFloatingText,<1.0,1.0,1.0>,1.0); } }
}
show() {
visible = TRUE; render();
}
hide() {
visible = FALSE; render();
}
default {
on_rez(integer channel) { Name = llGetObjectDesc(); if (Name == "" || Name == "(No Description)") { //chaz edit Name = ""; } else { if (llSubStringIndex(Name, "*") == 0) { llSetPrimitiveParams([PRIM_PHANTOM, TRUE]); Name = llGetSubString(Name, 1, -1); } if (llSubStringIndex(Name, "+") == 0) { ADJUSTABLE = TRUE; Name = llGetSubString(Name, 1, -1); } if (Name == "none") { Name = ""; } } llSitTarget(SitTarget, ZERO_ROTATION); if (Name != "") { llSetSitText(Name); } else { llSetSitText(""); } Avatar = NullKey; Chan = channel; Group = 0; if (ListenHandle) { llListenRemove(ListenHandle); ListenHandle = 0; }
if (Chan != 0) { ListenHandle = llListen(Chan,"",NullKey,""); // start timer unless ball was dragged from inv llSetTimerEvent(180.0); } if (llGetObjectDesc() == "ADJUSTABLE") { ADJUSTABLE = TRUE; } }
changed(integer change) { if (change != CHANGED_LINK) return; Avatar = llAvatarOnSitTarget(); if (Avatar != NullKey) {
if (Group) { if (!llSameGroup(Avatar)) { llUnSit(Avatar); llWhisper(0,"no permission to use poseball"); return; } } if (ADJUSTABLE) { llRequestPermissions(Avatar, PERMISSION_TAKE_CONTROLS); } } llSay(Chan+8,(string)Avatar); //requests perm, sets animation render(); }
listen(integer channel, string name, key object, string str) { integer ix; ix = llSubStringIndex(str,">"); if (ix != -1) { BallPos = (vector)llGetSubString(str,0,ix); BallRot = (rotation)llGetSubString(str,ix+1,-1); llSetPos(BallPos + SitTargetRef - SitTarget); llSetRot(BallRot); } else if (str == "0") { //HIDE hide(); } else if (str == "SHOW") { //SHOW show(); } else if (str == "ADJUST|1") { Adjusting = TRUE; render(); } else if (str == "ADJUST|0") { Adjusting = FALSE; render(); } else if (str == "SAVE") { llSay(Chan+16,(string)(llGetPos() + SitTarget - SitTargetRef)+(string)llGetRot()); } else if (str == "GROUP") { Group = 1; } else if (str == "ALL") { Group = 0; } else if (str == "DIE") { llSay(Chan+8, (string)NullKey); //msg to poser (don't reanimate after STOP) llDie(); } else if (str == "LIVE") { llSetTimerEvent(180.0); // llSay(Chan+8,"ALIVE"); //msg to poser -> to menu } else { list ldata = llParseString2List(str, ["|"], []); integer colorIx = (integer) llList2String(ldata,0); string ballIx = llList2String(ldata,1); Adjusting = (integer) llList2String(ldata,2); if ((colorIx > 0) && (colorIx < 16)) { // this must be a color setting llSetColor(llList2Vector(colors, colorIx),ALL_SIDES); //pull the color out of the list render(); llSetObjectName("~ball" + ballIx); BallPos = llGetPos() + SitTarget - SitTargetRef; BallRot = llGetRot(); } } }
timer() { //not heard "LIVE" from menu for a while: suicide llDie(); }
run_time_permissions(integer perm) { if (llKey2Name(Avatar) == "") { return; } if (Avatar != llGetPermissionsKey()) { return; }
if (perm & PERMISSION_TAKE_CONTROLS) { control_ready(); } }
moving_end() { vector newpos = llGetPos() + SitTarget - SitTargetRef; if (llVecMag(newpos - (BallPos + Offset)) > EPSILON) { // we didn't move it, someone else did. Deal with it. BallPos = newpos; } BallRot = llGetRot(); }
control(key id, integer level, integer change) { handle_control(id, level, change); }
} </LSL>