Jump to content

Dialogger - dialogs using prims


Rufus Darkfold
 Share

You are about to reply to a thread that has been inactive for 3910 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

The new version will not fit in one message!   It is split between this and the first reply.   A hud containing this is available here

// dialogger - dialogs using prims
// To put a dialog prim on the screen, send a chat to channel 444 or a link message to 44400:
// [/outchan] name,p,px,v
// /outchan = (optional) / character followed by return chat channel number followed by space.  (The [ ] are not part of the message) 
// name = field label or texture
// p = location to place control (rotation: <lowerleft.x,lowerleft.y,upperright.x,upperright.y>)
// px (rotation) = bounds or control type:
//   <1,0,0,0> texture (texture name in newtext)
//   <1,1,0,0> texture picker.  Drop any full-perm texture on it to send its UUID as its value.
//   <2,0,0,0> on/off button green/red
//   <2,r,g,b>  (0<(r,g,b)<1) menu button in color rgb
//   <3,lo,0,hi> 3 vertical sliders with a range from lo to hi
//   <3,lo,2,hi> 1 2-dimensional xy-slider and 1 vertical z slider with a range from lo to hi
//    otherwise <lowerlimit.x,lowerlimit.y,upperlimit.x,upperlimit.y> slider control in 1 or 2 dimensions
//    zero bounds for dimension not being used (except use 1 to force values to integers).
// v = value (vector) to display.  Scalar values are passed as <x,0,0>
//
// If name specifies a dialog prim that is already being displayed, that one is updated.
//
// An empty message clears all dialog prims (makes them invisible)
//
// Link messages are returned on 44401.  Chat messages are also returned on outchan if specified above:
// name = field label or texture
// name:v
// v = value (vector) to display.  Scalar values are passed as <x,0,0>
float version=0.4;
float touchrate=0.3;
debugout(string outstr)
{
//llOwnerSay(outstr);
}
integer controlbits = -1;  // turn on the undocumented controls too
integer mapside = 0;
//vector light = <1,1,1>;
//vector dark = <.2,.2,.3>;
integer havecontrols = 0;
vector newval;
vector newst;
integer hlisten;
integer touchedside;
vector touched;
integer lasttouchedside;
integer lastindex = -1;
vector lasttouched;
vector lastval;
vector taper;
vector shear;
integer dialogactive;
float transparency = 0.5;
float minscale = .1;
float dimpl = 1;
integer transpmarker = 2;
integer mychannel = 444;
integer ochannel = 445;
string page;
list settingvalue;
list settingchild;  // child assigned to each settings item
list settingminmax; 
list settingname;
list settingbox; // <minx,miny, maxx, maxy> bounding box
integer chatreply;
integer primbankidx = -1;
integer primsdesired;
integer permissionsdesired;
key chatsender;

positionmarkers()
{
    if (!dialogactive) return;
    integer i;
    //for (i=1; i<avmarker; i++) llSetLinkAlpha(i, 1.0 - transparency, ALL_SIDES);
    if (llGetListLength(settingname)) {
        llMessageLinked(LINK_THIS, 44403, "", "");
    }
                                    
    for (i=0; i<llGetListLength(settingchild); i++){
        integer child = llList2Integer(settingchild, i);
        rotation p = llList2Rot(settingbox, i); // <leftbottom.x, leftbottom.y, righttop.x, righttop.y>
        if (p == ZERO_ROTATION){
            llSetLinkPrimitiveParamsFast(child,
                                  [PRIM_POSITION, <0,1,0>, PRIM_COLOR, ALL_SIDES, <0.5,0.5,0.5>, 0.1,
                                   PRIM_ROT_LOCAL, llEuler2Rot(<0,PI/2,0>),
                                   PRIM_TEXT, "", <0.5,0.5,0.5>, 0.1]);
        }
        vector v = llList2Vector(settingvalue, i);
        rotation px = llList2Rot(settingminmax, i);
        if ((px.z > px.x) && (px.s > px.y)) {
            vector vv = llList2Vector(settingvalue, i);
            newval.z = vv.y;
        }
        //debugout("positionmarkers: " + llDumpList2String([child,v,p,px],"|"));
        positionmarker(child, v, p, px, llList2String(settingname, i));
    }
    if (havecontrols) {
        llTakeControls(controlbits, TRUE, TRUE);                        
        havecontrols = 0;
    }
    lastindex = -1; 
}

