Jump to content

Innula Zenovka

Advisor
  • Posts

    10,720
  • Joined

  • Last visited

Posts posted by Innula Zenovka

  1. As Vania said, the only way that someone can force-tp you somewhere and prevent you from leaving is if you're using a third-party viewer with RLV enabled and if you're also wearing something that's designed to let people force-tp you and and stop you leaving (i.e. just using and RLV viewer and enabling RLV doesn't  do much in particular) and (at least with any legitimate RLV product) that you've explicitly told the thing you're wearing that people can use this functionality on you.

    The simplest way for your daughter to check if she's got RLV turned on or not (and people do get confused sometimes) is for you to send her an IM while she's online, simply saying "@version" (without the quotes -- just @version on a line on its own).   If RLV is turned on, she won't receive the message but you will receive an automatic reply with details of the version she's using.   Then she can simply turn it off and relog, or use the official LL viewer.

    If anyone does find themselves in a predicament from which they can't, because they're using RLV, extricate themselves, there's always a very simple solution.   Either turn off RLV in the viewer's preferences and relog or simply log out and relog using the official viewer.   

    But, as I said, the only way this can have happened with RLV is if she's wearing something designed for role-play that's let it happen.   If she'd like to IM me (here or in-world) I can probably help her identify the item and tell her how to use it safely.

     

    • Like 2
  2.  


    Kenbro Utu wrote:

    So you have to update the sit target as the child prim moves.  That could qualify as a pseudo-trick.  :smileywink:

     

    Well, sort of.   Except you aren't updating the sit target at all (that doesn't have any effect while the avatar is seated, you see).   The UpdateSitTarget function by Strife Onizuka and Escort DeFarge (which poseball-free animation systems like nPose and Perfect Sitter use) uses llSetLinkPrimitiveParams to move the avatar about in the way we've all wanted to when we've said, "If only you could update the sit target when someone's sitting". 

    I took their calculations and method and played round with them a bit to get the platform child prim and the avatar sitting on it to move together to the correct end positions without drifting too far apart in transit.

     

     

  3. In that case, so long as you're careful about what order you turn things on and off, I think llMove2Target should do what you want.   When I'm stopping stuff, I always turn physics off first, before I do anything else, and when I'm starting I always turn it on right at the end of calculating everying, just before I start moving again.  And if I'm making the object phantom, then I don't do that, if I can help it, until I'm actually moving.

    The not_at_target event, which is called constantly while you're moving, is a very good place to check if you're where you think you should be and to take any necessary corrective action.

    As a general point, I would suggest putting a listener in your moving physical object when you're testing it , though, that either turns physics off and uses posjump to bring the object back home, or simply kills it, and having a simple prim by you, which calls something like llRegionSay(some channel, "where the **** did you go?") when you touch it.    I have learned this the hard way.

  4.  


    Drega Riddler wrote:

    Well, the reason for not being physical is that i am going to have no track, so if it were physical it would just fall correct?

    I don't really understand.   Why should it, unless you set it to phantom while it's physical and not moving?    Certainly if you set it to phantom and then stop llMove2Target without turning off physics first it goes through the floor, as I have many times proved without intending to, but so long as you're careful about doing stuff in the right order it should be ok.

    The main advantage to having tracks, other than the cosmetic ones, is that it's an easy way to place the beacons the train has to look for.  But you're going to need to set those somehow in any case.

     

  5. I looked at Strife's UpdateSitTarget again, and had a play and, rather to my surprise, managed to come up with this -- called from the root prim -- which seems to do it.  

    I'm not competely sure I've done it right, but I tried rotating the "platform" prim on which I sit round on its z axis and ended up in the right direction, which was what worried me a bit.

     

    ETA -- it needs resetting before you first use it, I have realised, in order to set prim_pos.   It would be nice to reset it when the links change, but that's going to mess stuff up when the avatar gets off.  I'm sure there's a simple solution, but if you use it, be aware that the script needs resetting before first use.

     

    vector sit_target =<0.0,0.0,0.5>;//same as the sit target set in the platform primrotation sit_rot = ZERO_ROTATION;//same as the sit target set in the platform priminteger platform;integer toggle;key av;vector offset;vector size;vector prim_pos;find_prims(){	integer max=llGetNumberOfPrims()+1;	while(max--){		if(llToLower((string)llGetLinkPrimitiveParams(max,[PRIM_NAME]))=="platform"){			platform = max;		}	}}default{	state_entry()	{		find_prims();		list prim_details=llGetLinkPrimitiveParams(platform,[PRIM_POSITION]);		prim_pos =llList2Vector(prim_details,0)-llGetRootPosition()/llGetRootRotation();	}	changed(integer change){		if(change& CHANGED_LINK){			find_prims();		}	}	touch_start(integer total_number)	{		list av_details=[];		vector av_offset;		vector sit_offset = sit_target;		size = llGetAgentSize(llGetLinkKey(llGetNumberOfPrims()));		if(size!=ZERO_VECTOR){			av=llGetLinkKey(llGetNumberOfPrims());			av_details= llGetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_ROT_LOCAL]);		}		llOwnerSay(llList2String(av_details,0));		toggle=!toggle;		if(toggle){			offset =<prim_pos.x,prim_pos.y,5.0>;		}		else{			offset =prim_pos;		}		if(av_details!=[]){			sit_offset.z+=0.4;			vector v = llList2Vector(av_details,0)-llGetRootPosition()/llGetRootRotation();			llOwnerSay((string)v);			if(toggle){				av_offset =<prim_pos.x,prim_pos.y,5.0>;			}			else{				av_offset=prim_pos;			}			av_offset +=sit_offset;			av_offset =av_offset+(llRot2Up(sit_rot) * size.z * 0.02638) * llList2Rot(av_details,0);			llSetLinkPrimitiveParamsFast(llGetNumberOfPrims(),[PRIM_POSITION,av_offset*llGetRootRotation()]);		}		llSetLinkPrimitiveParamsFast(platform,[PRIM_POSITION,offset*llGetRootRotation()]);	}}

     

     

  6. Since you're re-thinking your approach, you might want to consider putting all the sub-menus into one script (which is what I would tend to do).

    The basic mechanism is something like this:

     

    list top_level_menus=    [        "Reds",    "Blues",    "Greens"        ];list reds=    [        "Dark Red",    "Medium Red",    "Light Red"        ];list blues=    [        "Dark Blue",    "Medium Blue",    "Light Blue"        ];list greens =    [        "Dark Green",    "Medium Green",    "Light Green"        ];list buttons;integer handle;integer dialog_channel;float timeout =30.0;key toucher = NULL_KEY;string caption;list order_buttons(list buttons)//compact function to put buttons in readable order{    return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4)        + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);}default{    state_entry()    {        dialog_channel = ((integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;        //quick way to calculate a channel based on the prim's uuid -- almost certain to be unique on the sim    }    touch_start(integer total_number)    {        if(llDetectedKey(0)!=toucher){            if(toucher==NULL_KEY){//if I'm not in use by anyone                toucher = llDetectedKey(0);//now i am            }            else{//I am in use                llRegionSayTo(llDetectedKey(0),0,"Sorry, but the item is in use right now");//so let's use a new function to say I am                return;//and don't do anything else            }        }        llListenRemove(handle);//close any old listeners that might be open still        handle=llListen(dialog_channel,"",toucher,"");//listen to the toucher on the dialog channel        buttons = ["Finished"]+top_level_menus;        caption = "Please choose a colour group";        llDialog(toucher,caption,order_buttons(buttons),dialog_channel);        llSetTimerEvent(timeout);//30 seconds to choose    }    listen(integer channel, string name, key id, string msg)    {        if("Finished"==msg){//if we've finished            llListenRemove(handle);//stop listening            llSetTimerEvent(0.0);//turn off the timer            toucher=NULL_KEY;//clear the "toucher" variable so we're ready for the next person            return;        }        else if ("Main Menu"==msg){            caption = "Please choose a colour group";            buttons = ["Finished"]+top_level_menus;        }        else if(~llListFindList(top_level_menus,[msg])){//if the message is one of the items in the list top_level_menu            buttons =["Finished"]+["Main Menu"];            if("Reds"==msg){//choose the appropriate choices for the next menu we present                buttons+=reds;            }            else if("Blues"==msg){                buttons+=blues;            }            else if ("Greens"==msg){                buttons+=greens;            }            caption = "Please choose a colour shade";        }        else if(~llListFindList(reds,[msg])){            llRegionSayTo(id,0,"You chose one of the reds, and your choice was "+msg);            //this is where you would do something with the menu choice        }        else if(~llListFindList(blues,[msg])){            llRegionSayTo(id,0,"You chose one of the blues, and your choice was "+msg);            //this is where you would do something        }        else if(~llListFindList(greens,[msg])){            llRegionSayTo(id,0,"You chose one of the greens, and your choice was "+msg);            //this is where you would do something        }        llDialog(toucher,caption,order_buttons(buttons),dialog_channel);        llSetTimerEvent(timeout);//30 seconds to choose    }    timer()//always do this in dialogs, in case the toucher has hit "ignore" or crashed or wandered off    {        llListenRemove(handle);//stop listening        llSetTimerEvent(0.0);//turn off the timer        toucher=NULL_KEY;//clear the "toucher" variable so we're ready for the next person    }}

     

     

  7. Why don't you want it to be physical?  The usual way to make such things is to have them call llMove2Target to move to a series of destinations, which either the script knows beforehand or which are specified by beacons which it detects en route.

    That makes it far easier to control the speed, since physics functions are for moving objects about the sim.

    The alternative, for a non-physical object, is repeatedly to call llSetPrimitiveParams to follow a similar course, but it means calling it repeatedly. on a very short timer, if the movement isn't to be very fast and jerky.  

    This is because physical movement actually moves the object between points on a sim, passing through intermediate ones, in the same way an avatar might walk or fly, while non-physical movement actually picks up the object from the sim at point A and replaces it at point B, and the sim tries, more or less successfully, to interpolate the apparent movement between the two points.  And unless you're repeatedly moving it very short distances over very short times -- fractions of a metre every fraction of a second -- it never looks right over long distances.

  8. Yes, it is banned.   And I find it very difficult to believe that there's any copies on the grid still working  -- LL in general and Soft Linden in particular did a pretty thorough job of nuking the scripts for the damn thing.

    No harm in ARing this person for harassment and disclosure of RL information, but I'm willing to bet he or she is just trying to intimidate your friends.   That seems to me far more likely than that LL missed any RZ installations.

  9. One thing an inexperienced scripter may not at first realise, (I didn't and I still remember it driving me almost to tears trying to figure out what was wrong) is that when you pass the link message to the submenu scripts, you have to have something like this in the receiver script:

     

    link_message(integer sender_number, integer number, string message, key id)	{		handle = llListen(dialog_channel,"",id,"");		llDialog(id,"Please choose an option",choices,dialog_channel);		//llDialog(llDetectedKey(0),...) won't work in link messages!)	}

     

     

     

     

     

  10. Void, my holovendors calculate a channel based on their uuid, and pass this to the rezzed objects as the start parameter, and the rezzed object listens for its uuid (as a string) to know when to llDie().

    In practical terms is there a great advantage to using llRegionSayTo, given that possiblility of there being another listener on the sim using that channel, let alone filtering for a message comprising the uuid of the rezzed object, is utterly remote?

  11. Are you sure about that, Rolig?  My reading of the OP is that the coffin and hearse are all part of the same linkset, and when the coffin moves -- using llSetLinkPrimitiveParamsFast, one would imagine -- its occupant, of course, doesn't move with it because the script thinks that the avatar is an extra prim that it's not been told to move.

    In those circumstances (coffin and hearse are linked together), I either would use something based on Strife's user function UpdateSitTarget, telling it to fire when I tell the coffin to move, or (which would probably be the simpler solution and might look better, too) have two corpse anims, identical save for their offsets, and switch between them for the two coffin positions

    My caveat for Marcia, though, is that the UpdateSitTarget function is brilliant, and isn't diffcult to use once you understand how to use it, but it's a bit incomprehensible the first time you read it (or I found it so).  If you want to have a shot at it, then maybe asking about it Scripting Tips would be an idea.  Or I will try to knock together a simple working example over the weekend if I can find the time.

  12. May we ask what you need it for?  As Void says, they only work under certain circumstances (and even then, in practice, I've always discovered drawbacks to using them that weren't immediately  appararent when I thought I needed one), and it may be that we can suggest an alternative method for whatever it is you want to do.

  13. I see.   But it certainly seems to be the case that if I use llRegionSayTo(uuid, rlvrc, message); the message is only received by the rlv relay worn by uuid, and that the other relays in range don't have to parse the message, only to discard it when they find it's not for them, even though they're listening on rlvrc.   I've just tested that.

    I wonder if there's any way to tell relays to reply using a specified channel other than the main rlv one.   I know you can use @notify to make them use another channel in addition to the rlvrc, but there doesn't seem any way to turn the rlvrc replies off, which presumably spams other people's relays, too.

    Still, it's very good news this can cut down traffic by half.

  14. The point for RLV isn't so much that avatars can't listen on negative channels, though you are right to say they can't, but that RLV only listens to commands in the form llOwnerSay("@something-or-other") so you need an object you own, a relay, to pick up requests from objects that don't belong to you, parse them, and pass them on to your viewer in the form of llOwnerSay.

    The great thing about this is that now, while there will still have to be a lot of open listeners on the rlv relay channel, you can now apparently direct your commands to your victim's relay without all the other relays in earshot having to pick them up, parse them, determine that they're not meant for them, and silently discard them.    This, I know from doing product demos on RP sims, is a major issue when there's a lot of relays about.   It can easily take 20 or 30 seconds for something to happen that is almost instantaneous on my building platform.

    I've got to test it properly, of course, but I've just gone in quickly, and

     

    integer rlvrc = -1812221819;integer handle;integer my_channel;default{	state_entry()	{		my_channel = (integer)llFrand(1000000.0)+1000; // has to be positive since the avatar's replying	}	touch_start(integer total_number)	{		llListenRemove(handle);		key av = llDetectedKey(0);		handle = llListen(my_channel,"",av,"");		llSetTimerEvent(20.0);		llRegionSayTo(av,rlvrc,"checking,"+(string)av+",@version="(string)my_channel);	}	listen(integer channel, string name, key id, string message)	{		llListenRemove(handle);		llOwnerSay(message);	}	timer()	{		llListenRemove(handle);		llSetTimerEvent(0.0);	}		}

     

     

     

    certainly works.   This should mean I can make my toys work far better simply by changing all the instances of  llSay(rlvrc,"some command") into llRegionSayTo((key)victim,rlvrc, "some command").

    This, presumably, has  very positive implications for the performance of many combat systems, too, at least those where your hud and that of your opponent talk to each other.

  15.  


    Void Singer wrote:

    now, you can target, not only a single avatar or object, but also when targeting an avatar on a non-zero channel, it targets all the attachments on that av...

    and the channel is PRIVATE... no more pollution of the region channels... I am seriously loving this function a whole bunch more now.

    Void.. does this mean that llRegionSayTo(avatar's uuid,-1812221819, "some message"); is going to be picked up by that avatar's rlv relay without adding to the congestion on the rlv relay channel?

     

  16.  


    Jenni Darkwatch wrote:

    All good points, and IMO all true. Scripts in SL are, mostly, atrocities as it is.

     

    The main reason for that, I suspect, is that all too often someone will get hold of a perfectly good script -- perhaps from the script library -- that does its job as it should.   He edits it a bit, and then some time later someone asks in a builders' group, "anyone got a script to do such-and-such?"  

    The first person passes his over, and then, soon after, an edited version of his edited version gets passed to another builder who "doesn't know much about scripting but I can edit them a bit" who, more by luck than good judgment gets it to work for his purposes, possibly by dropping bits of another script in... and so it goes on.

    A while ago, someone gave me a gun script to have a look at that they'd got from a friend but couldn't get to work.    The thing was a bloated nonsense with whole sections, clearly by a variety of different people, that either did nothing at all or cancelled out what something else did.  I told him it was gibberish and that I was amazed it had ever worked, to which he replied, "but it's by a Linden -- look at the creator field". 

    So I looked more closely, and realised it had started out as the pop-gun script in everyone's library before half a dozen different people had hacked it about.    I gave him a copy of the original and explained to him how to use it, checked what he did with it  and he ended up with a decent script. 

    Then there's the related reason, I guess, that someone decides to write a script for sale that has to be endlessly configurable, often by notecards,  to adapt to the particular circumstances in which it's to be used, and you end up with something that's very good at covering all the bases but massive overkill for the particular base that needs covering on any particular occasion.   I can't be the only person who started out thinking that the Timeless Door Script was wonderful, though possibly more complex than necessary for what I wanted to do (and certainly too complex for making a wardrobe),  and then, on deciding to learn a bit about scripting for myself, came across Void's really simple door and got a bit of a shock.

    But I don't really see there's solution to the problem, other than helping people write better scripts for themselves.  

    • Like 1
  17. Depends what country you're in, jules.  Residents of Northern Ireland (and, for all I know, of other parts of the UK) in your position have reported success using their National Insurance number, for example, (but I don't know if that still works).   But that's not much help if you're not in NI, any more than would be an equivalent fix that works for the French (if there is one) would be much use for a German resident and vice versa.

  18. Someone asked me to help them tweak a script they'd bought, which I did, and while I was so doing, I noticed something I've never seen before.

    The script was switching between listening to the owner on integer chat_channel and integer dialog_channel, depending on whether there was a menu open or not.   Now, when I do this, I have a global called integer handle, and then say

    llListenRemove(handle);
    handle = llListen(dialog_channel,"",owner,"");
    // or
    handle = llListen(chat_channel,"",owner,"");

     as appropriate, which is how I learned to do it from the old lsl wiki.

    The way this script did it, though, was  on the lines of

     

    llListen(-999,"",owner,"");//open the dialog listener
    //and then
    llListenRemove(-999);//to close it

    I don't think anything gets closed that way, and I've certainly never seen it done like that.  

    I thought the integer you remove in llListenRemove(integer number) was the callback number and nothing to do with the channel.   However, the original script was clearly written by someone who was reasonably competent, so I'm wondering if it's a shortcut I didn't know about.

     

     

×
×
  • Create New...