Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discussion: MLP - Multi-love-pose

Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
05-15-2006 03:06
MLP - MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)

FEATURES:
- Put all your poseball animations into one object (50 pairs or even more should be no problem).
- Create submenu's for each category of poses, for instance: "Lovers, Boy-Girl, Girl-Girl, Self, Solo, Dance"
- Shows 1 or 2 poseballs depending on the submenu you select
- Positions can be adjusted and saved into memory (backup is easy: select Memory Dump and copy-paste into notecard)
- Portable, can be worn and used everywhere
- Option to adjust height offset (Z) of all poses at once (for different persons/locations).

The BSD Licence allows anybody to use the source code, in any manner they wish, providing that they provide the copyright notice above on further distributions.
So it's totally free, however if you like it, I would be very happy if you donate any L$ (even L$1 as a thank you). If you're using significant parts of this code in commercial products, I would appreciate if you donate me L$1 for each sold product (or more) I won't give support, however I'll make an exception for end-users that donated L$1000 or more (for commercial support, custom versions, contact me).
To donate, go to my profile (Find - People - Miffy Fluffy) and use the "Pay..." button, thanks!

Pickup a copy in SL (free). For the location of the latest version check my profile (Find - People - Miffy Fluffy - Picks), this saves you a lot of work :)

~run script:
CODE
//MLP MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
//To donate, go to my profile (Find - People - Miffy Fluffy) and use the "Pay..." button, thanks!
//You can also find the link to the latest version here.

// DESCRIPTION OF THE SCRIPTS
//
// ~run:
// Default: sets other scripts to not running.
// When the object is touched it will start all scrips.
//
// ~memory:
// Here the positions are stored permanently. Information is still kept when the script is
// not running or when everything is placed in inventory. The information will be lost only
// when the ~memory script is reset.
// A backup can be made on the .POSITIONS notecard, when the memory is empty, it will start
// reading the .POSITIONS notecard automatically.
//
// ~menu:
// 1.loading: reads the .MENUITEMS notecard and builds the menu.
// When it reads a "POSE": - the animations are stored in ~pose
// - their matching positions are looked up in ~memory and stored
// in ~pos.
// 2.ready:
// When the object is touched: - shows the main menu
// - listens for menu selections.
//
// When a submenu is selected: - shows the submenu
// - when balls are defined for this submenu it will rez
// balls (if not already there) and set their colors.
//
// When a pose is selected: - ~pose will send the animations to ~pose1 and ~pose2,
// they will set the animations to the avatars
// - ~pos wil send the matching positions to each ball.
//
// When a position is saved: - ~pose will ask the balls for their position
// - the positions are saved in ~memory ("permanent")
// - the positions are updated in ~pos
//
// When "STOP" is selected: - will hide the balls
// - will stop the pose
// When "STOP" is selected again (or if no pose is started yet):
// - will remove the balls (derez/die)
//
// ~pos:
// - loads the positions from ~memory and stores them (until shutdown/restart)
// - sends positions for the selected pose to the balls
//
// ~pose:
// - loads the animations from the .MENUITEMS notecard and stores them (until shutdown/restart)
// - sends animations for the selected pose to ~pose1 and ~pose2
// - when saving a position: will ask balls for their position and sends it to ~pos and ~memory
// (~pos would be a more logical place to handle this, but ~pose has more free memory).
//
// ~pose1 & pose2:
// - will ask permission to animate the avatar on ball 1&2
// - will set the animations to avatar 1&2
//
// ~ball
// - when balls are defined for a submenu (in .MENUITEMS), ~menu will rez two copies of ~ball
// - ball 1&2 will receive a unique communication channel from ~menu
// - the color for ball 1&2 is set by ~menu
// - the position of ball 1&2 is set by ~pos
// - when an avatar selects to sit on a ball, the avatar info is sent to ~pose1 or ~pose2, they
// will ask permission and set the animation directly to the avatar (not via the ball)
// - balls will commit suicide when they don't hear a "LIVE" message each minute (from ~menu).
//
// have fun!

//Note: if you make a revised version, please mention something like this:
//"MLP - alternative version by ... .... - Revision 1 (based on MLP 1.0 by Miffy Fluffy)

setRunning(integer st) {
llSetScriptState("~menu", st);
llSetScriptState("~pos", st);
llSetScriptState("~pose", st);
llSetScriptState("~pose1", st);
llSetScriptState("~pose2", st);
llResetOtherScript("~menu");
llSetScriptState("~memory", TRUE);
}
default {
state_entry() {
llOwnerSay("OFF (touch to switch on)");
setRunning(FALSE);
}
touch_start(integer i) {
if (llDetectedKey(0) == llGetOwner()) state run;
}
}
state run {
state_entry() {
llOwnerSay("Starting...");
setRunning(TRUE);
}
}


~memory script:
CODE

//MLP MULTI-LOVE-POSE 1.03 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer i;
integer j;
integer line;
integer p;
string pose;
list poses;
list positions;

default {
state_entry() {
llOwnerSay("Memory is empty, loading notecard: .POSITIONS");
llGetNotecardLine(".POSITIONS",0); //read first line of positions notecard
}
dataserver(key query_id, string data) {
if (data == EOF) state on;
if (llGetSubString(data,2,2) == ":" || llGetSubString(data,3,3) == ":") data = llGetSubString(data, 6,-1); //remove time stamp
i = llSubStringIndex(data,"["); //split name from positions, remove junk
j = llSubStringIndex(data,"] <");
if (i != -1 && j != -1) {
//poses += [ llGetSubString(data, i+1, j - 1) ];
//positions += [ llGetSubString(data, j+2, -1) ];
poses = [ llGetSubString(data, i+1, j - 1) ] + (poses = []) + poses; //saves memory
positions = [ llGetSubString(data, j+2, -1) ] + (positions = []) + positions; //saves memory
++p;
}
++line;
llGetNotecardLine(".POSITIONS",line); //read next line of positions notecard
}
state_exit() {
llOwnerSay((string)p+" positions stored in memory ("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free)");
if (p < 2) {
poses = [ "stand","default" ];
positions = [ "<-0.7,0.0,0.5> <0.0,0.0,0.0> <0.7,0.0,0.5> <0.0,0.0,-180.0>",
"<-0.8,0.0,0.4> <0.0,0.0,0.0> <0.8,0.0,0.4> <0.0,0.0,-180.0>" ];
p = 2;
}
llMessageLinked(LINK_THIS,2,"OK",NULL_KEY); //msg to menu, in case it's waiting for loading
}
}
state on {
link_message(integer from, integer num, string str, key dkey) {
if (num != 1) return;
if (str == "OK?") { //question from menu, before loading menu
llMessageLinked(from,2,"OK",NULL_KEY); //answer to menu
} else if (str == "LOADED") { //msg from menu: loaded
llMessageLinked(from,3,"LOADED",dkey); //forward msg to pos
} else if (str == "DUMP") {
llOwnerSay("_______________________________________________________________________________");
llOwnerSay("");
llOwnerSay("Copy to notecard: .POSITIONS");
llOwnerSay("_______________________________________________________________________________");
llOwnerSay("");
//for (i=0; i < p; ++i) llOwnerSay("["+llList2String(poses,i)+"] "+llList2String(positions,i));
for (i=p - 1; i>=0; --i) llOwnerSay("["+llList2String(poses,i)+"] "+llList2String(positions,i));
} else {
i = llListFindList(poses,[ str ]); //find pose
if (llGetSubString((string)dkey,0,0) == "<") { //SAVE
if (i != -1) {
positions = llListReplaceList(positions,[ (string)dkey ],i,i);
llOwnerSay("["+str+"] position updated in memory");
} else {
//poses += [ str ];
//positions += [ (string)dkey ];
poses = [ str ] + (poses = []) + poses; //saves memory
positions = [ (string)dkey ] + (positions = []) + positions; //saves memory
++p;
llOwnerSay("["+str+"] position added to memory");
}
llOwnerSay("("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free, "+(string)p+" positions)");
} else { //LOAD
//if (i == -1) i = 1; //not found, send default (-1 if save mem)
llMessageLinked(from,3,llList2String(positions,i),dkey); //msg to pos: sent position
}
}
}
}


~menu script:
CODE

//MLP MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer PINK1 = 1; //0001 binary
integer BLUE1 = 2; //0010 binary
integer PINK2 = 4; //0100 binary
integer BLUE2 = 8; //1000 binary
integer a;
integer all;
integer b;
integer b0;
integer ch;
integer chat;
integer i;
integer line;
integer menu;
integer redo;
integer rez;
integer swap;
integer visible;
float alpha;
string cmd;
string pose;
string pose0;
key owner;
key user;
list buttons;
list buttonindex;
list commands;
list mbuttons;
list menus;
list balls;
list users;

//menu partly based on Menu Engine by Zonax Delorean (BSD License)
//llDialog(user, menuname, buttons(from index to nextindex-1), channel)
doMenu() {
b0 = llList2Integer(buttonindex, menu); //position of first button for this (sub)menu
b = llList2Integer(buttonindex, menu+1); //position of first button for next (sub)menu
mbuttons = llList2List(buttons, b0, b - 1); //buttons for this (sub)menu
llDialog(user, llList2String(menus,menu), mbuttons, ch - 1);
b = llList2Integer(balls,menu); //ballcolors
if (b) { //if submenu includes ballcolor(s):
if (!rez) rezBalls(); //if no balls present: create balls
llSay(ch,(string)(b & 3)); //ball1color: mask with 3 = 0011 binary
llSay(ch+1,(string)(b >> 2)); //ball2color: shift 2 bits to the right
}
}
say(string str) {
if (all) llWhisper(0,str);
else llOwnerSay(str);
}
setBalls(string cmd) {
llSay(ch,cmd); //msg to balls
llSay(ch+1,cmd);
}
rezBalls() {
setBalls("DIE");
llRezObject("~ball",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,ch);
llRezObject("~ball",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,ch+1);
llMessageLinked(LINK_THIS,0,"REPOS",NULL_KEY); //msg to pos
llMessageLinked(LINK_THIS,0,"POSE","0"); //msg to pos/pose
rez = 1;
pose = pose0;
}

