string current_sitting_anim = "throneSitChilled"; vector current_sitting_offset = <-0.055, 0.2, 0.125>; vector init_pos; rotation default_rot = <0.000000, 0.000000, -0.707107, 0.707107>; integer can_ex = 1; float ex_timer = 20; float ex_frequency = 0.3; // Frequency % of EX to add RNG // Link Commands integer LINK_MENU_DISPLAY = 300; integer LINK_MENU_RETURN = 320; integer LINK_MENU_TIMEOUT = 330; DisplayMenu(key id) { string menuDescripter = "thronesitmenu"; string menuNavigate = "FALSE"; string menuText = "Select a sitting animation"; string menuButtons = "Sit~Chilled~Crossed~Slumped~Sleepy~Cozy"; // The buttons, each button separated by a '~'. llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, menuDescripter+"|"+menuNavigate+"|"+menuText+"|"+ menuButtons, id); } //Sets / Updates the sit target moving the avatar on it if necessary. UpdateSitTarget(vector pos, rotation rot) {//Using this while the object is moving may give unpredictable results. llSitTarget(pos, rot);//Set the sit target key user = llAvatarOnSitTarget(); if(user)//true if there is a user seated on the sittarget, if so update their position { vector size = llGetAgentSize(user); if(size)//This tests to make sure the user really exists. { //We need to make the position and rotation local to the current prim rotation localrot = ZERO_ROTATION; vector localpos = ZERO_VECTOR; if(llGetLinkNumber() > 1)//only need the local rot if it's not the root. { localrot = llGetLocalRot(); localpos = llGetLocalPos(); } integer linkNum = llGetNumberOfPrims(); do { if(user == llGetLinkKey( linkNum ))//just checking to make sure the index is valid. { //<0.008906, -0.049831, 0.088967> are the coefficients for a parabolic curve that best fits real avatars. It is not a perfect fit. float fAdjust = ((((0.008906 * size.z) + -0.049831) * size.z) + 0.088967) * size.z; llSetLinkPrimitiveParamsFast(linkNum, [PRIM_POS_LOCAL, (pos + <0.0, 0.0, 0.4> - (llRot2Up(rot) * fAdjust)) * localrot + localpos, PRIM_ROT_LOCAL, rot * localrot]); jump end;//cheaper but a tad slower then return } }while( --linkNum ); } else {//It is rare that the sit target will bork but it does happen, this can help to fix it. llUnSit(user); } } @end; }//Written by Strife Onizuka, size adjustment and improvements provided by Talarus Luan default { state_entry() { llSitTarget(ZERO_VECTOR,ZERO_ROTATION); vector default_seat = llGetGeometricCenter() - current_sitting_offset; init_pos = llGetGeometricCenter(); llSitTarget(default_seat, default_rot); } on_rez(integer start_param) { llResetScript(); //llOwnerSay("Reset"); // for debugging } changed(integer change) { //llOwnerSay("Changes"); // for debugging if (change & CHANGED_LINK) { //llOwnerSay("Sat"); // for debugging key av = llAvatarOnSitTarget(); integer perm = llGetPermissions(); if (av) { if(PERMISSION_TRIGGER_ANIMATION & perm) { llStopAnimation("sit"); llStartAnimation(current_sitting_anim); llSetTimerEvent(ex_timer); } else { llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION); } DisplayMenu(av); } else { if(PERMISSION_TRIGGER_ANIMATION & perm) { llStopAnimation(current_sitting_anim); } llResetScript(); } } } run_time_permissions(integer perm) { key av = llAvatarOnSitTarget(); if (av) { if(PERMISSION_TRIGGER_ANIMATION & perm) { llStopAnimation("sit"); llStartAnimation(current_sitting_anim); llSetTimerEvent(ex_timer); } } } timer() { key av = llAvatarOnSitTarget(); if (av) { integer perm = llGetPermissions(); if(PERMISSION_TRIGGER_ANIMATION & perm) { if (can_ex == 1) { float roll_dem_bones = llFrand(1.0); if (roll_dem_bones <= ex_frequency) { llStartAnimation(current_sitting_anim + "Ex"); } } } } } link_message(integer intSenderNum, integer num, string message, key id) { if (num == LINK_MENU_RETURN) { list returnMenu = llParseString2List(message, ["|"], []); string menuDescriptor = llList2String(returnMenu,0); if (menuDescriptor == "thronesitmenu") { key av = llAvatarOnSitTarget(); if (av) { string item = llList2String(returnMenu,1); //llOwnerSay(item); // for debugging string actual_current_sitting_anim = current_sitting_anim; if (item == "Sit") { current_sitting_anim = "sit"; current_sitting_offset = <0.05, 0.65, -0.15>; can_ex = 0; } else if (item == "Chilled") { current_sitting_anim = "throneSitChilled"; current_sitting_offset = <-0.055, 0.2, 0.125>; can_ex = 1; } else if (item == "Crossed") { current_sitting_anim = "throneSitCrossed"; current_sitting_offset = <0.01, 0.12, 0.125>; can_ex = 1; } else if (item == "Slumped") { current_sitting_anim = "throneSitSlumped"; current_sitting_offset = <0.01, 0.12, 0.125>; can_ex = 1; } else if (item == "Sleepy") { current_sitting_anim = "throneSitSleepy"; current_sitting_offset = <0.01, 0.12, 0.125>; can_ex = 1; } else if (item == "Cozy") { current_sitting_anim = "throneSitCozy"; current_sitting_offset = <0.01, 0.12, 0.125>; can_ex = 1; } integer perm = llGetPermissions(); if(PERMISSION_TRIGGER_ANIMATION & perm) { llStopAnimation(actual_current_sitting_anim); vector default_seat = init_pos - current_sitting_offset; UpdateSitTarget(default_seat, default_rot); //llSetLinkPrimitiveParamsFast(llGetNumberOfPrims(),[PRIM_POS_LOCAL,default_seat]); llStartAnimation(current_sitting_anim); } DisplayMenu(av); } } } else if (num == LINK_MENU_TIMEOUT) { if (message == "thronesitmenu") { key av = llAvatarOnSitTarget(); if (av) { DisplayMenu(av); } } } } }