float maxdelta = 0.05;
float dragspeed = .1;
float controlspeed = .01;
       
initpage()
{
    transparency = 1.0-llGetAlpha(mapside);
    debugout("init page");
    settingname = [];
    settingbox = [];
    settingminmax = [];
    settingvalue = [];
    dialogactive++; // force markers to be cleared
    positionmarkers();
    //llSetColor(light, mapside);
    llSetText("", ZERO_VECTOR, 0.0);
    dialogactive = 0;
}

string fmtv(vector v, integer siz)
{
    integer n = (siz-4)/3;
    return "<" +fmtf(v.x,n) +"," +fmtf(v.y, n) + "," + fmtf(v.z,n) + ">";
}

string fmtf(float f, integer siz)
{
    string s=(string)f;
    integer n = llStringLength(s) - siz;
    if (n > 0) {
        if (!~llSubStringIndex(llGetSubString(s,-n,-1),"."))
            s = llDeleteSubString(s,-n,-1);
    }
    return s;
}

positionmarker(integer child, vector v, rotation p, rotation px, string newtext)
// child = child id of control,
// v = value (vector) to display
// p = location to place control (rot: <lowerleft.x,lowerleft.y,upperright.x,upperright.y>)
// px (rot) = bounds or control type
// newtext = field label or texture
{
    debugout("positionmarker: " + llDumpList2String([child,v,p,px,newtext],"|"));
    vector scale=llGetScale();
    vector color=<1,1,1>;
    float alpha = 1.0 - transparency;
    vector mpos;
    vector msize;
    list plist;
    rotation rot = ZERO_ROTATION;
    string texture;
    integer texface = 0;
    if (p == ZERO_ROTATION){  // make it disappear
        llSetLinkPrimitiveParamsFast(child,
                                  [PRIM_POSITION, <0,1,0>, PRIM_COLOR, ALL_SIDES, <0.5,0.5,0.5>, 0.03,
                                   PRIM_ROT_LOCAL, ZERO_ROTATION, PRIM_SIZE, <.01,.01,.01>,
                                   PRIM_TEXT, "", <0.5,0.5,0.5>, 0.1]);
        return; 

    }
    vector texoff;
    vector texrpt = <.7,.7,0>;
    float offmin = .3; 
    mpos = <(p.x+p.z)/2, (p.y+p.s)/2, scale.z+(child*.01)+.02>;
    msize = <(p.z-p.x)*scale.x, (p.s-p.y)*scale.y, .01>;
    plist = [PRIM_TYPE, PRIM_TYPE_BOX, 0, <0,1,0>, 0.0, ZERO_VECTOR, <1,1,0>,ZERO_VECTOR];
    if ((px.x == 1.0) && (px.z == 0.0)) {
        texrpt = <1,1,0>;
        if (px.y == 0.0) {
            texture = newtext;
            alpha = 1.0 - (transparency/3);
        } else if (px.y == 1.0) {
            texture = "1a9658ba-ce85-2eb4-d6b1-c79887b861a5";
        }
        color = <1,1,1>;  
    } else if ((px.x == 2) && (px.z < 2)) {  // menu button
        vector prof=<.515,.75,0>;
        rot = <-0.707080, -0.707134, 0.000025, 0.000000>;
        msize = <(p.s-p.y)*scale.y, (p.z-p.x)*scale.x*8.4, .01>;
        //llOwnerSay("before "+(string)msize.x);//////////
       if (msize.x < .013) {
            prof.x=.7-msize.x;
            msize.x*=3;
        } else if (msize.x < .02) {
            prof.x=.68-msize.x;
            msize.x*=2;
        } else if (msize.x < .04) {
            prof.x=.68-msize.x*2.5;
            msize.x*=1.5;
        } else if (msize.x < .072) {
            prof.x=.68-msize.x*2.5;
            //msize.x*=1.2;
        }
        //llOwnerSay("after "+(string)msize.x);//////////
        //alpha = 1.0 - transparency;
        plist = [PRIM_TYPE, PRIM_TYPE_TUBE, PRIM_HOLE_DEFAULT, <.695,.8,0>, .95, ZERO_VECTOR, <1,.5,0>, <-.5,0,0>, prof, <0,1,0>, 1.0, 0.0, 0.0]; 
	texface = 2;
        if (px == <2,0,0,0>) {  // green for "on" or 1,  red for "off" or 0
            if (v.x) 
                color = <0,1,0>;
            else
                color = <1,0,0>;
            } else {
               color = <px.y,px.z,px.s>;  // use specified color
        }
    } else {    // set the texture offset to place the dot in the right place.
        texture = "2ef039b7-931e-23e1-4c2e-0b9d90b1916b"; // mostly transparent with a yellow dot in the middle
        if (havecontrols == child)
            color = <1,.7,0>;
        if (px.x == px.z) {
            if (px.x == 1.0) {
                integer y = llRound(v.y);
                v.y = (float)y;
                newtext += "  " + (string)y;
            } else {
                   newtext += "\n" + fmtf(v.y,4);
               }
            texoff = <0, offmin-((v.y-px.y)*offmin*2/(px.s-px.y)), 0>;
            texrpt.x = .12;
        } else if (px.y == px.s) {
            if (px.y == 1.0) {
                integer x = llRound(v.x);
                v.x = (float)x;
                newtext += "  " + (string)x;
            } else {
                newtext += "  " + fmtf(v.x,4);
            }
            texoff = <offmin-((v.x-px.x)*offmin*2/(px.z-px.x)), 0, 0>;
            texrpt.y = .12;
        } else if ((px.x == 3) && (px.z < 3)) {
            texrpt.x = .12;
            texoff = <0, offmin - ((1.0 - ((v.z - px.y) / (px.s - px.y))) * offmin * 2 ), 0>;
            plist += [PRIM_TEXTURE, 2, texture, texrpt, texoff, PI/2];
            newtext += "\n" + fmtv(v, 16);	    
            if (px.z == 0.0) {
                plist += [PRIM_TYPE, PRIM_TYPE_BOX, 0, <0,1,0>, 0.0, ZERO_VECTOR, <.33,1,0>, ZERO_VECTOR];
                texoff.y = offmin - ((v.x - px.y) * offmin * 2 / (px.s - px.y));
                plist += [PRIM_TEXTURE, 4, texture, texrpt, texoff, PI/2];
                texoff.y = offmin - (( v.y - px.y) * offmin * 2/ (px.s - px.y));
            } else if (px.z == 2.0) {
                string texture2 = "dede3802-362e-ed09-cf69-d7c8dd3412ef";
                plist += [PRIM_TYPE, PRIM_TYPE_BOX, 0, <0,1,0>, 0.0, ZERO_VECTOR, <1,1,0>, <-.16,0,0>,
                          PRIM_TEXTURE, 2, texture2, <.17,.7,0>, texoff, PI/2];
                texoff = <offmin-((v.x-px.y)*offmin*2/(px.s-px.y)), offmin-((v.y-px.y)*offmin*2/(px.s-px.y)), 0>;
                texrpt.x = .7;
                msize.x *= .83;
                mpos.x += .16 * msize.x;
            }
        } else {
            texoff = <offmin-((v.x-px.x)*offmin*2/(px.z-px.x)), offmin-((v.y-px.y)*offmin*2/(px.s-px.y)), 0>;
            newtext += "\n" + fmtv(v, 16);
        }
    }
    // suppress text if it has more than 3 dashes (to exclude uuids, and allow the label to be suppressed by --foo--
    if (llGetListLength(llParseStringKeepNulls(newtext,[],["-"])) > 3) newtext = "";
    msize.x *= taper.x;
    msize.y *= taper.y;
    mpos.x = (mpos.x + shear.x - .5) * scale.x * taper.x; 
    mpos.y = (mpos.y + shear.y - .5) * scale.y * taper.y;
    debugout(" v=" + (string)v + " mpos=" + (string)mpos + " texture " + texture);
    llSetLinkPrimitiveParamsFast(child, plist + 
                                  [PRIM_POSITION, mpos, PRIM_COLOR, ALL_SIDES, color, alpha,
                                   PRIM_ROT_LOCAL, rot, PRIM_SIZE, msize,
                                   PRIM_TEXTURE, texface, texture, texrpt, texoff, 0.0,
                                   PRIM_TEXT, newtext, <1,1,0>, 1-(transparency*.75)]);
}
               
