MLPV2 Ball Script with more flexible parameters
Revision as of 23: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.)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
- 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);
}
}