default {
state_entry() {
llSetScriptState("~run", TRUE);
llResetOtherScript("~pos");
llResetOtherScript("~pose");
llResetOtherScript("~pose1");
llResetOtherScript("~pose2");
ch = (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
setBalls("DIE");
owner = llGetOwner();
alpha = llGetAlpha(0); //store object transparancy (alpha)
if (alpha < 0.1) alpha = 0.5; else visible = 1; //if invisible store a visible alpha
llMessageLinked(LINK_THIS,1,"OK?",NULL_KEY); //msg to memory: ask if ready
}
link_message(integer from, integer num, string str, key id) {
if (num == 2) state load; //memory ready
}
}
state load {
state_entry() {
llGetNotecardLine(".MENUITEMS",0); //read first line of menuitems notecard
}
dataserver(key query_id, string data) {
if (data == EOF) state on;
i = llSubStringIndex(data,"//"); //remove comments
if (i != -1) {
if (i == 0) data = "";
else data = llGetSubString(data, 0, i - 1);
}
while (llGetSubString(data, -1, -1) == " ") data = llDeleteSubString(data, -1, -1); //remove spaces from end
if (data != "") {
i = llSubStringIndex(data," ");
cmd = data;
if (i != -1) { //split command from data
cmd = llGetSubString(data, 0, i - 1);
data = llGetSubString(data, i+1, -1);
}
list ldata = llParseString2List(data,[" | "," |","| ","|"],[]);
data = llList2String(ldata, 0);
if (cmd == "MENU") {
llOwnerSay("loading data for '"+data+"'");
if (!menu) { //main menu
if (!a) llOwnerSay("warning: first item in .MENUITEMS must be: POSE stand");
if (a<=1) llOwnerSay("warning: second item in .MENUITEMS must be: POSE default");
} else {
if (llList2String(ldata, 1) == "OWNER") menu = 0; //0 = owner only, 1 = all users
pose = llList2String(ldata, 2);
if (pose == "PINK") rez = PINK1;
else if (pose == "BLUE") rez = BLUE1;
pose = llList2String(ldata, 3);
if (pose == "PINK") rez += PINK2;
else if (pose == "BLUE") rez += BLUE2;
}
menus += [ data ];
balls += [ rez ];
buttonindex += [ b ];
users += [ menu ];
rez = 0;
b0 = 0;
menu = 1;
} else if (b0 < 12) { //maximum 12 buttons per menu
if (cmd == "POSE") {
llMessageLinked(LINK_THIS,1,data,(string)a); //msg to memory
llMessageLinked(LINK_THIS,9+a,llList2String(ldata, 1),llList2String(ldata, 2)); //msg to pose
if (!a) pose0 = data;
cmd = (string)a;
++a;
} else if (cmd == "REDO") {
if (llList2String(ldata, 1) == "ON") redo = 1;
} else if (cmd == "CHAT") {
if (llList2String(ldata, 1) == "ON") chat = 1;
} else if (cmd == "USERS") {
if (llList2String(ldata, 1) == "ON") all = 1;
}
commands += [ cmd ];
buttons += [ data ];
++b;
++b0;
}
}
++line;
llGetNotecardLine(".MENUITEMS",line); //read next line of menuitems notecard
}
state_exit() {
buttonindex += [ b ]; //enter last buttonindex
llOwnerSay((string)b+" menuitems loaded ("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free)");
llMessageLinked(LINK_THIS,1,"LOADED",(string)a); //msg to memory
llMessageLinked(LINK_THIS,9+a,"LOADED",NULL_KEY); //msg to pose
}
}
state on {
state_entry() {
llListen(ch - 1, "", user, ""); //listen for pressed buttons
llSetTimerEvent(59);
}
touch_start(integer i) {
user = llDetectedKey(0);
if (all || user == owner) {
menu = 0; doMenu(); //mainmenu
}
}
listen(integer channel, string name, key user, string button) {
if (button == "DIE") { menu = 0; rez = 0; return; } //suicide msg from ball
b = b0 + llListFindList(mbuttons,[ button ]); //find position of cmd
string cmd = llList2String(commands,b); //get command
//llSay(0,button+" "+cmd); //debug
if (cmd == "TOMENU") {
menu = llListFindList(menus,[ button ]); //find submenu
if (menu == -1) return;
if (user == owner || llList2Integer(users, menu)) {
doMenu(); return;
}
llWhisper(0,button+" menu deactivated (access by owner only)");
menu = 0;
} else if (cmd == "BACK") {
menu = 0; doMenu(); //mainmenu
return;
} else if ((integer)cmd > 0) { //POSE
llMessageLinked(LINK_THIS,0,"POSE",cmd); //msg to pos/pose
if (chat) say(button);
pose = button;
} else if (cmd == "SWAP") {
llMessageLinked(LINK_THIS,0,"SWAP",NULL_KEY); //msg to pos/pose
swap = !swap;
} else if (cmd == "STOP") {
llMessageLinked(LINK_THIS,0,"POSE","0"); //msg to pos/pose
if (pose != pose0) { //STOP
setBalls("0"); //hide balls
pose = pose0;
} else { //Balls OFF
setBalls("DIE");
rez = 0;
}
if (chat) say(button);
menu = 0;
} else if (cmd == "ADJUST") {
setBalls("ADJUST");
} else if (cmd == "DUMP") {
llMessageLinked(LINK_THIS,1,"DUMP",NULL_KEY);
} else if (cmd == "INVISIBLE") {
visible = !visible;
llSetAlpha((float)visible*alpha, ALL_SIDES);
} else if (cmd == "REDO") {
redo = !redo;
if (redo) say(button+" ON"); else say(button+" OFF");
} else if (cmd == "CHAT") {
chat = !chat;
if (chat) say(button+" ON"); else say(button+" OFF");
} else if (cmd == "USERS") {
if (user == owner) {
all = !all;
if (all) llOwnerSay(button+" ON"); else llOwnerSay(button+" OFF");
} else llWhisper(0,button+" ON (can be switched by owner only)");
} else if (cmd == "OFF" || cmd == "RESET") {
llMessageLinked(LINK_THIS,0,"POSE","0"); //msg to pos/pose
if (chat) llOwnerSay(button);
setBalls("DIE");
llSleep(0.5);
if (user == owner) {
if (cmd == "OFF") llResetOtherScript("~run");
llResetScript();
}
llWhisper(0,button+" deactivated (owner only)");
rez = 0;
} else { //SAVE //Z-adjust
if (user == owner) {
llMessageLinked(LINK_THIS,0,cmd,pose); //msg to pos/pose
doMenu(); return;
} llWhisper(0,button+" deactivated (owner only)");
}
if (redo) doMenu();
}
on_rez(integer r) {
rez = 0;
}
timer() {
if (rez) {
llWhisper(ch,"LIVE"); //msg to balls: stay alive
llWhisper(ch+1,"LIVE");
}
}
}
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
Discussion: MLP - Multi-love-pose
05-15-2006 07:34
~pos script:
CODE

//MLP MULTI-LOVE-POSE 1.01 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer a;
integer ch;
integer p;
integer swap;
integer z;
string pr1;
string pr2;
list plist;
list positions1;
list positions2;
list rotations1;
list rotations2;
vector pos;
vector pos0;
vector pos1;
vector pos2;
vector rot1;
vector rot2;
rotation rot;

getRefPos() { //reference position
pos = llGetPos();
rot = llGetRot();
pos0 = pos;
z = (integer)llGetObjectDesc();
pos.z += (float)z/100;
}
getPos() {
pos1 = (vector)llList2String(positions1, p);
pos2 = (vector)llList2String(positions2, p);
rot1 = (vector)llList2String(rotations1, p);
rot2 = (vector)llList2String(rotations2, p);
}
setPos() {
pr1 = (string)(pos1*rot + pos);
pr2 = (string)(pos2*rot + pos);
pr1 += (string)(llEuler2Rot(rot1*DEG_TO_RAD) * rot);
pr2 += (string)(llEuler2Rot(rot2*DEG_TO_RAD) * rot);
llSay(ch+swap,pr1); //msg to ball1/2
llSay(ch+!swap,pr2);
}
default {
state_entry() {
getRefPos();
ch = (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
link_message(integer from, integer num, string pdata, key akey) {
if (num != 3) return;
if ((integer)((string)akey) != a) { llOwnerSay("debug ~pos mismatch a "+(string)akey+" "+(string)a); return; }//
if (pdata == "LOADED") state on;
plist = llParseString2List(pdata,[" "],[]);
positions1 += llList2List(plist,0,0);
positions2 += llList2List(plist,2,2);
rotations1 += llList2List(plist,1,1);
rotations2 += llList2List(plist,3,3);
//positions1 = llList2List(plist,0,0) + (positions1 = []) + positions1; //trick to save memory
//positions2 = llList2List(plist,2,2) + (positions2 = []) + positions2; //but not useful after
//rotations1 = llList2List(plist,1,1) + (rotations1 = []) + rotations1; // replacing positions
//rotations2 = llList2List(plist,3,3) + (rotations2 = []) + rotations2;
++a;
}
state_exit() {
llOwnerSay((string)a+" positions loaded ("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free)");
}
}
state on {
link_message(integer from, integer num, string cmd, key pkey) {
if (num) return;
if (cmd == "POSE") {
p = (integer)((string)pkey);
//p = -(integer)((string)pkey) - 1; //read reversed when using memory saving trick above ^
getPos();
setPos();
} else if (cmd == "SWAP") {
swap = !swap;
llSay(ch+swap,pr1); //msg to ball1/2
llSay(ch+!swap,pr2);
} else if (cmd == "REPOS") {
getRefPos();
} else if (llGetSubString(cmd, 0, 0) == "Z") {
z += (integer)llGetSubString(cmd, 1, -1);
pos.z = pos0.z + (float)z/100;
setPos();
llOwnerSay("Heigth adjustment Z "+(string)z+"cm");
llSetObjectDesc((string)z);
} else if (cmd == "SAVE") {
llMessageLinked(LINK_THIS,8,(string)pos,(string)rot); //send reference position to pose
} else if (cmd == "SAVE2") { //replace positions
plist = llParseString2List((string)pkey,[" "],[]);
positions1 = llListReplaceList(positions1,llList2List(plist,0,0),p,p);
positions2 = llListReplaceList(positions2,llList2List(plist,2,2),p,p);
rotations1 = llListReplaceList(rotations1,llList2List(plist,1,1),p,p);
rotations2 = llListReplaceList(rotations2,llList2List(plist,3,3),p,p);
llOwnerSay("("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free, "+(string)a+" positions)");
getPos();
}
}
}


~pose script:
CODE

//MLP MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer a;
integer ch;
integer hear1;
integer hear2;
integer i;
integer swap;
string an1;
string an2;
string pose;
string pr1;
string pr2;
list anims;
vector pos;
rotation rot;

string prStr(string str) {
i = llSubStringIndex(str,">");
vector p = ((vector)llGetSubString(str,0,i) - pos) / rot;
vector r = llRot2Euler((rotation)llGetSubString(str,i+1,-1) / rot)*RAD_TO_DEG;
return "<"+round(p.x, 3)+","+round(p.y, 3)+","+round(p.z, 3)+"> <"+round(r.x, 1)+","+round(r.y, 1)+","+round(r.z, 1)+">";
}
string round(float number, integer places) {
float shifted;
integer rounded;
string s;
shifted = number * llPow(10.0,(float)places);
rounded = llRound(shifted);
s = (string)((float)rounded / llPow(10.0,(float)places));
s = llGetSubString(s,0,llSubStringIndex(s, ".")+places);
//while (llGetSubString(s,-1,-1) == "0") s = llDeleteSubString(s,-1,-1);
//if (llGetSubString(s,-1,-1) == ".") s = llDeleteSubString(s,-1,-1);
return s;
}
default {
state_entry() {
ch = (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
}
link_message(integer from, integer num, string an1str, key an2key) {
if (num != 9+a) return;
if (an1str == "LOADED") state on;
an1 = an1str;
an2 = (string)an2key;
if (a>1) {
if (an1 == "") an1 = llList2String(anims, 2); //use default
else if (llGetInventoryType(an1) != INVENTORY_ANIMATION) llSay(0,"animation '"+an1+"' not in inventory (ok for build-in animations, otherwise check)");
if (an2 == "") an2 = llList2String(anims, 3); //use default
else if (llGetInventoryType(an2) != INVENTORY_ANIMATION) llSay(0,"animation '"+an2+"' not in inventory (ok for build-in animations, otherwise check)");
} else if (a) { //pose1: set default
if (an1 == "") an1 = "sit_ground";
if (an2 == "") an2 = "sit_ground";
} else { //pose0: set stand
if (an1 == "") an1 = "stand";
if (an2 == "") an2 = "stand";
}
anims += [ an1, an2 ];
++a;
}
state_exit() {
llOwnerSay((string)a+" posepairs loaded ("+llGetScriptName()+": "+(string)llGetFreeMemory()+" bytes free)");
}
}
state on {
link_message(integer from, integer num, string cmd, key akey) {
if (num) return;
if (cmd == "POSE") {
a = (integer)((string)akey) * 2;
an1 = llList2String(anims, a);
an2 = llList2String(anims, a+1);
} else if (cmd == "SWAP") {
swap = !swap;
} else if (cmd == "SAVE") {
pose = (string)akey;
state save;
} else return;
llMessageLinked(LINK_THIS,ch+swap, an1,NULL_KEY); //msg to pose1/2
llMessageLinked(LINK_THIS,ch+!swap,an2,NULL_KEY);
}
}
state save {
state_entry() {
pr1 = "";
pr2 = "";
hear1 = llListen(ch+8, "", NULL_KEY, "");
hear2 = llListen(ch+9, "", NULL_KEY, "");
llSay(ch,"SAVE"); //msg to balls
llSay(ch+1,"SAVE");
llSetTimerEvent(3);
}
listen(integer channel, string name, key id, string pr) {
if (channel == ch+8+swap) pr1 = pr;
else if (channel == ch+8+!swap) pr2 = pr;
if (pr1 != "" && pr2 != "") {
pr = prStr(pr1)+" "+prStr(pr2);
llOwnerSay("["+pose+"] "+pr);
llMessageLinked(LINK_THIS,0,"SAVE2",pr); //save to pos
llMessageLinked(LINK_THIS,1,pose,pr); //write to memory
state on;
}
}
link_message(integer from, integer num, string posstr, key rotkey) {
if (num != 8) return;
pos = (vector)posstr;
rot = (rotation)((string)rotkey);
}
timer() {
state on;
}
state_exit() {
llSetTimerEvent(0);
llListenRemove(hear1);
llListenRemove(hear2);
}
}


~pose1 and ~pose2 script:
The code for both scripts is the same, except the value of ch in the first line, in ~pose2 change it to:
integer ch = 1;
CODE

//MLP MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch = 0; //pose1: ch=0 //pose2: ch=1
string animation = "stand";
key avatar;

stopAnim() {
list l=llGetAnimationList(llGetPermissionsKey());
integer i;
for (i;i<llGetListLength(l);++i) llStopAnimation(llList2String(l,i));
}

default {
state_entry() {
ch += (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim
llListen(ch+4,"",NULL_KEY,"");
}
link_message(integer from, integer num, string an, key id) { //an animation is set
if(num != ch) return;
if (llGetPermissionsKey() == avatar && avatar != NULL_KEY) { //permissions
llStopAnimation(animation);
llStartAnimation(an);
}
animation=an;
}
listen(integer channel, string name, key id, string av) { //avatar sits or stands up
avatar = av;
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) { //permissions ok
stopAnim();
if (llGetPermissionsKey() == avatar) { llStartAnimation(animation); return; } //if avatar is the same: animate
}
if (avatar != NULL_KEY) llRequestPermissions(avatar,PERMISSION_TRIGGER_ANIMATION); //ask permission from new avatar
}
run_time_permissions(integer perm) {
if (perm & PERMISSION_TRIGGER_ANIMATION && llGetPermissionsKey() == avatar) { //avatar gave permission
stopAnim();
llStartAnimation(animation);
} else llUnSit(avatar); //for chickens
}
}
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
Discussion: MLP - Multi-love-pose
05-15-2006 07:36
~ball script:
put this script inside a ball and place the ball in the object containing all other scripts
CODE

//MLP MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
integer ch;
integer hear;
integer i;
integer visible;
key avatar;

show() {
llSetAlpha(1.0, ALL_SIDES);
llSetScale(<0.2,0.2,0.2>);
llSetText("Pose",<1.0,1.0,1.0>,1.0);
}
hide() {
llSetScale(<0.01,0.01,0.01>);
llSetAlpha(0.0, ALL_SIDES);
llSetText("",<1.0,1.0,1.0>,1.0);
}

default {
on_rez(integer channel) {
hide();
llSitTarget(<0.0,0.0,0.5>,ZERO_ROTATION);
llSetSitText("POSE");
avatar = NULL_KEY;
ch = channel;
llListenRemove(hear);
hear = llListen(ch,"",NULL_KEY,"");
llSetTimerEvent(60);
}
changed(integer change) {
if (change != CHANGED_LINK) return;
avatar = llAvatarOnSitTarget();
llSay(ch+4,(string)avatar); //requests perm, sets animation
if (visible & avatar == NULL_KEY) show(); else hide();
}
listen(integer channel, string name, key object, string str) {
i = llSubStringIndex(str,">");
if (i != -1) {
llSetRot((rotation)llGetSubString(str,i+1,-1));
llSetPos((vector)llGetSubString(str,0,i));
} else if (str == "1") { //PINK
llSetColor(<1.0,0.0,1.0>,ALL_SIDES);
if (avatar == NULL_KEY) show();
visible = 1;
} else if (str == "2") { //BLUE
llSetColor(<0.0,0.0,1.0>,ALL_SIDES);
if (avatar == NULL_KEY) show();
visible = 1;
} else if (str == "0") { //HIDE
hide();
visible = 0;
} else if (str == "ADJUST") {
llSetAlpha(0.2,ALL_SIDES);
llSetText("Adjust",<1.0,1.0,1.0>,1.0);
llSetScale(<0.1,0.1,5.0>);
} else if (str == "SAVE") {
llSay(ch+8,(string)llGetPos()+(string)llGetRot());
} else if (str == "DIE") {
llDie();
} else if (str == "LIVE") {
llSetTimerEvent(60);
}
}
timer() { //not heard "LIVE" from ~menu for a minute: suicide
llSay(ch + 1,"DIE"); //1st ball: msg to 2nd ball
llSay(ch - 1,"DIE"); //2nd ball: msg to 1st ball, 1st ball: msg to ~menu
llSay(ch - 2,"DIE"); // 2nd ball: msg to ~menu
llDie();
}
}


.MENUITEMS notecard (example):
CODE

POSE stand | stand | stand //pose before starting and when stopping
POSE default | sit_ground | sit_ground //default pose when no animation entered

MENU MAIN MENU | 600 //timeout: menu stops functioning after ...seconds (optional)
STOP
TOMENU Shut Down
TOMENU OPTIONS
TOMENU Girl-Boy
TOMENU Girl-Girl
TOMENU Self poses

MENU Shut Down | OWNER //OWNER = menu can be accessed by owner only //ALL = all users
RESET Restart //(note: RESET & OFF are deactivated for other users, even if menu set to ALL)
OFF Shut Down
BACK Cancel

MENU OPTIONS | OWNER
DUMP Mem Dump //lists all positions stored in memory, copy/paste into .POSITIONS for backup
USERS All Users | ON //switches who can operate main menu: ON = all users, OFF = owner only
BACK
SAVE Save Pos //Saves current position to memory (note: deactivated for other users)
CHAT Chat Info | ON //switches chat info on/off (for most buttons) //ON - sets default on
REDO Redo Menu | ON //switches if menu disappears/reappears automatically //ON - sets default on
ADJUST Adjust Pos //changes poseballs into transparant beams easy to select for moving
Z-1 //adjust Z = height offset (so you don't have to adjust the positions of
Z-10 // each individual pose for different bodies/places)
INVISIBLE Invisible //make the main object invisible/visible (usefull if it's worn)
Z+1 //adjust Z = height offset in cm - use any integer to set the step size
Z+10 // (note: the Z-buttons are deactivated for other users)

MENU Girl-Boy | ALL | PINK | BLUE //this menu creates/shows a PINK and a BLUE poseball
STOP STAND //stops animations and hides balls, or removes balls when already stopped
SWAP //swap animations
BACK
POSE (empty)
POSE (empty)
POSE (empty)
POSE (empty)
POSE (empty)
POSE (empty)
POSE Let's hug | hug-femanine | hug-masculine //syntax: POSE name | animation1 | animation2
POSE Legs up | splat //if no second animation is set it will use "POSE default" (see line 2, sit_ground)
POSE (empty)

MENU Girl-Girl | ALL | PINK | PINK
STOP STAND //you can use max 12 buttons per menu, with stop/swap/back, this leaves 9 poses
SWAP //the buttons appear from bottom-to-top, left-to-right
BACK //for top-to-bottom order: change order in groups of 3 buttons, like this example:
POSE (empty) 7
POSE (empty) 8
POSE (empty) 9
POSE (empty) 4
POSE (empty) 5
POSE (empty) 6
POSE (empty) 1
POSE (empty) 2
POSE (empty) 3

MENU Self poses | OWNER | PINK | HIDE //this menu can be used by OWNER only, and shows the PINK poseball only
STOP STAND
SWAP
BACK
POSE Play self | solo
POSE Splat pose | splat
POSE default //to get menu access to "POSE default" (see line 2, sit_ground), so you can
//adjust the default positions (this pose can be removed after it's adjusted)


.POSITIONS notecard (example):
CODE

MLP: [default] <-0.8,0.0,0.4> <0.0,0.0,0.0> <0.8,0.0,0.4> <0.0,0.0,-180.0>
MLP: [stand] <-0.7,0.0,0.5> <0.0,0.0,0.0> <0.7,0.0,0.5> <0.0,0.0,-180.0>
MLP: [Let's hug] <-0.167,0.208,0.482> <1.8,2.4,-36.0> <0.357,-0.173,0.480> <0.0,0.0,144.0>
MLP: [Legs up] <0.283,0.156,-0.019> <-2.1,-3.7,-148.0> <0.267,0.028,0.511> <-5.2,-33.0,179.5>
MLP: [Play self] <-0.694,-0.142,-0.376> <5.6,-8.3,23.4> <0.942,0.488,0.258> <-2.8,9.6,-163.8>
MLP: [Splat pose] <-0.458,0.145,-0.376> <11.4,36.5,-161.8> <0.800,0.000,0.400> <0.0,0.0,-180.0>


.readme notecard:
CODE

MLP - MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)

The BSD Licence allows anybody to use the source code, in any manner they wish, providing that they provide the copyright notice above on further distributions.
So it's totally free, however if you like it, I would be very happy if you donate any L$ (even L$1 as a thank you). If you're using significant parts of this code in commercial products, I would appreciate if you donate me L$1 for each sold product (or more :) I won't give support, however I'll make an exception for end-users that donated L$1000 or more (for commercial support, custom versions, contact me).
To donate, go to my profile (Find - People - Miffy Fluffy) and use the "Pay..." button, thanks!
You can also find the link to the latest version here.

FEATURES:
- Put all your poseball animations into one object (50 pairs or even more should be no problem).
- Create submenu's for each category of poses, for instance: "Lovers, Boy-Girl, Girl-Girl, Self, Solo, Dance"
- Shows 1 or 2 poseballs depending on the submenu you select
- Positions can be adjusted and saved into memory (backup is easy: select Memory Dump and copy-paste into notecard)
- Portable, can be worn and used everywhere
- Option to adjust height offset (Z) of all poses at once (for different persons/locations).

OPERATION:
- Click the MLP object to switch it on
- When everything has loaded click again for the menu
- Select a submenu containing poses, poseballs will appear automatically
- Sit on your poseball (Right-click - POSE)
- Select a pose, the animations will start
- To stop: select "STOP" or "STAND" (balls will hide if not seated)
- To remove the balls: press "STOP" (or "STAND") again
- To switch-off: select "Shut Down" twice (but you can leave it on after use).

TO ADD ANIMATIONS:
Copy all animations into the MLP object (if you want to use existing poseballs, open them to rip their animations). Note: you can use any object as MLP, just copy the MLP contents in the object of your choice.
Open the .MENUITEMS and add the animations:
POSE name | animation1 | animation2 (see examples in .MENUITEMS)
The changes will become active after MLP is (re)started.

TO ADJUST POSITIONS:
Select a submenu containing the pose you want to adjust, sit on the balls and select the pose you want to adjust.
Go back to the main menu, select "Options - Adjust Pos", this way the balls are changed into transparant beams. Right-click a beam, select Edit to adjust the position (hold Shift to select both beams). You can position the balls anywhere within 10m from the MLP object.
"Save Pos" will store the position into memory.

TO MAKE A BACKUP:
The positions will still be kept in memory after shutdown/restart or when the MLP is put back in your inventory. The positions will be lost only when the memory script is reset (or when it crashes f.i. when it's too full: "Script run-time error / Stack-Heap Collision"). A backup can be made on the .POSITIONS notecard, when the memory is empty it will read the .POSITIONS notecard automatically.
To make a backup select "Mem Dump", copy the complete dump (from Chat-History) and paste it into the .POSITIONS notecard (just replace everything, you don't need to edit/format anything).

TO ADJUST HEIGHT OFFSET (Z):
Select "Options" and click the "Z"-buttons, this will adjust the height for all poses. (Note: the offset height is stored in the Object Description in cm, so any descriptions will be replaced).

USER ACCESS TO THE MENU:
The owner is the only one who can start/restart/shutdown/save, in all cases.
If "Options - All Users" is set ON, anyone can operate the main menu, but access to individual submenus can still be blocked (you can define access for each submenu in .MENUITEMS, see examples in .MENUITEMS).

PORTABLE USE:
Attach the object to the HUD, you can use it's default shape and color for clickable bar on one of the edges of your screen (to move HUD position: Right-click - Edit), you can make it invisible too (MLP menu: "Options - Invisible").
Adjust the height offset (Z). Note: the balls will appear relative to the initial MLP position (to reset where the balls appear press STOP twice and reselect a submenu containing poses).
Instead of attaching it to the HUD, you could also wear it, change the object into an invisible ball of about 0.5m diameter and wear it on your pelvis (if that's free, or hip, but that's not always leveled when standing). This way your partner could operate the menu by clicking your ass (if "Options - All Users" is switched ON).


FAQ:
- Why is there no button to SHOW/HIDE the poseballs?
The balls will show automatically when a submenu is selected which contains poses (can be defined in .MENUITEMS). To hide select "STOP" or "STAND".

- Will my animations be lost if I loose a poseball?
No. The animations are not placed the balls, they remain in the main MLP object. Don't worry about the poseballs, they are copies of the one in the MLP object. A balls will commit suicide if left behind somewhere (the MLP object needs to be within 10m).

- Sometimes notecards or scripts won't open for editing, why?
If the MLP contains many animations, access to it's contents can be slow, try again after a few seconds.

- "Script run-time error / Stack-Heap Collision"?
When it happens during loading: probably there are too many items in .MENUITEMS
When it happens during saving a position: the memory is full. If you do a reset (select: Tools - Reset Scripts in Selection), the backup on the .POSITIONS notecard will be loaded. (The Linden Scripting Language currently needs a lot of overhead memory during a 'save', which is the limiting factor for the number of poses that we can store, probably this will improve in the future. If you have saved a lot of positions (more than 50 or so), make a backup often (after saving a few positions), and do a reset after making the backup, this way the memory is optimized again and you can store more positions.)


Please report any bugs, or improvements in efficiency without loosing readability of the code (In many instances I've chosen readabilty over speed or size because I think it's reasonable to expect that the compiler will improve in the future). If you want to read the code start reading the comments in ~run for an overview. The source code used in ~menu is partly based on the Menu Engine by Zonax Delorean (BSD License), thanks. I included some free poses as examples, thanks to their makers. Thanks to Purrcat Miranda for testing. Thanks to other creative people in SL too, and thanks for any donations. Have fun!

MLP - MULTI-LOVE-POSE 1.0 - Copyright (c) 2006, by Miffy Fluffy (BSD License)
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Original Thread
05-15-2006 07:48
/15/39/106798/1.html
_____________________
i've got nothing. ;)
Socks Sleestak
Registered User
Join date: 26 Mar 2006
Posts: 3
Wow
05-16-2006 11:07
I don't know if I should be sad that one of my projects now seems irrelevant or ecstatic that you've saved me tons of time!

Will be checking this out once I can get away from this cursed firewall and get back in-game.
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
05-16-2006 17:15
From: Socks Sleestak
I don't know if I should be sad that one of my projects now seems irrelevant or ecstatic that you've saved me tons of time!

Will be checking this out once I can get away from this cursed firewall and get back in-game.


Just enjoy that I saved you a lot of time then...
The coding was a hell of a job, but testing with a very nice lady was fun :)

I would love to hear some feedback from different users, let me know if it works for you.
Jesse Murdock
Moves You
Join date: 23 Jun 2004
Posts: 149
05-17-2006 14:52
From: Miffy Fluffy
Just enjoy that I saved you a lot of time then...
The coding was a hell of a job, but testing with a very nice lady was fun :)

I would love to hear some feedback from different users, let me know if it works for you.


All I have to say is .... WOW! Can anyone say.... perfect? I knew you could!
Only modification I can see is to change where it says you can use it anywhere, weell add to actually, that you will still be rtestricted in no build/no script areas(common sense... but hey!).
_____________________
The writing's on the wall...
hurly Burleigh
Registered User
Join date: 19 Sep 2005
Posts: 167
05-17-2006 15:34
Hi:)

Very impressed:)

i have added a group button to it but i am not sure how i can get more than 2 poseballs up:)
Is this possible?

its great anyway:)
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
05-18-2006 05:46
Hi, I fixed a bug in the ~pos script, pick up the updated version (MLP V1.01) in SL (free). For the location of the latest version check my profile (Find - People - Miffy Fluffy - Picks).
You can replace the first version entirely, or just the ~pos script.

The problem was that the "Height Offset (Z)" adjustment influenced the "Save Position" function too, these should be independent.
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
05-18-2006 06:14
From: hurly Burleigh
Hi:)

Very impressed:)

i have added a group button to it but i am not sure how i can get more than 2 poseballs up:)
Is this possible?

its great anyway:)

Hi. You'll get 2 poseballs at a time only, this way your room doesn't get cluttered with balls. These 2 poseballs are used for all your animations. Via the menu you select which animation you want and the balls change position (when you add new animations, you'll need to adjust their positions and save them). The balls can be adjusted into any position within 10m from the main MLP object (which can be any object: a blanket, a bed, the floor).
No need for more balls, unless you want to do a trio (I've not implemented that, it wouldn't be difficult, but it would limit the amount of free memory, this should be no problem when Linden has fixed the memory handling of the scripts).

If you want to organize a party, you can set up more than one MLP in one room.
hurly Burleigh
Registered User
Join date: 19 Sep 2005
Posts: 167
05-19-2006 03:56
Thanks,

I will keep and eye on the forums for the updates:)

it seems to do everything it says on the box anyway.

you rock!!!!!
Aurael Neurocam
Will script for food
Join date: 25 Oct 2005
Posts: 267
Oh my god!!
05-19-2006 17:08
I just wrote almost exactly the same thing! I spent today putting the finishing touches on it....

