Skip to content

oc_titler.lsl setting additions #1178

@PandaCakes12321

Description

@PandaCakes12321

I made some additions to oc_titler.lsl to make the Titler a bit smarter in busy locations or if you are sitting with someone.

Added AutoHide option
Hides the title automatically when another avatar/agent comes close
Toggle button in the Titler menu

Added adjustable distance for the hide sensor
New “Set Range” button
Wearer can type any value 0.5m–10m
Updates the sensor instantly

These features don't replace anything, Or break OC behavior.
Runs if the user turns it on off by default

If this is useful to others, feel free to merge it.

string g_sSubMenu="Titler";
string g_sVersion="8.3";

integer LINK_CMD_DEBUG=1999;
integer g_iNoB64=FALSE;
integer g_iWasUpgraded=FALSE;

integer CMD_OWNER=500;
integer CMD_WEARER=503;

integer NOTIFY=1002;
integer REBOOT=-1000;

integer LM_SETTING_SAVE=2000;
integer LM_SETTING_REQUEST=2001;
integer LM_SETTING_RESPONSE=2002;
integer LM_SETTING_DELETE=2003;
integer LM_SETTING_EMPTY=2004;

integer MENUNAME_REQUEST=3000;
integer MENUNAME_RESPONSE=3001;

integer DIALOG=-9000;
integer DIALOG_RESPONSE=-9001;
integer DIALOG_TIMEOUT=-9002;

string UPMENU="BACK";

integer bool(integer a){return a;}

list g_lCheckboxes=["□","▣"];
string Checkbox(integer v,string l){return llList2String(g_lCheckboxes,bool(v))+" "+l;}

list g_lMenuIDs;
integer g_iMenuStride;
list g_lOwner;
list g_lTrust;
list g_lBlock;

string g_sTitle="";
vector g_vColor=<1,1,1>;
integer g_iShow=FALSE;
integer g_iOffset=8;
integer g_iTextPrim;
key g_kWearer;
integer g_iLocked=FALSE;

integer g_iProximityHide=TRUE;
integer g_iAgentNear=FALSE;
float g_fDetectRange=2.0;

Dialog(key k,string p,list c,list u,integer page,integer auth,string name){
    key id=llGenerateKey();
    llMessageLinked(LINK_SET,DIALOG,(string)k+"|"+p+"|"+(string)page+"|"+llDumpList2String(c,"`")+"|"+llDumpList2String(u,"`")+"|"+(string)auth,id);
    integer i=llListFindList(g_lMenuIDs,[k]);
    if(~i)g_lMenuIDs=llListReplaceList(g_lMenuIDs,[k,id,name],i,i+g_iMenuStride-1);
    else g_lMenuIDs+=[k,id,name];
}

Menu(key k,integer a){
    Dialog(
        k,
        "\n[Titler]\nUse Up/Down, Title, Color, Show/Hide, AutoHide, Range.",
        ["UP","DOWN","Set Title","Color","Set Range",Checkbox(g_iShow,"Show"),Checkbox(g_iProximityHide,"AutoHide")],
        [UPMENU],
        0,
        a,
        "Menu~Titler"
    );
}

ColorMenu(key k,integer a){
    Dialog(k,"\n[Titler]\nColor selection",["colormenu please"],[UPMENU,"Custom"],0,a,"Menu~Colors");
}

integer validvector(string s){
    list t=llParseString2List(s,[",","<",">"," "],[]);
    if(llGetListLength(t)!=3)return FALSE;
    t=llParseString2List(s,[",","<",">"," ","."],[]);
    string x=(string)t;
    integer i=llStringLength(x);
    while(i){--i;if(llGetSubString(x,i,i)!="0"&&(integer)llGetSubString(x,i,i)==0)return FALSE;}
    return TRUE;
}

vector text2col(string s){
    list t=llParseString2List(s,[",","<",">"," "],[]);
    integer n;
    integer i;
    integer v;
    while(i<3){
        v=llList2Integer(t,i);
        if(v<0)t=llListReplaceList(t,[0],i,i);
        else if(v>1)n=TRUE;
        if(v>255)t=llListReplaceList(t,[255],i,i);
        ++i;
    }
    vector o=(vector)("<"+llList2CSV(t)+">");
    if(n)o/=255;
    return o;
}