updatemarker(integer i, vector t, integer side)
{
    integer child = llList2Integer(settingchild, i);
    rotation p = llList2Rot(settingbox, i); // <leftbottom.x, leftbottom.y, righttop.x, righttop.y>
    rotation px = llList2Rot(settingminmax, i);
    string newtext = llList2String(settingname,i);
    newst = t;
    newst.z = 0;
    if (px == <2,0,0,0>) {
        vector oldval = llList2Vector(settingvalue, i);
        if (oldval.x) {
            newval = <0,0,0>;
        } else {
            newval = <1,0,0>;
        }
    } else {
        lastindex = i;
        if (px.z >= px.x) {
            newval = <newst.x*(px.z-px.x)+px.x, newst.y*(px.s-px.y)+px.y, 0>;
        } else {
	           if ((px.x == 3) && (px.z < 3)) { // 3-way control
	               newval = llList2Vector(settingvalue, i);
	               float s = px.s - px.y;
        	       if (!side) {
                    newval.y = t.y * s + px.y;
                    if (px.z == 2) newval.x = t.x * s + px.y;
                } else if (side == 2) newval.z = t.x * s + px.y;
		               else if (side == 4) newval.x = (1.0 - t.x) * s + px.y;
	           } else
    	           newval = <newst.x, newst.y, 0>;
        }
    }

    string outstr=newtext + ":";
    if ((px.x == 1.0) && (px.y == 1.0) && (px.z == 0.0)) {
        key oldtex = llList2Key(settingvalue, i);
        key tex = llList2Key(llGetLinkPrimitiveParams(child,[PRIM_TEXTURE, side]),0);
        if (tex == "1a9658ba-ce85-2eb4-d6b1-c79887b861a5") {
            if (t != ZERO_VECTOR)
                tex = "";   // actual mouse click should clear it.
            else
                return;
        }
        outstr += (string)tex;
        settingvalue = llListReplaceList(settingvalue, [tex], i, i);
    } else {
        outstr += (string)newval;
        settingvalue = llListReplaceList(settingvalue, [newval], i, i);
    }
    positionmarker(child, newval, p, px, newtext);
    llMessageLinked(LINK_SET, 44401, outstr, "");
    if (chatreply)
        llRegionSayTo(chatsender, ochannel, outstr);
    return;
}

