Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update oc_couples.lsl to add partner controlled couples pose system to remove legacy ask box if both individuals have access #1042

Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 186 additions & 17 deletions src/collar/oc_couples.lsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// This file is part of OpenCollar.
// Copyright (c) 2004 - 2021 Francis Chung, Ilse Mannonen, Nandana Singh,
// Cleo Collins, Satomi Ahn, Joy Stipe, Wendy Starfall, Garvin Twine,
// littlemousy, Romka Swallowtail, Sumi Perl et al.
// littlemousy, Romka Swallowtail, Sumi Perl, Rosalyn Russell et al.

//Rosalyn (RosalynRussell)
// *Apr 2024 - Added optional partner controlled couples pose system to remove legacy ask box if initiator is trusted

// Licensed under the GPLv2. See LICENSE for full details.
string g_sScriptVersion="8.1";
integer LINK_CMD_DEBUG=1999;
Expand Down Expand Up @@ -34,6 +38,7 @@ key g_kWearer;
string STOP_COUPLES = "STOP";
string TIME_COUPLES = "TIME";


integer g_iLine1;
integer g_iLine2;
key g_kDataID1;
Expand Down Expand Up @@ -66,6 +71,7 @@ string g_sDeviceName;
integer g_iTargetID;
string g_sSubAnim;
string g_sDomAnim;
string g_sPartnerAnim;
integer g_iVerbose = TRUE;

//MESSAGE MAP
Expand Down Expand Up @@ -112,6 +118,13 @@ integer g_iStopChan = 99;
integer g_iLMChannel = -8888;
integer g_iListener; //stop listener handle

string timer_reason;
integer listenHandlePartner;
string anim_powered;
integer g_iAutomate = FALSE;
integer auto_busy = FALSE;
key ping_sent_to_key = NULL_KEY;

/*
integer g_iProfiled;
Debug(string sStr) {
Expand All @@ -126,6 +139,13 @@ Debug(string sStr) {
}
*/

integer getChannel(key kAv)
{
integer chan= -llAbs((integer)("0x" + llGetSubString(kAv,30,-1)));
if(chan==0) chan= -9876; //I mean it COULD happen.
return chan;
}

Dialog(key kRCPT, string sPrompt, list lButtons, list lUtilityButtons, integer iPage, integer iAuth, string sMenuID) {
key kMenuID = llGenerateKey();
string sSearch;
Expand Down Expand Up @@ -158,11 +178,13 @@ refreshTimer(){
}

CoupleAnimMenu(key kID, integer iAuth) {
string sPrompt = "\n[Couples]\n\nChoose an animation to play.\n\nAnimations will play ";
if(g_fTimeOut == 0) sPrompt += "ENDLESS.\n\nNOTE: The non-looped \"pet\" sequence is an exception to this rule and can only play for 20 seconds at a time." ;
string sPrompt = "\n[Couples]\n\nChoose an animation to play.\nAnimations will play ";
if(g_fTimeOut == 0) sPrompt += "ENDLESS.\n\nNOTE: The non-looped \"pet\" sequence is an exception to this rule and can only play for 20 seconds at a time.";
else sPrompt += "for "+(string)llCeil(g_fTimeOut)+" seconds.";
sPrompt += "\n\nAuto Acc. will auto accept animation permission from trusted or owners.";
list lButtons = g_lAnimCmds;
lButtons += [TIME_COUPLES, STOP_COUPLES];
if(g_iAutomate) lButtons+="▣ Auto Acc."; else lButtons+="▢ Auto Acc.";
Dialog(kID, sPrompt, lButtons, [UPMENU],0, iAuth,"couples");
}

Expand Down Expand Up @@ -191,13 +213,23 @@ string StrReplace(string sSrc, string sFrom, string sTo) {
StopAnims() {
if (llGetInventoryType(g_sSubAnim) == INVENTORY_ANIMATION) llMessageLinked(LINK_SET, ANIM_STOP, g_sSubAnim, "");
if (llGetInventoryType(g_sDomAnim) == INVENTORY_ANIMATION) {
if (llKey2Name(g_kPartner) != "") {
llStopAnimation(g_sDomAnim);
if (llKey2Name(g_kPartner) != "")
{
if (anim_powered == "PARTNER")
{
integer iChannel = getChannel(g_kPartner);
llSay(iChannel, (string)g_kPartner + ":partnerstop "+g_sDomAnim);
}
else
{
llStopAnimation(g_sDomAnim);
}
llRegionSayTo(g_kPartner,g_iLMChannel,(string)g_kPartner+"booton");
}
}
g_sSubAnim = "";
g_sDomAnim = "";
anim_powered = "";
}

// Calmly walk up to your partner and face them. Does not position the avatar precicely
Expand All @@ -215,9 +247,18 @@ MoveToPartner() {

GetPartnerPermission() {
string sObjectName = llGetObjectName();
//g_sSubAnim = llList2String(g_lAnimSettings, g_iCmdIndex * 4);
string temp_g_sDomAnim = llList2String(g_lAnimSettings, g_iCmdIndex * 4 + 1);
llSetObjectName(g_sDeviceName);
llRequestPermissions(g_kPartner, PERMISSION_TRIGGER_ANIMATION);
llSetObjectName(sObjectName);
//Ping their oc_couples_partner script
ping_sent_to_key = g_kPartner;
integer iChannel = getChannel(g_kPartner);
llSay(iChannel, (string)g_kPartner + ":partnerping "+temp_g_sDomAnim);
//Set Timeout
timer_reason = "PING";
llSetTimerEvent(2.5);
//llRequestPermissions(g_kPartner, PERMISSION_TRIGGER_ANIMATION);
//llSetObjectName(sObjectName);
}

StartNotecards() {
Expand Down Expand Up @@ -265,6 +306,7 @@ state active
//added to stop anims after relog when you logged off while in an endless couple anim
if (g_sSubAnim != "" && g_sDomAnim != "") {
llSleep(1.0); // wait a second to make sure the poses script reseted properly
auto_busy = FALSE;
StopAnims();
}
llResetScript();
Expand All @@ -277,13 +319,49 @@ state active
//Debug("Starting");
}

listen(integer iChannel, string sName, key kID, string sMessage) {
listen(integer iChannel, string sName, key kID, string sMessage)
{
//Debug("listen: " + sMessage + ", iChannel=" + (string)channel);
llListenRemove(g_iListener);
if (iChannel == g_iStopChan) StopAnims();
if (iChannel == g_iStopChan) StopAnims();
}

link_message(integer iSender, integer iNum, string sStr, key kID){
if ((kID == ping_sent_to_key)&&(kID != NULL_KEY))//Is this from the person we sent a ping to?
{
list lParams = llParseString2List(sStr, [" "], []);
string sCommand = llToLower(llList2String(lParams, 0));
string sValue = llToLower(llList2String(lParams, 1));
g_kCmdGiver = kID;
g_kPartner = g_kCmdGiver;
g_sPartnerName = "secondlife:///app/agent/"+(string)g_kPartner+"/about";
if (sCommand == "partnerpong")
{
timer_reason = "";
llSetTimerEvent(0.0);
anim_powered = "PARTNER";
MoveToPartner();
}
else if (sCommand == "partnererror")
{
if (sValue == "autooff")
{
timer_reason = "";
llSetTimerEvent(0.0);
llMessageLinked(LINK_SET,NOTIFY,"0"+g_sPartnerName + " has auto accept disabled, using legacy permissions instead.",g_kWearer);
llMessageLinked(LINK_SET,NOTIFY,"0"+"%WEARERNAME% invited you to a couples animation! Click [Yes] to accept.",g_kPartner);
llRequestPermissions(g_kPartner, PERMISSION_TRIGGER_ANIMATION);
}
if (sValue == "autobusy")
{
timer_reason = "";
llSetTimerEvent(0.0);
llMessageLinked(LINK_SET,NOTIFY,"0"+g_sPartnerName + " is currently being animated, please wait.",g_kWearer);
//llMessageLinked(LINK_SET,NOTIFY,"0"+"%WEARERNAME% invited you to a couples animation! Click [Yes] to accept.",g_kPartner);
//llRequestPermissions(g_kPartner, PERMISSION_TRIGGER_ANIMATION);
}
}
}
//if you don't care who gave the command, so long as they're one of the above, you can just do this instead:
if (iNum >= CMD_OWNER && iNum <= CMD_EVERYONE) {
//the command was given by either owner, secowner, group member, wearer, or public user
Expand Down Expand Up @@ -329,6 +407,44 @@ state active
}
llMessageLinked(LINK_SET,NOTIFY,"0"+"Verbose for couple animations is now turned "+sValue+".",kID);
}
else if (sCommand == "partnerping")
{
if(llGetInventoryType(sValue)==INVENTORY_ANIMATION)
{
if (g_iAutomate == FALSE)
{
integer iChannel = getChannel(g_kCmdGiver);
llSay(iChannel, (string)g_kCmdGiver + ":partnererror autooff");
}
else if (auto_busy == TRUE)
{
integer iChannel = getChannel(g_kCmdGiver);
llSay(iChannel, (string)g_kCmdGiver + ":partnererror autobusy");
}
else
{
//vector pointTo = llList2Vector(llGetObjectDetails(llGetOwnerKey(id),[OBJECT_POS]),0) - llGetPos();
auto_busy = TRUE;
vector pointTo = llList2Vector(llGetObjectDetails(g_kCmdGiver,[OBJECT_POS]),0) - llGetPos();
float turnAngle = llAtan2(pointTo.x, pointTo.y);// - myAngle;
llOwnerSay("@setrot:" + (string)(turnAngle) + "=force");
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
}
}
}
else if (sCommand == "partnerpose")
{
g_sPartnerAnim = sValue;
//llStartAnimation(g_sPartnerAnim);
llMessageLinked(LINK_SET, ANIM_START, g_sPartnerAnim, "");
}
else if (sCommand == "partnerstop")
{
g_sPartnerAnim = sValue;
auto_busy = FALSE;
//llStopAnimation(g_sPartnerAnim);
llMessageLinked(LINK_SET, ANIM_STOP, g_sPartnerAnim, "");
}
} else if (iNum == MENUNAME_REQUEST && sStr == g_sParentMenu)
llMessageLinked(iSender, MENUNAME_RESPONSE, g_sParentMenu + "|" + g_sSubMenu, "");
else if (iNum == LM_SETTING_RESPONSE) {
Expand All @@ -345,6 +461,8 @@ state active
g_iVerbose = (integer)sValue;
else if (sToken == g_sGlobalToken+"devicename")
g_sDeviceName = sValue;
else if (sToken == g_sSettingToken+"autocouple")
g_iAutomate = (integer)sValue;
} else if(iNum == LM_SETTING_EMPTY){

//integer ind = llListFindList(g_lSettingsReqs, [sStr]);
Expand All @@ -354,7 +472,7 @@ state active

//integer ind = llListFindList(g_lSettingsReqs, [sStr]);
//if(ind!=-1)g_lSettingsReqs = llDeleteSubList(g_lSettingsReqs, ind,ind);

if(sStr==g_sSettingToken+"autocouple") g_iAutomate=FALSE;
} else if (iNum == DIALOG_RESPONSE) {
integer iMenuIndex = llListFindList(g_lMenuIDs, [kID]);
if (~iMenuIndex) {
Expand All @@ -376,7 +494,33 @@ state active
if(g_fTimeOut == 0) sPrompt += "ENDLESS.\n\nNOTE: The non-looped \"pet\" sequence is an exception to this rule and can only play for 20 seconds at a time." ;
else sPrompt += "for "+(string)llCeil(g_fTimeOut)+" seconds.";
Dialog(kAv, sPrompt, ["10","20","30","40","60","90","120", "ENDLESS"], [UPMENU],0, iAuth,"timer");
} else if (llGetSubString(sMessage,0,6) == "Verbose") {
} else if(sMessage=="▣ Auto Acc.")
{
if (iAuth==CMD_OWNER || kAv==g_kWearer)
{
g_iAutomate=FALSE;
llMessageLinked(LINK_SET,LM_SETTING_DELETE,g_sSettingToken+"autocouple","");
}
else
{
llMessageLinked(LINK_SET,NOTIFY,"0%NOACCESS% to changing this setting except by wearer or Owners.",kAv);
}
CoupleAnimMenu(kAv, iAuth);
}
else if(sMessage=="▢ Auto Acc.")
{
if (iAuth==CMD_OWNER || kAv==g_kWearer)
{
g_iAutomate=TRUE;
llMessageLinked(LINK_SET,LM_SETTING_SAVE,g_sSettingToken+"autocouple=1","");
}
else
{
llMessageLinked(LINK_SET,NOTIFY,"0%NOACCESS% to changing this setting except by wearer or Owners.",kAv);
}
CoupleAnimMenu(kAv, iAuth);
}
else if (llGetSubString(sMessage,0,6) == "Verbose") {
if (llGetSubString(sMessage,8,-1) == "Off") {
g_iVerbose = FALSE;
llMessageLinked(LINK_SET, LM_SETTING_SAVE, g_sSettingToken + "verbose=" + (string)g_iVerbose, "");
Expand Down Expand Up @@ -405,8 +549,6 @@ state active
g_sPartnerName = "secondlife:///app/agent/"+(string)g_kPartner+"/about";
StopAnims();
GetPartnerPermission();
llMessageLinked(LINK_SET,NOTIFY,"0"+"Inviting "+ g_sPartnerName + " to a couples animation.",g_kWearer);
llMessageLinked(LINK_SET,NOTIFY,"0"+"%WEARERNAME% invited you to a couples animation! Click [Yes] to accept.",g_kPartner);
}
} else if (sMenu == "timer") {
//Debug("Response from timer menu"+sStr);
Expand Down Expand Up @@ -468,7 +610,15 @@ state active

llMessageLinked(LINK_SET, ANIM_START, g_sSubAnim, "");
llRegionSayTo(g_kPartner,g_iLMChannel,(string)g_kPartner+"bootoff");
llStartAnimation(g_sDomAnim);
if (anim_powered == "PARTNER")
{
integer iChannel = getChannel(g_kPartner);
llSay(iChannel, (string)g_kPartner + ":partnerpose "+g_sDomAnim);
}
else
{
llStartAnimation(g_sDomAnim);
}
g_iListener = llListen(g_iStopChan, "", g_kPartner, g_sStopString);
llMessageLinked(LINK_SET,NOTIFY,"0"+"If you would like to stop the animation early, say /" + (string)g_iStopChan + g_sStopString + " to stop.",g_kPartner);

Expand All @@ -485,8 +635,22 @@ state active
else g_iAnimTimeout=0;
refreshTimer();
}
timer() {
refreshTimer();
timer()
{
if (timer_reason == "PING")
{
//No Response, Fail
llSetTimerEvent(0.0);
timer_reason = "";
ping_sent_to_key = NULL_KEY;
llMessageLinked(LINK_SET,NOTIFY,"0"+"Inviting "+ g_sPartnerName + " to a couples animation using legacy permissions.",g_kWearer);
llMessageLinked(LINK_SET,NOTIFY,"0"+"%WEARERNAME% invited you to a couples animation! Click [Yes] to accept.",g_kPartner);
llRequestPermissions(g_kPartner, PERMISSION_TRIGGER_ANIMATION);
}
else
{
refreshTimer();
}
}
dataserver(key kID, string sData) {
if (sData == EOF) iCardComplete++;
Expand Down Expand Up @@ -531,7 +695,12 @@ state active
if (perm & PERMISSION_TRIGGER_ANIMATION) {
key kID = llGetPermissionsKey();
//Debug("changed anim permissions\nPerm ID="+(string)kID+"g_kPartner="+(string)g_kPartner);
if (kID == g_kPartner) {
if (kID == llGetOwner())
{
integer iChannel = getChannel(g_kCmdGiver);
llSay(iChannel, (string)g_kCmdGiver + ":partnerpong");
}
else if (kID == g_kPartner) {
g_iPermissionTimeout=0;
MoveToPartner();
} else {
Expand Down
Loading