MLPV2 Ball Script with more flexible parameters

* MLPV2
* Back to MLPV2_Addons
// ~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);
 }
}
Category:MLPV2