process_msg(string msg, integer chatflag)
{
    debugout("msg="+msg);
    if (msg == "") {
        initpage();
        return;
    }
    if (!llGetListLength(settingname)) {
        dialogactive++;
        //llSetColor(dark, mapside);
    }
    if (llGetSubString(msg,0,0)=="/"){
        integer x = llSubStringIndex(msg," ");
        ochannel = (integer)llGetSubString(msg,1,x-1);
        msg = llDeleteSubString(msg,0,x);
    }
    chatreply = chatflag;
    list blist = llParseString2List(msg, ["\n",";"],[]);
    while (blist != []) {
        list clist = llCSV2List(llList2String(blist,0));
        blist = llDeleteSubList(blist, 0, 0);        
        if (clist != []) {
            string newname = llList2String(clist, 0);
            if (llGetListLength(clist) > 2) {
                //transparency = 0.2;
                integer x = llListFindList(settingname, [newname]);
                string snewbox = llList2String(clist,1);
                rotation newbox = (rotation)snewbox;
                string snewminmax = llList2String(clist,2);
                rotation newminmax = (rotation)snewminmax;
                vector newvalue = (vector)llList2String(clist,3);
                if (~x) {
                    if (snewbox != "")    
                        settingbox = llListReplaceList(settingbox, [newbox], x, x);
                    if (snewminmax != "")
                        settingminmax = llListReplaceList(settingminmax, [newminmax], x, x);
                    settingvalue = llListReplaceList(settingvalue, [newvalue], x, x);
                } else {
                    settingname += newname;
                    settingbox += newbox;
                    settingminmax += newminmax;
                    settingvalue += newvalue;
                }
            } else {
                vector color;
                if (llGetListLength(clist) == 2)
                    color = (vector)llList2String(clist,1);
                else
                    color = <1,1,1>;
                llSetText(llList2String(clist,0), color, 1.0);
            }
        }
    }
    positionmarkers();
}