integer SAVE_SHOW_HIDE=1;
integer SAVE_OFFSET=2;
integer SAVE_TITLE=4;
integer SAVE_COLOR=8;

Save(integer w){
    if(w&SAVE_SHOW_HIDE){
        if(g_iShow)llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_show=1","");
        else llMessageLinked(LINK_SET,LM_SETTING_DELETE,"titler_show","");
    }
    if(w&SAVE_OFFSET)llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_offset="+(string)g_iOffset,"");
    if(w&SAVE_TITLE){
        if(!g_iNoB64)
            llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_title="+llStringToBase64(g_sTitle),"");
        else
            llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_title="+g_sTitle,"");
    }
    if(w&SAVE_COLOR)llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_color="+(string)g_vColor,"");
    Titler();
}

Titler(){
    if(g_iProximityHide && g_iAgentNear){
        llSetLinkPrimitiveParams(g_iTextPrim,[PRIM_TEXT,"",ZERO_VECTOR,0]);
        return;
    }
    if(g_iShow){
        string o="";
        integer i;
        while(i<g_iOffset){o+=" \n";++i;}
        llSetLinkPrimitiveParams(g_iTextPrim,[PRIM_TEXT,g_sTitle+o,g_vColor,1]);
    }else{
        llSetLinkPrimitiveParams(g_iTextPrim,[PRIM_TEXT,"",ZERO_VECTOR,0]);
    }
}

ScanFloatText(){
    integer i;
    integer e=llGetNumberOfPrims();
    for(i=0;i<=e;i++){
        list p=llGetLinkPrimitiveParams(i,[PRIM_NAME,PRIM_DESC]);
        if(~llSubStringIndex(llList2String(p,0),"FloatText")){g_iTextPrim=i;return;}
        if(~llSubStringIndex(llList2String(p,1),"FloatText")){g_iTextPrim=i;return;}
    }
    g_iTextPrim=LINK_THIS;
}

NukeOtherText(){
    integer i=1;
    integer e=llGetNumberOfPrims();
    for(;i<=e;i++)llSetLinkPrimitiveParamsFast(i,[PRIM_TEXT,"",ZERO_VECTOR,0]);
}

UserCommand(integer n,string s,key k){
    if(n<CMD_OWNER||n>CMD_WEARER)return;

    if(n==CMD_OWNER&&s=="runaway"){
        g_lOwner=g_lTrust=g_lBlock=[];
        return;
    }

    if(llToLower(s)==llToLower(g_sSubMenu)||llToLower(s)=="menu "+llToLower(g_sSubMenu)){
        Menu(k,n);
        return;
    }

    if(n!=CMD_OWNER)return;

    list L=llParseString2List(s,[" "],[]);
    string t=llList2String(L,0);
    string v=llToLower(llList2String(L,1));
    string p=llList2String(L,2);

    if(t=="title"){
        if(v==""){
            Dialog(k,"What should the title say?",[],[],0,n,"Textbox~Title");
            return;
        }
        g_sTitle=llDumpList2String(llList2List(L,1,-1)," ");
        Save(SAVE_TITLE);
    }
    else if(t=="titler"){
        if(v=="color"){
            if(!validvector(p))ColorMenu(k,n);
            else{g_vColor=text2col(p);Save(SAVE_COLOR);}
        }
        else if(v=="show"){g_iShow=TRUE;Save(SAVE_SHOW_HIDE);}
        else if(v=="hide"){g_iShow=FALSE;Save(SAVE_SHOW_HIDE);}
        else if(v=="up"){++g_iOffset;Save(SAVE_OFFSET);}
        else if(v=="down"){--g_iOffset;if(g_iOffset<0)g_iOffset=0;Save(SAVE_OFFSET);}
        else if(v=="plain"){
            g_iNoB64=!g_iNoB64;
            string m="0Titler plain text mode is now set to ";
            if(g_iNoB64){
                llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_plain=1","");
                m+="PLAIN";
            } else {
                m+="BASE64";
                llMessageLinked(LINK_SET,LM_SETTING_DELETE,"titler_plain","");
            }
            llMessageLinked(LINK_SET,NOTIFY,m,k);
        }
        else if(v=="autohide"){
            if(p=="on")g_iProximityHide=TRUE;
            else if(p=="off")g_iProximityHide=FALSE;
            Titler();
        }
        else if(v=="range"){
            float d=(float)p;
            if(d<0.5)d=0.5;
            if(d>10)d=10;
            g_fDetectRange=d;
            llSensorRepeat("",NULL_KEY,AGENT,g_fDetectRange,TWO_PI,5.0);
        }
        else if(v=="title"){
            g_sTitle=llDumpList2String(llList2List(L,2,-1)," ");
            UserCommand(n,"title "+g_sTitle,k);
        }
    }
}

