MLPV2 Ball Script with more flexible parameters
Revision as of 22:46, 23 February 2016 by ErikoLeo Resident (talk | contribs) (Added the missing </source> tag, removed the </lsl> and </LSL> obsolete(?) ones. The whole script now displays correctly.)
- 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);
}
}