// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Owner pose menu // Not compiled or tested in-world // Setup: Add licensed animations pose_a, pose_b and pose_c. Owner-touch requests permission, then opens a menu. // Stop / restore: Choose Stop before removing or resetting. If interrupted, use the viewer Stop Animating Me command. // Notes: Stop before renaming or removing animation assets. An animation asset may also be used by another controller: do not run competing controllers for the same asset. Requests only animation permission. Stops only the animation it started, not every animation on the avatar. Viewer AO and animation priorities can compete. // License: see LICENSE in this distribution. // Original Incoprea. MIT. Not compiled or tested in-world. integer channel; integer handle; integer pending; string current; integer permitted() { return (llGetPermissions()&PERMISSION_TRIGGER_ANIMATION)&&llGetPermissionsKey()==llGetOwner(); } close() { if(handle)llListenRemove(handle); handle=0; llSetTimerEvent(0.0); } stop() { if(current!=""&&permitted())llStopAnimation(current); current=""; } show() { close(); channel=-1000-(integer)llFrand(1000000.0); handle=llListen(channel,"",llGetOwner(),""); llDialog(llGetOwner(),"Preview a pose; Stop before removing.",["A","B","C","Stop"],channel); llSetTimerEvent(30.0); } default { touch_start(integer n) { if(llDetectedKey(0)!=llGetOwner()||pending)return; if(permitted())show(); else { pending=TRUE; llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION); } } run_time_permissions(integer p) { if(!pending)return; pending=FALSE; if(permitted())show(); } listen(integer ch,string name,key id,string s) { if(!handle||ch!=channel||id!=llGetOwner()||!permitted())return; if(s=="Stop") { stop(); close(); return; } integer i=llListFindList(["A","B","C"],[s]); if(i<0)return; string animation=llList2String(["pose_a","pose_b","pose_c"],i); if(llGetInventoryType(animation)!=INVENTORY_ANIMATION) { llOwnerSay("Missing "+animation); return; } stop(); current=animation; llStartAnimation(current); show(); } timer() { stop(); close(); } changed(integer change) { if(change&CHANGED_OWNER)llResetScript(); } }