integer ALIVE=-55;
integer READY=-56;
integer STARTUP=-57;

default{
    on_rez(integer n){llResetScript();}
    state_entry(){llMessageLinked(LINK_SET,ALIVE,llGetScriptName(),"");}
    link_message(integer s,integer n,string st,key k){
        if(n==REBOOT&&st=="reboot")llResetScript();
        else if(n==READY)llMessageLinked(LINK_SET,ALIVE,llGetScriptName(),"");
        else if(n==STARTUP)state active;
    }
}

state active{
    on_rez(integer t){llResetScript();}
    state_entry(){
        if(llGetStartParameter()!=0)llResetScript();
        llSetMemoryLimit(40000);
        g_kWearer=llGetOwner();
        NukeOtherText();
        llSensorRepeat("",NULL_KEY,AGENT,g_fDetectRange,TWO_PI,5.0);
    }

    changed(integer c){
        if(c&CHANGED_LINK){
            integer o=g_iTextPrim;
            ScanFloatText();
            if(g_iTextPrim!=o)NukeOtherText();
            Titler();
        }
    }

    sensor(integer n){
        if(!g_iAgentNear){
            g_iAgentNear=TRUE;
            Titler();
        }
    }

    no_sensor(){
        if(g_iAgentNear){
            g_iAgentNear=FALSE;
            Titler();
        }
    }

    link_message(integer s,integer n,string st,key k){
        if(n>=CMD_OWNER&&n<=CMD_WEARER)UserCommand(n,st,k);

        else if(n==MENUNAME_REQUEST&&st==g_sParentMenu)
            llMessageLinked(s,MENUNAME_RESPONSE,g_sParentMenu+"|"+g_sSubMenu,"");

        else if(n==DIALOG_RESPONSE){
            integer i=llListFindList(g_lMenuIDs,[k]);
            if(i!=-1){
                string m=llList2String(g_lMenuIDs,i+1);
                g_lMenuIDs=llDeleteSubList(g_lMenuIDs,i-1,i-2+g_iMenuStride);
                list P=llParseString2List(st,["|"],[]);
                key av=llList2Key(P,0);
                string msg=llList2String(P,1);
                integer a=llList2Integer(P,3);
                integer r=TRUE;

                if(a!=CMD_OWNER){
                    llMessageLinked(LINK_SET,NOTIFY,"0%NOACCESS% to titler options",av);
                    llMessageLinked(LINK_SET,a,"menu "+g_sParentMenu,av);
                    return;
                }

                if(m=="Menu~Titler"){
                    if(msg==UPMENU){
                        r=FALSE;
                        llMessageLinked(LINK_SET,a,"menu "+g_sParentMenu,av);
                    }
                    else if(msg=="UP"){++g_iOffset;Save(SAVE_OFFSET);}
                    else if(msg=="DOWN"){--g_iOffset;if(g_iOffset<0)g_iOffset=0;Save(SAVE_OFFSET);}
                    else if(msg==Checkbox(g_iShow,"Show")){g_iShow=!g_iShow;Save(SAVE_SHOW_HIDE);}
                    else if(msg==Checkbox(g_iProximityHide,"AutoHide")){g_iProximityHide=!g_iProximityHide;Titler();}
                    else if(msg=="Set Title"){
                        r=FALSE;
                        Dialog(av,"What should the title say?",[],[],0,a,"Textbox~Title");
                    }
                    else if(msg=="Color"){
                        r=FALSE;
                        ColorMenu(av,a);
                    }
                    else if(msg=="Set Range"){
                        r=FALSE;
                        Dialog(av,"Enter proximity distance in meters (0.5–10):",[],[],0,a,"Textbox~Range");
                    }

                    if(r)Menu(av,a);
                }

                else if(m=="Menu~Colors"){
                    if(msg==UPMENU){
                        Menu(av,a);
                        r=FALSE;
                    }
                    else if(msg=="Custom"){
                        Dialog(av,"[Titler Custom Color]\nType R,G,B",[],[],0,a,"Textbox~Color");
                        r=FALSE;
                    }
                    else g_vColor=(vector)msg;

                    if(r)ColorMenu(av,a);
                    Save(SAVE_COLOR);
                }

                else if(m=="Textbox~Title"){
                    g_sTitle=msg;
                    Menu(av,a);
                    Save(SAVE_TITLE);
                }

                else if(m=="Textbox~Color"){
                    if(!validvector(msg)){
                        llRegionSayTo(av,0,"Not a valid vector!");
                        Dialog(av,"[Titler Custom Color]\nTry again:",[],[],0,a,"Textbox~Color");
                        return;
                    }
                    g_vColor=text2col(msg);
                    ColorMenu(av,a);
                    Save(SAVE_COLOR);
                }

                else if(m=="Textbox~Range"){
                    float v=(float)msg;
                    if(v<0.5)v=0.5;
                    if(v>10)v=10;
                    g_fDetectRange=v;
                    llSensorRepeat("",NULL_KEY,AGENT,g_fDetectRange,TWO_PI,5.0);
                    Menu(av,a);
                }
            }
        }

        else if(n==DIALOG_TIMEOUT){
            integer i=llListFindList(g_lMenuIDs,[k]);
            g_lMenuIDs=llDeleteSubList(g_lMenuIDs,i-1,i+3);
        }

        else if(n==LM_SETTING_RESPONSE){
            list L=llParseString2List(st,["_","="],[]);
            if(llList2String(L,0)=="global"){
                if(llList2String(L,1)=="locked")g_iLocked=llList2Integer(L,2);
                else if(llList2String(L,1)=="checkboxes")g_lCheckboxes=llCSV2List(llList2String(L,2));
            }
            else if(llList2String(L,0)=="titler"){
                integer o=g_iTextPrim;
                ScanFloatText();
                if(g_iTextPrim!=o)NukeOtherText();

                string v=llList2String(L,1);

                if(v=="show")g_iShow=TRUE;
                else if(v=="offset")g_iOffset=(integer)llList2String(L,2);
                else if(v=="title"){
                    if(!g_iNoB64)g_sTitle=llBase64ToString(llList2String(L,2));
                    else g_sTitle=llList2String(L,2);
                    if(g_iWasUpgraded){
                        g_sTitle=llList2String(L,2);
                        if(!g_iNoB64)
                            llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_title="+llStringToBase64(g_sTitle),"");
                        else
                            llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_title="+g_sTitle,"");
                        g_iWasUpgraded=FALSE;
                    }
                }
                else if(v=="color")g_vColor=(vector)llList2String(L,2);
                else if(v=="on"){
                    g_iWasUpgraded=TRUE;
                    llMessageLinked(LINK_SET,LM_SETTING_REQUEST,"ALL","");
                    llMessageLinked(LINK_SET,LM_SETTING_DELETE,"titler_auth","");
                    llMessageLinked(LINK_SET,LM_SETTING_DELETE,"titler_on","");
                    llMessageLinked(LINK_SET,LM_SETTING_DELETE,"titler_height","");
                    g_iShow=(integer)llList2String(L,2);
                    llMessageLinked(LINK_SET,LM_SETTING_SAVE,"titler_show="+(string)g_iShow,"");
                }
                else if(v=="plain"){
                    g_iNoB64=TRUE;
                    llMessageLinked(LINK_SET,LM_SETTING_REQUEST,"ALL","");
                }

                Titler();
            }
        }

        else if(n==LM_SETTING_DELETE){
            list L=llParseString2List(st,["_"],[]);
            if(llList2String(L,0)=="global"&&llList2String(L,1)=="locked")g_iLocked=FALSE;
        }

        else if(n==LINK_CMD_DEBUG){
            if(st=="ver"){
                llInstantMessage(k,llGetScriptName()+" "+g_sVersion);
                return;
            }
            llInstantMessage(k,"SHOW "+(string)g_iShow);
        }

        else if(n==REBOOT&&st=="reboot")llResetScript();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions