Jump to content

Ares Halostar

Resident
  • Posts

    99
  • Joined

  • Last visited

Everything posted by Ares Halostar

  1. Thanks for all the suggestions. I finally got this thing to report in the format I needed. Whilst I use the make notecard function to save the results, in LSL you will need to direct the output the way you need to. If you wish to use it for a normal 256 sized region, you will have to adjust the Max scan float to 256 instead of 512. Here is the script that works for me: list gListCountsAndOwners; // Sorted list count+owner pairs integer gOffset; integer gIndex; integer gListLength; list gPrclID; integer gTotPrims; integer gNUM; float gX; float gY; CalcPrims(vector Loc) { list TempList = llGetParcelPrimOwners(Loc); gListLength = llGetListLength(TempList); if (!gListLength) { llSetText("[ERROR]\n Couldn't get Parcel Prim Owners", <1,0,0>, 1); } else { // Produce a copy of the list suitable for sorting by count, i.e. count then key integer x; for ( ; x < gListLength; x += 2) { string owner = osKey2Name(llList2Key(TempList, x)); integer count = llList2Integer(TempList, x + 1); integer index = llListFindList(gListCountsAndOwners, [owner]); if (index % 2 == 1) // make sure the find is in column 2. owner name might be a number { // prim owner is in list, so update --index; // decrement to point to prim count count += llList2Integer(gListCountsAndOwners, index); gListCountsAndOwners = llListReplaceList(gListCountsAndOwners, [count], index, index); } else { // prim_owner is not in list, so append gListCountsAndOwners += [count, owner]; } } //llOwnerSay(llList2CSV(gListCountsAndOwners)); } } default { state_entry() { llSetText("Show Prim Owners\nTouch to scan region", <1,1,1>, 1); gListCountsAndOwners=[]; } touch_start(integer total_number) { llSetText("Scanning...\n", <1,1,0>, 1); gPrclID = []; gTotPrims = 0; // Start scan in the SW corner of the sim gX = 4.0; gY = 4.0; gNUM = 0; integer i; for (i = 0; i < 4096; i++) { list parcel = llGetParcelDetails(<gX,gY,100.0>,[PARCEL_DETAILS_ID,PARCEL_DETAILS_NAME]); key temp = llList2Key(parcel,0); // The parcel's UUID string parcel_name = llList2String(parcel,1); // The parcel's name if (parcel_name == "") { parcel_name = "(no name)"; } if (!~llListFindList(gPrclID,[temp])) // Have we scanned this parcel before? { ++gNUM; llSetText("Processing Parcel:\n"+(string)parcel_name,<0,1,0>,1.0); CalcPrims(<gX,gY,100.0>); gPrclID += [temp]; } if (gX < 512.0) // Increment X but don't let X go outside the sim borders { gX +=8.0; } if (gX > 512.0) // If it does, reset X and increment Y { gY += 8.0; gX = 4.0; } if (gY > 512.0) // Don't let Y go outside the sim boders. If it does, wrap up the scan .... { string NCname = llGetRegionName(); string ReportName = "## Region: "+(string)NCname+" - Total Parcels: "+(integer)gNUM+"\n"; gListCountsAndOwners = llListSort(gListCountsAndOwners, 2, FALSE); integer Length = llGetListLength(gListCountsAndOwners); integer z; integer Inc; string Output; for ( ; z < Length; z++) { Inc+=1; Output+=(string)llList2String(gListCountsAndOwners,z); Output+=" "; if(Inc==2) { Output+="\n"; Inc=0; } } osMakeNotecard(NCname, ReportName+"\n"+Output); llOwnerSay("Total Parcels: "+(integer)gNUM+"\nReport Notecard "+(string)NCname+" saved to prim inventory"); gListCountsAndOwners=[]; llSetText("Show Prim Owners\nTouch to scan region", <1,1,1>, 1); } } } } Thanks again for all the help.
  2. While this works in SL, I need it to work in Opensim as well, and llListSortStrided is not supported as yet. Basically what I am trying to achieve, is to scan a region's parcels, and find out how many prims the avatars are using on that region. I will attach the code that I am experimenting with now. list gListCountsAndOwners; // Sorted list count+owner pairs list gListNamesAndCounts; // List of owner names + prim counts integer gOffset; integer gIndex; key gDataserverID; integer gListLength; list gPrclID; integer gTotPrims; integer gNUM; float gX; float gY; list NameList; CalcPrims(vector Loc) { list TempList = llGetParcelPrimOwners(Loc); gListLength= llGetListLength(TempList); if (!gListLength) { llSetText("[ERROR]\n Couldn't get Parcel Prim Owners", <1,0,0>, 1); } else { // Produce a copy of the list suitable for sorting by count, i.e. count then key integer x; for ( ; x < gListLength; x += 2) { gListCountsAndOwners += llList2Integer(TempList, x+1); gListCountsAndOwners += osKey2Name(llList2Key(TempList, x)); } } } default { state_entry() { llSetText("Prim Owners\n", <1,1,1>, 1); gListCountsAndOwners=[]; NameList=[]; } touch_start(integer total_number) { llSetText("Scanning...\n", <1,1,0>, 1); gPrclID = []; gTotPrims = 0; // Start scan in the SW corner of the sim gX = 4.0; gY = 4.0; gNUM = 0; list TEMPLIST; TEMPLIST+="## Region: "+(string)llGetRegionName()+"\n"; integer i; for (i = 0; i < 4096; i++) { list parcel = llGetParcelDetails(<gX,gY,100.0>,[PARCEL_DETAILS_ID,PARCEL_DETAILS_NAME]); key temp = llList2Key(parcel,0); // The parcel's UUID string parcel_name = llList2String(parcel,1); // The parcel's name if (parcel_name == "") { parcel_name = "(no name)"; } if (!~llListFindList(gPrclID,[temp])) // Have we scanned this parcel before? { ++gNUM; llSetText("Processing \n"+(string)parcel_name,<0,1,0>,1.0); CalcPrims(<gX,gY,100.0>); gPrclID += [temp]; } if (gX < 512.0) // Increment X but don't let X go outside the sim borders { gX +=8.0; } if (gX > 512.0) // If it does, reset X and increment Y { gY += 8.0; gX = 4.0; } if (gY > 512.0) // Don't let Y go outside the sim boders. If it does, wrap up the scan .... { //Tally List //Sort List gListCountsAndOwners = llListSort(gListCountsAndOwners, 2, FALSE); string NCname = llGetRegionName(); osMakeNotecard(NCname,gListCountsAndOwners); //Create Notecard with data llOwnerSay("Total Parcels: "+(integer)gNUM); FinalOutput(); gListCountsAndOwners=[]; NameList=[]; llSetText("Touch to start scan",<1.0,1.0,0.0>,1.0); } } } }
  3. I have a list of data that basically gives an integer, and avatar name. The integer is the result of how many prims an avatar may have on a given parcel. But my avatar and others are repeated in the list several times and with different amounts (as I own several parcels on that region) ie: 1367, Ares Halostar, 456, Drongo Bonk, 325, Ares Halostar, 345, Mr Zonk, 567, Drongo Bonk My name appears twice, as does another, but I want to total the integers and create a new list: 1692, Ares Halostar, 1023, Drongo Bonk, 345, Mr Zonk. Lists always do my head in, even though this is a simple 2 strided list. Please can someone work out a quick routine for me to use ? Thanks in advance.
  4. It works, not as smooth as I'd hoped, but with some fine tuning I will get there. I had to divide by the root rotation TWICE to get the result I wanted with the upper prim. The final code is below: integer getLinkNum(string primName) { integer primCount = llGetNumberOfPrims(); integer i; for (i=0; i<primCount+1;i++) { if (llGetLinkName(i)==primName) return i; } return FALSE; } rotation TurnTowards(vector pos) { vector this = llGetPos() + <0, 0, 0.75>; // Calculate the base (left/right rotation) vector direction = llVecNorm(pos - this); direction.z = 0; rotation final = llRotBetween(<1,0,0>, direction); // Calculate the turret (up/down rotation) float dist = llVecDist(<pos.x, pos.y, 0>, <this.x, this.y, 0>); rotation pitch = llRotBetween(<1,0,0>, llVecNorm(<dist, 0, pos.z - this.z>)); // Set both values llSetLinkPrimitiveParamsFast(getLinkNum("Main"), [PRIM_ROTATION, final, PRIM_LINK_TARGET, getLinkNum("UpDown"), PRIM_ROTATION, pitch * final/llGetRootRotation()/llGetRootRotation()]); // This is used later for rezzing return pitch * final; } default { state_entry() { llSensorRepeat("", "", AGENT, 96.0, PI,1.0); } sensor(integer num_detected) { TurnTowards(llDetectedPos(0)); } }
  5. integer getLinkNum(string primName) { integer primCount = llGetNumberOfPrims(); integer i; for (i=0; i<primCount+1;i++) { if (llGetLinkName(i)==primName) return i; } return FALSE; } rotation TurnTowards(vector pos) { vector this = llGetPos();// + <0, 0, 1.06>; // Calculate the base (left/right rotation) vector direction = llVecNorm(pos - this); direction.z = 0; rotation final = llRotBetween(<1,0,0>, direction); // Calculate the turret (up/down rotation) float dist = llVecDist(<pos.x, pos.y, 0>, <this.x, this.y, 0>); rotation pitch = llRotBetween(<1,0,0>, llVecNorm(<dist, 0, pos.z - this.z>)); // Set both values llSetLinkPrimitiveParamsFast(getLinkNum("Main"), [PRIM_ROTATION, final, PRIM_LINK_TARGET, getLinkNum("UpDown"), PRIM_ROTATION, pitch * final]); // This is used later for rezzing return pitch * final; } default { state_entry() { llSensorRepeat("", "", AGENT, 96.0, PI,1.0); } sensor(integer num_detected) { TurnTowards(llDetectedPos(0)); } } That is the code I am using, and it nearly works, the bottom prim "Main" turns as it should, but the top prim "UpDown" doesn't quite do what it is required and ends up at a different angle as per the photo:
  6. I have two Prims. The bottom one points one face to an avatar (disregarding avatars height, so it only tracks left and right). That simple code is: default { state_entry() { llSensorRepeat("", "", AGENT, 96.0, PI,1.0); } sensor(integer num_detected) { vector Pos = llDetectedPos(0); vector MyPos = llGetPos(); vector target_posA = <Pos.x, Pos.y, MyPos.z>; llRotLookAt(llRotBetween(<1.0, 0.0, 0.0>,llVecNorm(target_posA-MyPos)), 1.0, 0.1); } } That works fine. The linked child prim above it, I want it to point to the avatar as well, but not only with the left and right movement, but also up and down. Seems like a simple thing to accomplish, but rotations have always done my head in. As an example, think of a rocket launcher rotating on a base, with the actual rocket tube tracking up and down while the base moves around on it's own axis.
  7. Thanks panterapolnocy for your reply, and yes, that fixed my problem. For anyone else interested, this was for moving a clone that I had made in Opensim. But it could be applied to a primset as well. That is why I couldn't use other movement solutions.
  8. llMoveToTarget has a limitation of 65m, but I need to move something over that distance, and it can be hundreds of metres away. I know how to calculate the amount of "hops" needed, if I break it up to 50m movements. But how to do calculate the positions that the project needs to travel to. I've looked at the old warppos, but that is meant for llSetPos and uses llSetPrimitiveParams PRIM_POSITION, which I can't use. I hope I have explained myself enough.
  9. Brilliant. Perfect for what I need. Sometimes you just can't find what is staring you in the face. Thanks for that.
  10. I am making a simple combat prim that is worn above the head, giving basic info like health, but now I want to add a limited radar that gives target name, distance and which compass direction it is from the avatar. I can do the radar easily with distance, but getting a compass direction for each target is a headache. This has me stumped and if anyone can provide some simple code, I'd appreciate it.
  11. I simply asked for scripting advice. I didn't ask to be called a liar, and be called a griefer and that I should be banned. Stop with the head games. The above pyscho babble you wrote is insulting to say the least, and I ignored it for a while, but you persist. Now, the script problem is solved and nothing further needs to be said, unless you need to explain yourself more (which is not needed or wanted). THE END
  12. Thanks for your constructive advice PheebyKatz. The script now works, but not as it is presented here. What I posted earlier is just one part of the project that I was working on. There will be added checks besides the check for who is aiming at me. I will also add collision checking and checking the owner of the bullet that collided, and all these things together will ensure that no one gets shot, that shouldn't. Besides, I will not be using this outside of my parcel. It is my project and something that kept me interested. All things that shoot at people can be used to grief someone. It is how we use it that determines if we are a griefer or not. And for your info, a script similar to mine was created by someone on the old forums ages ago, so this is nothing new. SL for me was always about creating things. I've even sold a few things years ago.
  13. Thanks for you valid input, Wulfie. Fionalein, the core of the script in question was copied from the old LSL archives, dated 2008 or earlier. I am not the first, nor the last to use this script.
  14. God, some of you are toxic. Never have I been the subject of so much hate and ignorance. As I said, the script only targets avatars when they are aiming at you, and yes, you have to be in mouselook to aim at someone with a weapon. This line of code: determines if you have anyone's crosshairs are on you. Did you actually test out the script ? Obviously not, as you are incapable. Some people just like to get on their high horse and sprout crap. And as I said, I will only be using this script on my own land. I invite any Administrators to look at this post, and lock/close this thread, as I don't want to be the subject of more flaming. I have been in Second Life for over 10 years with various avatars, and never been accused of griefing. I used to enjoy the input of the advanced members of this forum, but a few individuals just can't look past their noob noses.
  15. Fionalein - The script actually detects when someone is aiming at you. Look at the script more closely. It doesn't just target anyone in mouselook, as that would be a silly thing to do. Berksey - I was only after a bit of friendly advice, nothing more. I have been in SL for many years, and I like to script, but I am no expert, and I sometimes ask for help on these forums. We are not all expert scripters. Lucia Nightfire - Again, as others, you have not bothered to read the script. It will ONLY target someone that is aiming at you in mouselook. I have no intention of using this script as a griefer tool. In fact, I only plan on using this script on my own parcel. Thankyou Rolig for your suggestion. I am already experimenting with that line of advice. Rolig, you were the only one to offer any constructive advice. I will think twice in future, when asking for help here.
  16. I have an attached prim, which is attached to the Avatar Centre. It basically detects if someone is aiming at me, and rotates the prim towards that avatar and fires a bullet. Rotation of the attached prim towards the target avatar works fine, but when it comes to rezzing the bullet towards the avatar, it instead, rezzes the bullet, and fires it, at the direction my avatar is facing. As I said, the attached prim rotates nicely to approximately the target's direction, but meh, the bullet fires where I am pointing. I can't work out the required rotations in the Fire() routine, as rotations always do my head in. Any help would be appreciated. vector vel; vector pos; vector DetPos; vector MyPos; string sName; integer LIFETIME = 1000; float SPEED = 75.0; float Distance; key target; key Hitter; //Notes llGetRootRotation - returns region rotation of avatar NOT of the object's root prim. // llGetRot - Returns a rotation that is the prim's rotation relative to the region's axes. // llGetLocalRot - Returns the rotation of the prim relative to the root.If called from the root prim, it returns the objects rotation. Fire() { rotation rot = llGetLocalRot(); vector vel = llRot2Fwd(rot); pos = llGetPos(); vel = vel * SPEED; llTriggerSound("Report", 1.0); llRezObject("Bullet2", pos, vel, rot, LIFETIME); } default { state_entry() { llSetText("", <1.0, 1.0, 1.0>, 1.0); llSensorRepeat("", "", AGENT, 96, PI, 1.0); } sensor(integer n) { integer i; list sweep; integer inc; for (i=0;i<n;++i) { if (llGetAgentInfo(llDetectedKey(i)) & AGENT_MOUSELOOK) { target = llDetectedKey(i); DetPos = llDetectedPos(i); MyPos = llGetPos(); Distance = llVecDist(DetPos, MyPos); if (llVecDist(llGetPos(), llDetectedPos(i)+llRot2Fwd(llDetectedRot(i))*llVecDist(llGetPos(),llDetectedPos(i))) < 1.5) { sweep += llDetectedName(i); inc = inc + 1; } if (i == n-1) { llSetText(llDumpList2String( sweep, "\n"), <1.0, 1.0, 1.0>, 1.0); string Aimer = llDumpList2String(sweep,"\n"); if (inc>0) { //llLookAt(DetPos,0.5,1.0); llLookAt(MyPos+(DetPos+<0,0,1> - MyPos) / llGetRootRotation(),0.5,1.0); llSetText(Aimer+" is Targetting me."+"\n Enemy at: "+(string)llRound(Distance)+" M",<1,1,0>,1.0); Fire(); } } } } } }
  17. I have owned a few of those Zombie rezzers for ages, and sometimes I have made turrets or guns to shoot them. Then I got lazy, and decided to get another scripted monster to chase and kill the zombies. To use my scripts, simply create a cube, put the main script in that. If have have a premade prim monster, you can link this prim to it (make it the root prim) and make sure that the cube comfortably covers your prim monster. At this stage, you will have a "chaser" monster, that will chase any scripted/moving prim called Zombie. I will also include a gun script, so you can make another prim, and link it to the main prim (just make sure the little gun prim is just outside, and to the front of your main prim (that you previously made and put over your monster). Also included is a simple gun flame script, that you can also put in the small gun prim. I will leave it up to you to make the Bullet, but I would make it something reasonably small, round (you can even put a flame script in that too.. kinda like a tracer effect) and make it Physical, and most importantly make the Bullet Temporary (or you will fill your parcel with spent bullets). So all up: Make the Main Prim and put in the main script Make the Gun Prim and put in both Gun and Flame scripts. Make your own Bullet (take it to your inventory when finished, then put the Bullet in the Gun Prim) If you have any problems, IM me in game. Here are the scripts: Main Movement Script // This script is mainly used to hunt other active/scripted Linksets (like those zombies in the rezzers). // But the script can be adapted to hunt Avatars as well. // Have fun, and use this script anyway you wish, except to grief others. // Ares Halostar. string sTarget = "Zombie";//Change this, for another target float fRange = 96.0; float fRate = 1.0; float fForce = 5.0; vector vKick_up = <0,0,0.25>; float fForward_kick; vector vHome = <49.32539, 129.264145, 21.5>; //Set this vector to somewhere on your parcel. vector vMyPos; Fire() { llMessageLinked(LINK_SET, 1, "Shoot", "");//Send message to linked prim to shoot a bullet at target } default { state_entry() { llSetStatus(STATUS_PHYSICS,TRUE); llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y,FALSE); llSetStatus(STATUS_ROTATE_Z, TRUE); llSensorRepeat( sTarget, "", ACTIVE | SCRIPTED, fRange, PI, fRate ); } sensor( integer number_detected ) { llSetStatus(STATUS_PHYSICS,TRUE); if (llOverMyLand(llGetKey()) == FALSE) { llMoveToTarget(vHome,0.4);//Return home if I am out of the Parcel } key kTarget = llDetectedKey(0);//Pick the nearest target llSensorRepeat( "", kTarget, ACTIVE | SCRIPTED, fRange, PI, fRate );//Only sense the above target integer i; for( i = 0; i < number_detected; i++ ) { vector vTargetPos = llDetectedPos(i); vMyPos = llGetPos(); float fDistance = llVecDist(vTargetPos, vMyPos); llLookAt(vTargetPos,0.2,1.0); llSetText((string)llKey2Name(kTarget)+" is at "+(string)llRound(fDistance)+" Metres \n ",<1,1,1>,1.0); Fire(); fForward_kick = llFrand(2.0); float fTime = fDistance/2;//Only used with llMoveToTarget, if you choose to change the motion to that. //Instead of llApplyImpulse, you could use llMoveToTarget, but you may have problems. //llMoveToTarget(vTargetPos, fTime); llApplyImpulse((vKick_up + <0,0,llFrand(2.5)>) * llGetMass(), FALSE);//Little jump up llApplyImpulse(-llVecNorm(vMyPos - vTargetPos) * fForward_kick * llGetMass(), FALSE);//Forward movement if (fDistance<=8.0)//Push Target away, as it is too close { vector vDirection = llVecNorm(vTargetPos-vMyPos); vector vImpulse = fForce * vDirection; vImpulse *= llGetObjectMass(kTarget); vImpulse *= llPow(llVecDist(vMyPos, vTargetPos), 3.0); vImpulse -= llDetectedVel(i); llPushObject(kTarget, vImpulse, ZERO_VECTOR, FALSE); } } } no_sensor() { llSetText("No "+(string)sTarget+"s Detected",<1,1,1>,1.0); llSetStatus(STATUS_PHYSICS,FALSE);//I only do this, so the prim doesn't fall over. vector vTempMyPos = llGetPos(); float fGround = llGround(ZERO_VECTOR); float Difference = (vTempMyPos.z - fGround); if(vTempMyPos.z<(fGround+1.2)) { llSetPos(vTempMyPos+<0,0,Difference>); } if (llOverMyLand(llGetKey()) == FALSE) { llSetStatus(STATUS_PHYSICS,TRUE); llMoveToTarget(vHome,0.4); llSetStatus(STATUS_PHYSICS,FALSE); } llSensorRepeat( sTarget, "", ACTIVE | SCRIPTED, fRange, PI, fRate ); } } Gun Scripts: fire() { rotation rot = llGetRot(); vector vel = llRot2Fwd(rot); vector pos = llGetPos(); pos = pos + vel; pos.z += 0.25; vel = vel * 100; //llTriggerSound("Report", 1.0); llRezObject("Bullet", pos, vel, rot, 1); //llTriggerSound("Report", 1.0); llRezObject("Bullet", pos, vel, rot, 1); } default { link_message(integer sender, integer num, string message, key id) { if (message == "Shoot") fire(); } touch_start(integer moo) { fire(); } } integer glow = TRUE; integer bounce = FALSE; integer interpColor = TRUE; integer interpSize = TRUE; integer wind = TRUE; integer followSource = FALSE; integer followVel = TRUE; integer pattern = PSYS_SRC_PATTERN_EXPLODE; key target = ""; float age = 1; float maxSpeed = 0.3; float minSpeed = 0.1; string texture ; float startAlpha = 1.0; float endAlpha = 0.05; vector startColor = <1,1,0>; vector endColor = <1,0,0>; vector startSize = <.2,.6,0>; vector endSize = <.0,.0,2>; vector push = <0,0,0>; float rate = 0.10; float radius = 0.02; integer count = 5; float outerAngle = 0; float innerAngle = 2.55; vector omega = <0,0,0>; float life = 1; integer flags; updateParticles() { flags = 0; if (target == "owner") target = llGetOwner(); if (target == "self") target = llGetKey(); if (glow) flags = flags | PSYS_PART_EMISSIVE_MASK; if (bounce) flags = flags | PSYS_PART_BOUNCE_MASK; if (interpColor) flags = flags | PSYS_PART_INTERP_COLOR_MASK; if (interpSize) flags = flags | PSYS_PART_INTERP_SCALE_MASK; if (wind) flags = flags | PSYS_PART_WIND_MASK; if (followSource) flags = flags | PSYS_PART_FOLLOW_SRC_MASK; if (followVel) flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK; if (target != "") flags = flags | PSYS_PART_TARGET_POS_MASK; llParticleSystem([ PSYS_PART_MAX_AGE,age, PSYS_PART_FLAGS,flags, PSYS_PART_START_COLOR, startColor, PSYS_PART_END_COLOR, endColor, PSYS_PART_START_SCALE,startSize, PSYS_PART_END_SCALE,endSize, PSYS_SRC_PATTERN, pattern, PSYS_SRC_BURST_RATE,rate, PSYS_SRC_ACCEL, push, PSYS_SRC_BURST_PART_COUNT,count, PSYS_SRC_BURST_RADIUS,radius, PSYS_SRC_BURST_SPEED_MIN,minSpeed, PSYS_SRC_BURST_SPEED_MAX,maxSpeed, PSYS_SRC_TARGET_KEY,target, PSYS_SRC_INNERANGLE,innerAngle, PSYS_SRC_OUTERANGLE,outerAngle, PSYS_SRC_OMEGA, omega, PSYS_SRC_MAX_AGE, life, PSYS_SRC_TEXTURE, texture, PSYS_PART_START_ALPHA, startAlpha, PSYS_PART_END_ALPHA, endAlpha ]); } default { state_entry() { } link_message(integer sender, integer num, string message, key id) { if (message == "Shoot") { updateParticles(); } } } You could also put in gun sounds. Or have the project chase avatars instead. Up to you. Have Fun !!
  18. Thanks for that advice Rolig. I was thinking along those lines myself. When the linkset does fall sideways, it falls slowly, but still follows the target - even though the linkset is now sideways on the ground. Resetting the script usually works, so am having a good look at the start of the script (with not so tired eyes this morning).
  19. Thanks for pointing out the fact that I had to turn on Physics first. First I have to point out, that this zombie is tracking multiple moving zombies. But as to the multiple llMoveToTarget calls, it is only scanning for zombies (in the first llSensorRepeat line - though I suppose I could just use llSensor there), then it picks the closest zombie (kTarget = llDetectedKey(0)), and the subsequent llSensorRepeat uses that UUID to track just the one zombie. It only moves to that zombie, and shoots it. It doesn't track all zombies. The reason I use - for (i = 0; i < number_detected; i++), is that the targets are moving, and in my thinking (I am probably wrong here), that the target's position is continually changing and needs to be tracked or my zombie just goes to the old position of the target. It works quite well, up to a point, then it goes wonky and falls over. I'd rather just find a nice script someone else has done and the heck with the headache.
  20. Targeting is fine and working as intended. It scans all targets in the area, selects the closest, and chases that target and shoots it, then picks another target and away it goes. The main issue is keeping the physical linkset upright and not going sideways or wonky movements.
  21. I am continuing to try and build this zombie project. I am at a stage where I have the zombie tracking other zombies, and shooting at them. But I have a few problems, in that it isn't tracking zombies all that well. Sometimes it does, and other times it just falls over. I felt that the Sensor() event wasn't updating the zombie with the correct information at times as well, but yeah the problem of keeping Mr Zombie rotated correctly is my biggest problem. I have included the script for anyone to have a looksee (please excuse my coding - I have returned to SL after quite a few years). key kTarget; float fRange = 96.0; float fRate = 1.0; float fForce = 10.0; vector vKick_up = <0,0,0.25>; float fForward_kick; vector vHome; float DELAY = 3.0; integer armed = TRUE; Fire() { if (armed) { llMessageLinked(LINK_SET, 1, "Shoot", ""); armed = FALSE; llSetTimerEvent(DELAY); } } default { state_entry() { armed = TRUE; llSensorRepeat( "Zombie", "", ACTIVE | SCRIPTED, fRange, PI, fRate ); vHome = <49.32539, 129.264145, 21.5>; llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y,FALSE); llSetStatus(STATUS_ROTATE_Z, TRUE); llSetStatus(STATUS_PHYSICS,FALSE); llLookAt(llGetPos()+<1.0,0.0,0.0>,0.2,0.2); //Try and Set Zombie upright llStopLookAt(); } timer() { llSetTimerEvent(0.0); armed = TRUE; } sensor( integer number_detected ) { kTarget = llDetectedKey(0);//Lock onto closest Zombie llSensorRepeat( "", kTarget, ACTIVE | SCRIPTED, fRange, PI, fRate ); integer i; for( i = 0; i < number_detected; i++ ) { string Sname = llDetectedName( i ); vector vPos = llDetectedPos(i); vector vMyPos = llGetPos(); float fDistance = llVecDist(vPos, vMyPos); //llRotLookAt( llRotBetween( <1.0,0.0,1.0>, llVecNorm( vPos - llGetPos() ) ), 1.0, 0.4 ); llLookAt(vPos,1.0,1.0); llSetText(Sname+" is at "+(string)llRound(fDistance)+" Metres \n ",<1,1,1>,1.0); if (fDistance >10.0) { llSetStatus(STATUS_PHYSICS,TRUE); if (llOverMyLand(llGetKey()) == FALSE) { llMoveToTarget(vHome,0.4); } llLookAt(vPos,1.0,1.0); float fTime = fDistance/2; vPos.z = llGround( ZERO_VECTOR );//Try and keep Zombie level with Ground llMoveToTarget(vPos,fTime);//Move Zombie at a slow pace, according to distance/time } if (fDistance<=10.0) { llStopMoveToTarget(); list a = llGetObjectDetails(kTarget,([OBJECT_POS]));//Update Target Position vector vTempPos = llList2Vector(a,0); vMyPos = llGetPos(); llLookAt(vTempPos,1.0,1.0); Fire(); if (llOverMyLand(llGetKey()) == FALSE) { llMoveToTarget(vHome,0.4); } } } } no_sensor() { llSetText("No Zombies Detected",<1,1,1>,1.0); llSetStatus(STATUS_PHYSICS,FALSE); //llLookAt(llGetPos()+<1.0,0.0,0.0>,0.2,0.2); llStopLookAt(); if (llOverMyLand(llGetKey()) == FALSE) { llMoveToTarget(vHome,0.4); } llSensorRepeat( "Zombie", "", ACTIVE | SCRIPTED, fRange, PI, fRate ); } }
  22. Thanks for your help. I shouldn't code late at night. How easy it is to make a silly mistake. But I have learnt from this as well :)) I have attached the corrected and working code for this project. key kTarget; float fRange = 96.0; float fRate = 1.0; float fForce = 25.0; vector vKick_up = <0,0,0.75>; float fForward_kick = 2.5; vector vHome; default { state_entry() { llSensorRepeat( "Zombie", "", ACTIVE | SCRIPTED, fRange, PI, fRate ); vHome = <49.32539, 129.264145, 21.5>; llSetStatus(STATUS_PHYSICS,TRUE); } sensor( integer number_detected ) { kTarget = llDetectedKey(0); llSensorRepeat( "", kTarget, ACTIVE | SCRIPTED, fRange, PI, fRate ); integer i; for( i = 0; i < number_detected; i++ ) { string Sname = llDetectedName( i ); vector vPos = llDetectedPos(i); vector vMyPos = llGetPos(); float fPosition = llVecDist(vPos, vMyPos); llLookAt(vPos,1.0,1.0); llSetText(Sname+" is at "+(string)llRound(fPosition)+" Metres \n ",<1,1,1>,1.0); if (fPosition >5.0) { if (llOverMyLand(llGetKey()) == FALSE) { llMoveToTarget(vHome,0.4); } llApplyImpulse((vKick_up + <0,0,llFrand(1)>) * llGetMass(), FALSE); llApplyImpulse(-llVecNorm(llGetPos() - llDetectedPos(i)) * fForward_kick * llGetMass(), FALSE); } if (fPosition<=5.0) { vector vDirection = llVecNorm(vPos-vMyPos); vector vImpulse = fForce * vDirection; vImpulse *= llGetObjectMass(kTarget); vImpulse *= llPow(llVecDist(vMyPos, vPos), 3.0); vImpulse -= llDetectedVel(0); if (llOverMyLand(llGetKey()) == FALSE) { llMoveToTarget(vHome,0.4); } llPushObject(kTarget, vImpulse, ZERO_VECTOR, FALSE); } } } no_sensor() { llSetText("No Zombies Detected",<1,1,1>,1.0); if (llOverMyLand(llGetKey()) == FALSE) { llMoveToTarget(vHome,0.4); } llSensorRepeat( "Zombie", "", ACTIVE | SCRIPTED, fRange, PI, fRate ); } } Happy trails all
  23. I will try Innula's solution in the morning as it is getting late here. Rolig, I tried your solution, but the octopus went all over the sim attacking every prim with a script in it..LOL.. It was hard to keep track of. I will include the simple script I am working with, that I changed to include your method. Thanks for the replies so far : key kTarget; float fRange = 96.0; float fRate = 1.0; float fForce = 500.0; vector vKick_up = <0,0,0.5>; float fForward_kick = 2.0; default { state_entry() { llSensorRepeat( "Zombie", "", ACTIVE | SCRIPTED, fRange, PI, fRate ); } sensor( integer number_detected ) { kTarget = llDetectedKey(0); llSensorRepeat( "", "kTarget", ACTIVE | SCRIPTED, fRange, PI, fRate ); integer i; for( i = 0; i < number_detected; i++ ) { //key target = llDetectedKey(i); string Sname = llDetectedName( i ); vector vPos = llDetectedPos(i); vector vMyPos = llGetPos(); float fPosition = llVecDist(vPos, vMyPos); llLookAt(vPos,1.0,1.0); llSetText(Sname+" is at "+(string)llRound(fPosition)+" Metres \n ",<1,1,1>,1.0); if (fPosition >9.5) { llSetStatus(STATUS_PHYSICS,TRUE); llApplyImpulse((vKick_up + <0,0,llFrand(1)>) * llGetMass(), FALSE); llApplyImpulse(-llVecNorm(llGetPos() - llDetectedPos(i)) * fForward_kick * llGetMass(), FALSE); } if (fPosition <5.5) { if (fPosition<5.0) { vector vDirection = llVecNorm(vPos-vMyPos); vector vImpulse = fForce * vDirection; vImpulse *= llGetObjectMass(kTarget); vImpulse *= llPow(llVecDist(vMyPos, vPos), 3.0); vImpulse -= llDetectedVel(0); llPushObject(kTarget, vImpulse, ZERO_VECTOR, FALSE); } } } } no_sensor() { llSetText("No Zombies Detected",<1,1,1>,1.0); } }
  24. I am using an octopus to chase zombies on my sim. But the poor thing gets so confused when there is more than one zombie. I'd ideally like it to chase only the nearest zombie, and not flit about changing it's mind all the time. It is funny to watch, but not very functional. Any help would be appreciated.
  25. Thanks for all the suggestions. I have learned a few things again.. mmm or relearned them. Here is the code I worked out from your suggestions. It works and gives me the final degree that the thing stops at so I can do other calculations. Posting the code so that someone else may find it useful (please excuse my sloppy coding). integer WHEEL = 4;float Rotate;default{ state_entry() { Rotate = llFrand(360.0) * DEG_TO_RAD; } link_message(integer sender_num, integer num, string str, key id) { if (str == "Spin") { llSetTimerEvent(0.1); } if (str == "BigwheelStop") { llSetTimerEvent(0.0); float final = Rotate * RAD_TO_DEG; llSay(0,(string)llFloor(final)); } } timer() { Rotate = llFrand(360.0) * DEG_TO_RAD; //llSetTextureAnim(ANIM_ON|LOOP|SMOOTH|ROTATE, ALL_SIDES, 1, 1, 0, 0, 0.0); llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_GLOW, ALL_SIDES, 0.1,PRIM_TEXTURE,ALL_SIDES,"roulette_image copy",<1,1,0>,<0,0,0>,Rotate]); }} I will later use llMessageLinked to send the calculated stop position to the main program later on, after a bit of fliddling around. Cheers. Um and oops, yes I have a few things in that code to remove and clean up..LOL
×
×
  • Create New...