newshape()
{
    list newshapelist = llGetPrimitiveParams([PRIM_TYPE]);
    taper = llList2Vector(newshapelist, 5);
    shear = llList2Vector(newshapelist, 6);
}

Link to comment
Share on other sites

Continued from preceding message:

default {                state_entry()    {        integer i;        // assume we can use all child prims until told otherwise        for (i=2; i<=llGetNumberOfPrims(); i++) {            settingchild += i;            llClearLinkMedia(i, 0);        }        newshape();        initpage();        //llSetText("", ZERO_VECTOR, 0.0);        if (llGetAttached()) {            //llSetRot(llEuler2Rot(<0, PI*1.5, PI*1.5>));            permissionsdesired = PERMISSION_TRACK_CAMERA|PERMISSION_TAKE_CONTROLS|PERMISSION_ATTACH;        }        hlisten = llListen(mychannel, "", "", "");        llRequestPermissions(llGetOwner(), permissionsdesired);    }            attach(key id)    {        debugout("attached to "+(string)llGetAttached());        if (id != NULL_KEY) {            permissionsdesired = permissionsdesired & ~ PERMISSION_CHANGE_LINKS;            //llSetRot(llEuler2Rot(<0, PI*1.5, PI*1.5>));            //positionmarker(2, ZERO_VECTOR,  ZERO_ROTATION, ZERO_ROTATION, "");            if ((llGetPermissions() & permissionsdesired) == permissionsdesired) {                llTakeControls(CONTROL_FWD |                    CONTROL_BACK |                    CONTROL_LEFT |                    CONTROL_RIGHT |                    CONTROL_ROT_LEFT |                    CONTROL_ROT_RIGHT |                    CONTROL_UP |                    CONTROL_DOWN, TRUE, TRUE);            } else {                llRequestPermissions(llGetOwner(), permissionsdesired);            }        }    }    run_time_permissions(integer perm)    {           if (perm & PERMISSION_TAKE_CONTROLS) {            debugout("Taking Controls");            llTakeControls(controlbits, TRUE, TRUE);        }    }        changed(integer what)    { //llOwnerSay("changed " +(string)what);        if (what & CHANGED_SHAPE) {               list newshape = llGetPrimitiveParams([PRIM_TYPE]);            taper = llList2Vector(newshape, 5);            shear = llList2Vector(newshape, 6);        }        if (what & CHANGED_SCALE) {            vector s=llGetScale();            if (s.z > .02) // don't display if folded up                positionmarkers();        }        if (what & CHANGED_TEXTURE) {           integer i;            for (i=0; i<llGetListLength(settingminmax);i++) {                rotation px = llList2Rot(settingminmax,i);                if ((px.x == 1.0)  && (px.y == 1.0) && (px.z == 0.0)) {                    llSleep(1.0); // Let them see it                    updatemarker(i, ZERO_VECTOR, (integer)px.s);                }            }        }    }    control(key id, integer level, integer edge)    {        if (havecontrols){            integer side = 0;            //debugout("level=" +hex(level) + " edge=" +hex(edge));             if (!~lastindex) return;            //rotation cbox = llList2Rot(settingbox,lastindex);            if (level & (CONTROL_LEFT+CONTROL_ROT_LEFT)) {                newst.x += controlspeed;                side = 4;            }            if (level & (CONTROL_RIGHT+CONTROL_ROT_RIGHT)) {                newst.x -= controlspeed;                side = 4;            }            if (level & CONTROL_FWD) newst.y += controlspeed;            if (level & CONTROL_BACK) newst.y -= controlspeed;            if (level & CONTROL_UP) {                newst.z -= controlspeed;                side = 2;            }            if (level & CONTROL_DOWN) {                newst.z += controlspeed;                side = 2;            }                        if (newst.x < 0) newst.x = 0;            if (newst.x > 1) newst.x = 1;            if (newst.y < 0) newst.y = 0;            if (newst.y > 1) newst.y = 1;            updatemarker(lastindex,newst, side);            llSleep(0);        }     }        touch_start(integer num)    {        if (havecontrols) {            llTakeControls(controlbits, TRUE, TRUE);                                    havecontrols = 0;            llOwnerSay("Controls released");            llSetLinkPrimitiveParamsFast(llList2Integer(settingchild, lastindex),                                         [PRIM_COLOR, ALL_SIDES, <1,1,1>, 1.0-transparency]);        }        if (!dialogactive) return;        integer t;        for (t=0; t<num; t++) {            integer child = llDetectedLinkNumber(t);            touchedside = llDetectedTouchFace(t);            touched = llDetectedTouchST(t);            llResetTime();                                integer i = llListFindList(settingchild, [child]);            if (~i) {                rotation r = llList2Rot(settingminmax, i);                if (r.x > r.z) { // some kind of button		                  updatemarker(i, touched, touchedside);                }               } else {                    debugout("Touched side " + (string)touchedside);                    return;            }        }    }      touch(integer num)    {        if (!dialogactive) return;        integer t;        for (t=0; t<num; t++) {            integer child = llDetectedLinkNumber(t);            vector scale = llGetScale();            vector pos = llGetLocalPos();            vector newtouched = llDetectedTouchST(t);            vector prevtouched = lasttouched;            integer newtouchedside = llDetectedTouchFace(t);            if (~newtouchedside) {                lasttouched = newtouched;                lasttouchedside = newtouchedside;            } else {                if (lasttouched.x < .05) lasttouched.x = 0.0;                if (lasttouched.x > .95) lasttouched.x = 1.0;                if (lasttouched.y < .05) lasttouched.y = 0.0;                if (lasttouched.y > .95) lasttouched.y = 1.0;            }            integer i;                      debugout("child: "+(string)child + " touch: " +(string)lasttouched+ " side " + (string)touchedside +"/" +(string)lasttouchedside);                i = llListFindList(settingchild, [child]);            if (~i) {                rotation r = llList2Rot(settingminmax, i);                if ((r.x < 3) && (r.x > r.z)) // some kind of button                    return;                if (lasttouched != prevtouched)              		    updatemarker(i, lasttouched, lasttouchedside);                lastindex = i;                if ((llGetTime() > 5.0) && (lasttouched == touched)) {                    llTakeControls(controlbits, TRUE, FALSE);                    havecontrols = child;                    llOwnerSay("Keyboard/Joystick now controls " + llList2String(settingname, i) +"\nClick again to release controls");                    llSetLinkPrimitiveParams(child,                                             [PRIM_COLOR, ALL_SIDES, <1,.7,0>, 1.0-transparency]);                }                llSleep(touchrate);            }        }    }                                   listen(integer chan, string name, key id, string msg)    {        if (llGetOwner() != id) {            if (llList2Key(llGetObjectDetails(id, [OBJECT_OWNER]),0) != llGetOwner())                return;        }        if (chan == mychannel) {            chatsender = id;            process_msg(msg, TRUE);        }    }                link_message(integer sender, integer num, string msg, key id)    {        debugout("Linked Msg(" + (string)num + "):" + msg + " {" + (string)id + "}");        if (num == 44400) {            process_msg(msg, FALSE);        } else if (num == 44402) {            transparency = 1.0-llGetAlpha(mapside);            if (msg != "") {                list newlist = llCSV2List(msg);                settingchild = [];                while (newlist != []) {                    settingchild += (integer)llList2String(newlist,0);                    newlist = llDeleteSubList(newlist, 0,0);                 }            }            positionmarkers();        } else if (num == 44409) {            settingchild = [];            integer i;            for (i=2; i<=llGetNumberOfPrims(); i++) {                settingchild += i;                llClearLinkMedia(i, 0);            }            process_msg(msg, FALSE);        }    }}

 

Link to comment
Share on other sites

  • 3 months later...
  • 1 month later...
You are about to reply to a thread that has been inactive for 3910 days.

Please take a moment to consider if this thread is worth bumping.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...