I built a bed and a couch using my animation script that does basically the same thing this program does... I'll definitely have to check this out.

Thanks, Miffy.
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
05-20-2006 03:58
From: Aurael Neurocam
I just wrote almost exactly the same thing! I spent today putting the finishing touches on it....

I built a bed and a couch using my animation script that does basically the same thing this program does... I'll definitely have to check this out.

Thanks, Miffy.


:) Tell me if you think something can be impoved...

Thanks everyone for their feedback so far, I'm really glad this hard work payed off (we'll not in money, but it seems useful for others)
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-01-2006 15:00
Fixed a new problem. If you're using a previous version full of animations, you have to make a backup of all positions (copy/paste Memory Dump into the .POSITIONS notecard).

This was the problem: In SL1.10 there are timestamps in the Chat History, like this:
[14:49] Shirley's MLP: [Splat pose] <-0.458,0.145,-0.376> <11.4,36.5,-161.8>
When you make a backup (Memory Dump) and you copy and paste this dump from the Chat History into the .POSITIONS notecard, the timestamps were copied too, which gave problems. You'd had to delete them or switch them off (Edit-Preferences-IM-timestamps).

In the new version (MLP V1.02) you don't have to do this anymore, you can just copy/paste everything into the .POSITIONS notecard. The rubbish will be filtered out automatically when the notecard is read.

