// Simple AO sitting script with memory, menu, protection and reporting // Copyright (c) 2007 Nyndia Eponym // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any // damages arising from the use of this software. // // Permission is granted to anyone to use this software for any // purpose, including commercial applications, and to alter it and // redistribute it freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you // must not claim that you wrote the original software. If you use // this software in a product, an acknowledgment in the product // documentation would be appreciated but is not required. // // 2. Altered source versions must be plainly marked as such, and // must not be misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source // distribution. // The sitting avatar, or NULL_KEY key avatar; // The animation currently in use string animation; // The list of available animations list animations; // The channel to use (edit to your preference) integer CHANNEL = 38; // The listener callback integer callback; // Transformation for sit target (will need to be adjusted) rotation target_rot = <0,-1,0,1>; vector target_pos = <-1.15,0.0,-0.4>; default { state_entry() { // Make us sitable llSitTarget(target_pos, target_rot); integer i; integer count = llGetInventoryNumber(INVENTORY_ANIMATION); if (count) { // Build list of available animations for (i = 0; i < count; i++) animations += llGetInventoryName(INVENTORY_ANIMATION, i); animation = llList2String(animations, 0); llOwnerSay("Found " + (string) count + " animations"); state standing; } else { // No animations found, nag and turn into stupid object llOwnerSay("No animations found"); } } } state standing { state_entry() { avatar = NULL_KEY; } changed(integer changes) { avatar = llAvatarOnSitTarget(); if (changes & CHANGED_LINK) { if (avatar) { key owner = llGetOwner(); if (avatar == owner || llSameGroup(avatar)) llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION); else { // Invalid sitter, dispose and report (assumes we're purple) llUnSit(avatar); llInstantMessage(avatar, "You're the wrong shade of purple"); llInstantMessage(owner, "I'm in " + llGetRegionName() + " at " + (string) llGetPos() + " and " + llKey2Name(avatar) + " tried to sit on me"); state standing; } } } } run_time_permissions(integer permissions) { if (permissions & PERMISSION_TRIGGER_ANIMATION) { // Initial AO takeover llStopAnimation("sit"); llStartAnimation(animation); state sitting; } else llUnSit(avatar); } } state sitting { changed(integer changes) { if (changes & CHANGED_LINK) { avatar = llAvatarOnSitTarget(); if (avatar == NULL_KEY) { // Detected sitter standing up llStopAnimation(animation); state standing; } } } touch_start(integer touches) { integer i; for (i = 0; i < touches; i++) { // Only sitter may change animation key toucher = llDetectedKey(i); if (toucher == avatar) { callback = llListen(CHANNEL, "", avatar, ""); llDialog(toucher, "Select animation", animations, CHANNEL); } } } listen(integer channel, string name, key id, string message) { if (llListFindList(animations, [message]) != -1) { // Change active animation to selection llStopAnimation(animation); animation = message; llStartAnimation(animation); } llListenRemove(callback); } }