Jump to content

Ruthven Ravenhurst

Resident
  • Posts

    491
  • Joined

  • Last visited

Everything posted by Ruthven Ravenhurst

  1. I'm on a mobile device, it's not giving me the option to insert code /* By Aryn Gellner pos - position (in region coordinates) to check against. * Additional Land Owner Test added by Ruthven Willenov, simplified by Strife */ integer is_rezzable(vector pos) { integer parcel_flags = llGetParcelFlags(pos); if(parcel_flags & PARCEL_FLAG_ALLOW_CREATE_OBJECTS) { return true;//Anyone can rez. No further checks are needed. } //Ok, not just anyone can rez. Maybe they share an owner or the land allows for group rezzing. //So lets get the parcel owner_id and group_id list details = llGetParcelDetails(pos, [PARCEL_DETAILS_OWNER, PARCEL_DETAILS_GROUP]); if(llList2Key(details, 0) == llGetOwner()) { return TRUE;//Owner can always rez. } //Since what we are going to return is a boolean just return the result of the boolean expression. return (parcel_flags & PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS) && llSameGroup(llList2Key(details, 1)); }
  2. In the llSameGroup page. Look in useful snippets http://wiki.secondlife.com/wiki/LlSameGroup#Useful_Snippets
  3. The function you are looking for would be llDialog, but there is more to it than that. You would need to have an llListen on the appropriate channel that you have assigned the llDialog to, then a listen event to receive the messages. Is this for an object/script you are creating, or for an object you already own, created by someone else?
  4. Here is what I have put together. The first one will put your camera 1 meter in front of the object being followed. I didn't like the results of having it following behind, as it made the object look jittery, maybe someone else can fine tune that? I rarely work with cameras, and it's usually a stationary setting when someone sits on an object. I placed it into a HUD object so that it can be clicked on while following the object. The second script is the test script I put into the object being followed. It communicates using llRegionSayTo when someone clicks it. If the person clicking it is wearing the hud object, the hud object will ask if they would like to follow the object they clicked integer onoff;//toggle to determine whether or not to show the the dialog when touched. won't show if it is in idle stateinteger comchan = -991119;//this channel is for communication between the object being followed and the hud device, make sure they use the same channelinteger avchan;integer GotCam;//toggle to determine if the script has permissions to control camerainteger handler;key object;//the uuid of the object being followedsetcamera(vector pos, rotation rot)//set the camera params based on the object's position and rotation{ llSetCameraParams([ CAMERA_ACTIVE, 1, // 1 is active, 0 is inactive CAMERA_FOCUS, pos+(<10.0,0.0,0.0>*rot),//focus 10 meters in front of the object CAMERA_FOCUS_LOCKED,TRUE, CAMERA_POSITION, pos+(<1.0,0.0,0.0>*rot),//place the camera 1 meter in front of the object-adjust as desired-<-1.0,0.0,1.0> will be 1 meter behind, and above the object CAMERA_POSITION_LAG,0.0, CAMERA_POSITION_LOCKED, TRUE // (TRUE or FALSE) ]);}getcam(key id){ llRequestPermissions(id,PERMISSION_CONTROL_CAMERA);}avlisten()//this is the listener the dialog will communicate to{ llListenRemove(handler); avchan = (integer)llFrand(-2000)-2000; handler = llListen(avchan,"",llGetOwner(),"");}default{ state_entry() { llListen(comchan,"","","Here");//listens for the word "Here" from the object being followed. Object should use llRegionSayTo to communicate only to the avatar(and their attachments) who touches it avlisten(); } on_rez(integer param) { avlisten(); } listen(integer chan, string name, key id, string message) { if(chan == comchan)// { object = id; llDialog(llGetOwner(), "Would you like to follow " + name +"?", ["Yes","No"], avchan); } else if(message == "Yes")//if the "Yes" button is pressed on the dialog { if(GotCam)//if we already have camera permissions, start following { list params = llGetObjectDetails(object,[OBJECT_POS,OBJECT_ROT]); vector pos = llList2Vector(params,0); rotation rot = llList2Rot(params,1); setcamera(pos,rot); onoff = TRUE; llSetTimerEvent(0.0001); } else//if we don't already have camera permissons, ask for them { getcam(id); } } else if(message == "Stop" || message == "No")//stops/doesn't start following and resets camera to default { onoff = FALSE; llSetTimerEvent(0.0); llClearCameraParams(); llSetCameraParams([CAMERA_ACTIVE, 0]); object = ""; } } attach(key id) { if(llGetAttached()) { getcam(id); } } run_time_permissions(integer perms) { if(perms & PERMISSION_CONTROL_CAMERA) { GotCam = TRUE;//permissions granted, toggle On if(object)//if the object uuid is alread captured before asking for permissions to control camera, let's start following { list params = llGetObjectDetails(object,[OBJECT_POS,OBJECT_ROT]); vector pos = llList2Vector(params,0); rotation rot = llList2Rot(params,1); setcamera(pos,rot); onoff = TRUE;//following started, toggle On llSetTimerEvent(0.0001); } } else//if permissons declined for some reason { onoff = FALSE; object = ""; llSetTimerEvent(0.0); llSetCameraParams([CAMERA_ACTIVE, 0]); } } timer() { if(object)//if the object uuid isn't NULL_KEY { list params = llGetObjectDetails(object,[OBJECT_POS,OBJECT_ROT]); vector pos = llList2Vector(params,0); rotation rot = llList2Rot(params,1); setcamera(pos,rot); } else//probably won't get here, but just in case the timer event sneaks in after telling it to stop(uuid will be cleared first) { llSetTimerEvent(0.0); llSetCameraParams([CAMERA_ACTIVE, 0]); } } touch_start(integer total_number) { if(onoff) { llDialog(llGetOwner(), "Click 'Stop' to stop following",["Stop","Cancel"],avchan); } } } // Shared Data (must be the same in the other script)// --------------------------------------------------integer CommsChannel = -991119;string TargetName = "Helicopter";default{ on_rez(integer StartParam){ llResetScript(); } touch_start(integer n) { llRegionSayTo(llDetectedKey(0),CommsChannel,"Here"); } state_entry(){ llSetObjectName(TargetName); llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]); llSetKeyframedMotion( [<0.0, 0.0, 10.0>, llEuler2Rot(<90, 45, 180> * DEG_TO_RAD), 5, <0.0, 0.0, -10.0>, llEuler2Rot(<270, 225, 360> * DEG_TO_RAD), 5], [KFM_MODE, KFM_PING_PONG]); }}
  5. Now that I'm home and read through that other thread more clearly, I see that what you meant about the avatar's perspective. I'm working on something now that will put the camera in place of the object being followed
  6. Camera focus offset I believe is where you would adjust it. Otherwise, from your original explanation, I think it's basically what you're looking for. I'm at work in RL, so replying on my phone. Not able to go in world to modify the script for an example
  7. This isn't the forum to ask for a script to be written for you, but we can help with scripts you may be having trouble with. Here is a thread that may be of help to you though https://community.secondlife.com/t5/LSL-Scripting/Need-help-with-a-camera-tracking-an-object/td-p/1450567
  8. It should work. There could be a error in the channel numbers, I can't really tell without seeing the button script. Also make sure you have the script running. It may have left it as not running when it wouldn't previously compile
  9. Right, before the If tests, put in the OwnerSay to make sure it's being heard
  10. Also, as you have it coded, it's going to apply the same color to every option, so you won't see a color difference if it's already that color
  11. How is it communicating the textures to the script? If it's saying the name of the texture, it would need to be in the object's inventory with this script. If it's saying the texture uuid, it should work. Are you getting any errors shouted? Try putting an llOwnerSay(msg); in the listen event to see what it's actually receiving. Also llGetSubString(msg,0,-1) is a little redundant as it's telling it to use the whole message anyways
  12. that's because it's only listening for the owner to speak, not objects. assuming you're using a hud with prim buttons, you'll need to leave the listen open, and then test if the speaking object is owned by the same owner I made the edits below in red to show you what I added Reymundo wrote: Okay so it compiled finally...but it's still not applying the texture and color... ////////////////////////////////////////////////////////////////////////////////////// [ MESH WORKSHOP SCRIPTS ]///////////////////////////////////////////////////////////////////////////////////////// integer ch0=-13577; //Same unique 5 digit number as controller.integer ch1=-13578; //Same unique 5 digit number as controller.integer ch2=-13579; //Same unique 5 digit number as controller.integer side = 5; //Side to apply the texture to. // ALL_SIDES = All sides of the object. // Numbers 1-8 = Face number of the object. integer side2 = 6; //Side to apply the texture to. // ALL_SIDES = All sides of the object. // Numbers 1-8 = Face number of the object. integer side3 = 3; //Side to apply the texture to. // ALL_SIDES = All sides of the object. // Numbers 1-8 = Face number of the object. integer side4 = 2; //Side to apply the texture to. // ALL_SIDES = All sides of the object. // Numbers 1-8 = Face number of the object.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////default{ state_entry() { llListen(ch0,"",,""); llListen(ch1,"",,""); llListen(ch2,"",,""); } listen(integer ch, string name, key id, string msg) { if(ch==ch0) { llSetTexture(llGetSubString(msg,0,-1),side); llSetColor(<0.5, 0.0, 0.0>, side ); llSetTexture(llGetSubString(msg,0,-1),side2); llSetColor(<0.5, 0.0, 0.0>, side2 ); } else if(ch==ch1) { llSetTexture(llGetSubString(msg,0,-1),side3); llSetColor(<0.5, 0.0, 0.0>, side3 ); } else if(ch==ch2) { llSetTexture(llGetSubString(msg,0,-1),side4); llSetColor(<0.5, 0.0, 0.0>, side4 ); } } }
  13. this sounds more like an issue with the SL avatar shape. You probably just need to adjust the avatar eye spacing/depth to fit the tiger head's eye socket and use the 0 offset
  14. another suggestion would be llGetInventoryType changed(integer change) { if(change & CHANGED_INVENTORY) { if(llGetInventoryType("NaS-T Fairy") == INVENTORY_OBJECT) { //do something } } } or add even more of a test, to make sure someone's not cheating llGetInventoryCreator changed(integer change) { if(change & CHANGED_INVENTORY) { if(llGetInventoryType("NaS-T Fairy") == INVENTORY_OBJECT) { key objcreator = llGetInventoryCreator("NaS-T Fairy");//creator of the object key scriptcreator = llGetInventoryCreator(llGetScriptName());//creator of this script if(objcreator == scriptcreator)//they both have the same creator, so this person was not cheating { //do something } } } }
  15. Shouldn't this: gOld = gCurrent; // gCurrent now becomes gOldList, ready for the next sensor scan Be?: gCurrent = gOldList; // gCurrent now becomes gOldList, ready for the next sensor scan
  16. thanks, I was basing my loops on an incrementing idx, which would cause it to ignore the last list elements depending on how many are removed. now I realize it makes more sense to decrement by starting at the end, and move towards the beginning. And if I assume correctly, decrementing at the beginning of each pass of the loop won't cause it to miss idx 0 (the first element of the list), right? you're referencing gCurrentList, but where are you declaring it? is that a global too? and that would need to be cleared at the beginning of each sensor event then? I have to run to work in real life, but "Ah ha" moment when realizing it was the decrementing loop you were intending. Either way, since I don't have enough avatars around to test more than 2 avatars, I added (temporarily) PASSIVE to the sensor, and test whether the detected type is an agent, or an object with "test object" in its name. Instead of targetting everyone (after passing the delay test), i'm targeting at random, but how do I make sure it's an even number? here's what I did, but it's never targeting the first element, 0 integer templen = llGetListLength(temp1)/2;//half the length integer tempidx = (integer)llFrand(templen)*2;//double the index to make sure it's an even number (shouldn't this still be 0 if it's 0 before doubling it?
  17. Ah yeah, I meant to add that I did do that already. When building the gCurrent list, I first check if they're in the old list, add them to the old list if they aren't, and update them if it's passed the delay Time Then I run a loop through the old list comparing it to the new list. I originally had 3 loops. One building the current list, one running through the current list and adding/updating them in the old list, and one running through the old list and removing them if they weren't still present. I put in a debug to say the name of the avatar at the targeting point, it did say everyone's name, I guess the loop just ran too fast to allow it to actually target them? I put in a sleep of 0.25 on each pass of the loop, that seemed to help, but still too fast. I think instead of targeting everyone when they come up, I'll choose a random one from the list at the end of the loop. But how to I make sure it chooses an avatar index and not the UNIX time attached to them? The avatars would be an even number and the times would be odd
  18. I've got this, but it seems to get caught up on targeting only one avatar comparelists(list gCurrent){ integer test = 1; integer i = 0; integer len = llGetListLength(gOldList); integer time = llGetUnixTime(); for(i = 0; i < len; i += 2) { key id = llList2Key(gOldList,i); if(id) { integer idx = llListFindList(gCurrent,[id]); integer oldtime = llList2Integer(gOldList,idx+1); if(~idx) { if((time - oldtime) >= gTriggerTime) { gOldList = llListReplaceList(gOldList, [time], i+1, i+1); target(id); } else { llParticleSystem([]); } } else { gOldList = llDeleteSubList(gOldList,i,i+1); } } } }
  19. also, how are you preserving the coloring of the text in your code posted here?
  20. integer idxOld = llListFindList(gOldList,[llDetectedKey(0)]); integer idxCurrent = llListFindList(gCurrentList,[llDetectedKey(0)]); if (~idxOld) { integer OldTime = llList2Integer(gOldList,idxOld+1); if ( (llGetUnixTime() - OldTime ) > gTriggerTime ) { gOldList = llListReplaceList(gOldList,[llGetUnixTime()],idxOld+1,idxOld+1); } if (!~idxCurrent) { gOldList = llDeleteSubList(gOldList,idxOld,idxOld+1);//this is the part that I'm concerned about. Would deleting the sublist from the list the loop is looking through throw off the index if each pass of the loop? gCurrent += [llDetectedKey(0),llGetUnixTime()]; } }
  21. I'm looking back at this again. Before releasing it, silly me didn't test it with more than one avatar in range. It was working fine when I was the only one in range. But now that I saw someone else step into range with me, I realized something was wrong, and probably to do with the loop. It wasn't delaying the response with everyone in range, even though we all remained in range. I was running the first loop through the gCurrent list to see if they are present in the old list, and responding if the time is over the delay. If not in the old list, they are targeted, and added to the old list. I was then running the second loop through the old list, creating a temp list, then at the end of the loop, the old list gets written over with the temp list (with avatars not in range being ommited) Maybe I misunderstood your intent with what you suggested, I guess you meant to only run one loop through the oldlist, adding the avatars that were not already there, and overwriting the unix time of the avatars that were there but over the delay time. but then you mentioned closing the sensor with, gOldlist = gCurrentList, which didn't make sense to me, because the work being done in the tests were manipulating the old list, but replacing it with the current list would overwrite the unixtimes that were previously recorded (the sensor repeats faster than the delay time) here's what I have for that section of the script. I'll see if you have any suggestions for cleaning it up. In the mean-time, i'll work on it some more myself to make one loop comparedlists(list gCurrent)//fed by sensor event which creates a list of avatar id's (but not unix time){ integer i; integer len = llGetListLength(gCurrent); for(i = 0; i < len; i++)//run a loop through the list fed into function and see if they are in the old list { //llParticleSystem([]); key id = llList2Key(gCurrent,i); integer idxOld = llListFindList(gOldList,[id]); integer time = llGetUnixTime(); if(~idxOld) { integer OldTime = llList2Integer(gOldList,idxOld+1); if((time - OldTime) > gTriggerTime) { string name = llGetDisplayName(id); gOldList = llListReplaceList(gOldList, [time],idxOld+1,idxOld+1); target(id); } } else if(!~idxOld) { gOldList += [id, time]; target(id); } } len = llGetListLength(gOldList); list temp; for(i = 0; i < len; i++)//after running through gCurrent, run a loop through the old list to see who was/wasn't sensed again. If they are, add them to the temp list. { i++; key id = llList2Key(gOldList,i); integer idxCurrent = llListFindList(gCurrent,[id]); if(~idxCurrent) { temp += llList2List(gOldList,idxCurrent,idxCurrent+1); } } gOldList = temp;//after running the loop through the old list, overwrite it with the temp list so as not to preserve avatars that have left the range}
  22. Thanks wherorangi, I used your suggestion there. Works great.
  23. nevermind, just had to go back and break down each line of the test again to find the missing parentheses, colored below for(i = 0; i < n; i++) { id = llDetectedKey(i); if((ignorelevel == 7)|| ((ignorelevel == 6) && ((idx < 0)||(llSameGroup(id) == FALSE))|| ((ignorelevel == 5) && (llSameGroup(id) == FALSE)|| ((ignorelevel == 4) && (idx < 0))|| ((ignorelevel == 3) && ((id != llGetOwner())||(idx < 0)||(llSameGroup(id) == FALSE))|| ((ignorelevel == 2) && (id != llGetOwner())||(llSameGroup(id) == FALSE))|| ((ignorelevel == 1) && ((id != llGetOwner())||(idx < 0))) {gCurrent += [id];} }
  24. the only way to make it look right is if you want both of those faces to move the same, and if you make the other faces a solid color or completely transparent, then animate all the sides as you would just the 2
  25. ok, so I got that part figured out using 2 different loops to first check the new list against the old one, then check the old one against the new one adding the ones that are present in both to a temp list, then over-writing the old list with the temp list now, trying to use your whitelist example, I got the access part right, but I'm also trying to do the opposite for the sensor to ignore people based on different ignore levels this part won't compile, and I can't seem to find the error. for(i = 0; i < n; i++) { id = llDetectedKey(i); if((ignorelevel == 7) || ((ignorelevel == 6) && ((idx < 0)||(llSameGroup(id) == FALSE))|| ((ignorelevel == 5) && (llSameGroup(id) == FALSE)|| ((ignorelevel == 4) && (idx < 0))|| ((ignorelevel == 3) && ((id != llGetOwner())||(idx < 0)||(llSameGroup(id) == FALSE))|| ((ignorelevel == 2) && (id != llGetOwner())||(llSameGroup(id) == FALSE)) || ((ignorelevel == 1) && ((id != llGetOwner())||(idx < 0))) {gCurrent += [id];} } and the menu for that setting so you can see clearer what each of those levels mean ignorelevelmenu(key id, integer chan){ llDialog(id, "Ignore Levels \nOnly Owner Can Change This \nCurrent: " + (string)ignorelevel + "\n\n0 = Owner Only \n1 = Owner + Ignore List \n2 = Owner + Group(anyone in same group as object) \n3 = Owner + Ignore List + Group \n4 = Ignore List Only(does not ignore owner) \n5 = Group(anyone in same group as object, does not ignore owner if they have different tag on) \n6 = Ignore List + Group(see levels 4 and 5) \n7 = Ignore Nobody (doesn't ignore anyone, including the owner)", ["Main", "Load", "Done", "(0)","(1)","(2)","(3)","(4)","(5)","(6)","(7)"],chan);}
×
×
  • Create New...