Pick up the updated version (MLP V1.02) in SL (free). For the location of the latest version check my profile (Find - People - Miffy Fluffy - Picks).
You can replace the previous version entirely, or just the ~memory script.

Enjoy!
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-05-2006 06:07
Mmm, the fix above wasn't correct in all cases, uploaded a new one: MLP V1.03
Sorry for that.

With the current version of SL 1.10.1 things aren't running very smoothly. It often happens that people are unseated from the balls, other strange things happen.
This has nothing to do with the stability of MLP itsself, it was pretty reliable under the old version of SL. Let's hope Linden can fix our SL soon :)
delrona Antonelli
Registered User
Join date: 14 Apr 2006
Posts: 4
06-14-2006 04:09
First of all thank you so much, these are awesome scripts ...
Though I had a few problems ... Kind of newbish problems but if anyone could help it would be great :)

When setting some poses or animations ... The poseballs will be way too low compared to "where" the anim is happening .... And thus the poseball will be hidden "into" the furniture ... Unable to use or else I would be laying in the air .

Is this linked only with the animation / pose ... Or is there anyway to edit this from MLP ?
Thank you if anyone can help :)
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-14-2006 06:51
From: delrona Antonelli
First of all thank you so much, these are awesome scripts ...
Though I had a few problems ... Kind of newbish problems but if anyone could help it would be great :)

When setting some poses or animations ... The poseballs will be way too low compared to "where" the anim is happening .... And thus the poseball will be hidden "into" the furniture ... Unable to use or else I would be laying in the air .

Is this linked only with the animation / pose ... Or is there anyway to edit this from MLP ?
Thank you if anyone can help :)


Thanks, this is easy to fix. You can edit the llSitTarget height of the ~ball script, it's inside the ball (the ball rezzes small and invisible, zoom in and 'Highlight Transparant' to be able to edit it):
It's this line:
llSitTarget(<0.0,0.0,0.5>,ZERO_ROTATION);
change it f.i. into:
llSitTarget(<0.0,0.0,0.1>,ZERO_ROTATION);
or enter a negative value if you want to sit under the ball (btw: you can't use 0.0).
delrona Antonelli
Registered User
Join date: 14 Apr 2006
Posts: 4
06-14-2006 06:55
Woohoo thank you sooooo much !
Impatient to test that :)
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-14-2006 17:09
I'll make an updated version with a more convenient sit height and a few other changes. Also the last fix still doesn't work in all cases, so I'll fix that too. Check back tomorrow, or so...
delrona Antonelli
Registered User
Join date: 14 Apr 2006
Posts: 4
06-15-2006 01:20
I tried to adjust the sit target line ...... But the poseball I edited dissapeared after changing it :(
I will check with the updated version ;)
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-15-2006 07:17
:) yes the ball commits suicide within a few minutes, stop the script from running while you're editing it.

But it's better to wait for the update. B.t.w. it will include a tool to convert old positions to the new SitTarget height. So those who already saved a lot of positions don't have to reposition them one by one.
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-15-2006 11:59
OK! here's a new version. Pick up a free copy in world: go to my profile (Find - People - Miffy Fluffy) for the new location.

CHANGES IN MLP V1.1:
- selecting "STAND" doesn't hide the balls anymore (to avoid confusion)
- adjusted sit height on the balls, so the balls will remain visible with most objects
- included a "position conversion tool" for users of previous versions (before V1.1), also useful for those who've edited the SitTarget height in the ~ball script, no need to reposition all balls
- altough not really necessary, I've added the possibility to SHOW/HIDE the balls via the menu (you can add a SHOW and/or HIDE button somewhere in the .MENUITEMS notecard)
- fixed the reading of the .POSITIONS notecard, the new timestamps in the Chat-History memory dump gave problems
- improved menuacces: selections from previous menudialogs will be disregarded (avoids problems with multiple users too)
- owner gets a message if another user operates the menu (so you can avoid operating at the same time)
- reduced load: no timers are running anymore when no balls are rezzed
- with Save Position, the positions could be totally wrong sometimes (large distances), this problem is hard to track as it occurs sometimes only, I found a probable cause, so hopefully it's doesn't happen any more, please report
- sometimes the balls just disappeared, I made it more stable, please report if it still happens, thanks.

NOTE: users of previous versions (V1.0 - V1.03) who want to use their old .POSITIONS notecard with this version have to convert this notecard with the "~~position conversion tool" located in MLP, drag it into the world and follow instructions.
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-18-2006 09:30
CHANGES IN MLP V1.11:
- shame on me, fixed a mistake I made which caused the balls to dissappear within 60 seconds, sorry. If you have V1.1 already you only have to replace the ~ball inside MLP, delete the old one and drop in the new one.

See previous post for other changes and how to get a copy.
Macphisto Angelus
JAFO
Join date: 21 Oct 2004
Posts: 5,831
Um... hehe
06-27-2006 14:25
I went to your pick for the script, but it was a strip club. I didnt see anything that allowed me to get the script hee.
Has your location changed?

Thanks!
Miffy Fluffy
Registered User
Join date: 27 Feb 2006
Posts: 25
06-29-2006 05:30
Hello, the owner of the land accidently deleted the stuff at the pickup location, it's there again now (to find the location check my profile in world: Find - People: "Miffy Fluffy" - Picks).
1 2 3