Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Anyone got an idea for a variable offset/distance from an avatar?

Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-10-2006 15:18
If you remember, I'm trying to get a 'monster' coded in game.

Right now I'm looking for a solution to this problem:
I have a sensed avatar. I know his/her position vector, and I know mine. I know the distance between the two. I know how far away I want to be from the avatar before I execute a fire() script. The problem arises here.

I need a way to make the 'monster' move to a point 12-15 meters away from the avatar, but not to a defined point in RELATION to the avatar, but in relation to the avatar and the monster itself. I.e., I don't want the monster walking past the avatar to get to 12m behind it and fire, I don't want it trying to go through the av to get to its position, I want it to go until it's 12-15m away from the avatar, in a beeline to it.

Just imagine a 12m circle around an avatar. Now place a point outside that circle, and draw a line between that point and the avatar. The place where it intersects the circle is where I want the 'monster' to move to.

Any ideas on how to script this?
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
08-10-2006 16:11
From: Eaglebird Cameron
Any ideas on how to script this?

Well, you know the vector between the monster and the avatar, and you know its length. So what you need is to take this vector, scale it down (by multiplying by a float number) so its length is (distance to avatar - 15 m) instead of current (distance to avatar) ... then you add this newly scaled vector to position of your monster. the result is location where your monster should head to, to wind up in the spot you describe.

something like:
CODE

vector offset = av_position - monster_position;
float distance = llVecMag( offset );
float scale = (distance - 15.0) / distance;
vector destination = monster_position + (offset * scale);

note if your distance to target is less than desired 15 m then you'll need to do opposite, i.e. scale up vector between monster and AV so it places you at desired distance. It it's necessary for monster to be so far before it attacks, of course o.O;
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-10-2006 16:21
From: Joannah Cramer
Well, you know the vector between the monster and the avatar, and you know its length. So what you need is to take this vector, scale it down (by multiplying by a float number) so its length is (distance to avatar - 15 m) instead of current (distance to avatar) ... then you add this newly scaled vector to position of your monster. the result is location where your monster should head to, to wind up in the spot you describe.

something like:
CODE

vector offset = av_position - monster_position;
float distance = llVecMag( offset );
float scale = (distance - 15.0) / distance;
vector destination = monster_position + (offset * scale);

note if your distance to target is less than desired 15 m then you'll need to do opposite, i.e. scale up vector between monster and AV so it places you at desired distance. It it's necessary for monster to be so far before it attacks, of course o.O;


Well, this is kinda why I wish SL used a coordinate system that wasn't based on vectors, so we could specify the dfference between coordinates and vectors, etc.
Now I'm confused because of the vector coordinates and vecotr magnitudes and normals and ffffffffff
Angela Salome
Registered User
Join date: 6 Oct 2005
Posts: 224
08-10-2006 16:58
From: Eaglebird Cameron
Well, this is kinda why I wish SL used a coordinate system that wasn't based on vectors, so we could specify the dfference between coordinates and vectors, etc.
Now I'm confused because of the vector coordinates and vecotr magnitudes and normals and ffffffffff


Ah, but a coordinate, is a vector.

When you're in the middle of a sim at 128, 128, 20, that's the vector 128 m East, 128m North, and 20m Up, with respect to the origin at 0, 0, 0, in southwest, bottom corner of the sim.
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
08-10-2006 17:05
From: Eaglebird Cameron
Now I'm confused because of the vector coordinates and vecotr magnitudes and normals and ffffffffff

Err. think of vector as of a line extending from one point (monster) to another point (AV)

vector magnitude is length of this line, like measured with a ruler.

when you multiply this vector by a number, you make this 'line' still extend in the same direction but you make it either longer or shorter, depending on what value you use to multiply. Just like multiplying regular number by more than 1 makes it larger, and multiplying by less than 1 makes it smaller.

I can't explain it better than that, sorry :/ but if you can imagine it (or plain draw on piece of paper) then it's really not that complicated...
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-10-2006 19:03
From: Joannah Cramer
Err. think of vector as of a line extending from one point (monster) to another point (AV)

vector magnitude is length of this line, like measured with a ruler.

when you multiply this vector by a number, you make this 'line' still extend in the same direction but you make it either longer or shorter, depending on what value you use to multiply. Just like multiplying regular number by more than 1 makes it larger, and multiplying by less than 1 makes it smaller.

I can't explain it better than that, sorry :/ but if you can imagine it (or plain draw on piece of paper) then it's really not that complicated...

I know vectors, Lord, I should after that horrible year of precal.
The reason it confuses me is because you think of the coordinate, still a vector, then it is drawn from 000 to xyz, with that magnitude. When you add in another vector to the mix, well, sometimes it gets confusing, is it a new coordinate, is it a vector..?
You know? :(
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-10-2006 19:11
From: Eaglebird Cameron
I know vectors, Lord, I should after that horrible year of precal.
The reason it confuses me is because you think of the coordinate, still a vector, then it is drawn from 000 to xyz, with that magnitude. When you add in another vector to the mix, well, sometimes it gets confusing, is it a new coordinate, is it a vector..?
You know? :(

Ah! You bring up a good point (pun intended)! Points and vectors are actually quite distinct mathematically. A point represents a location while a vector represents a direction and magnitude. However, most (but not all actually!) computer applications simply use one construct for both, with the understanding that a point is represented by the vector difference between its location and the origin.
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-10-2006 19:24
From: Hewee Zetkin
Ah! You bring up a good point (pun intended)! Points and vectors are actually quite distinct mathematically. A point represents a location while a vector represents a direction and magnitude. However, most (but not all actually!) computer applications simply use one construct for both, with the understanding that a point is represented by the vector difference between its location and the origin.


Still, the component form used for both points and vectors confuses me. Besides, doesn't llMoveToTarget use vectors as points, not distances and magnitudes? :P
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-10-2006 20:26
Good news everyone, the script works except for a few flaws.
CODE

vector avpos;
vector currentpos;
float dist;
vector offset;
vector attackpos;
vector destination;
float scale;
//monster's height is 1.77301
vector lookat;
fire()
{
llSay(0,"I shotted u in teh face");
}
default
{
state_entry()
{
vector pos = llGetPos();
llSetStatus(STATUS_ROTATE_Z, TRUE);
llSleep(0.1);
llMoveToTarget(pos,0.1);
key id = llGetOwner();
llSensorRepeat("","",AGENT,50,PI,.4);
}
sensor(integer total_number)
{
avpos = llDetectedPos(0);
currentpos = llGetPos();
offset = avpos - currentpos;
dist = llVecMag(offset);
if(dist > 14)
{
scale = (dist - 15.0) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
lookat = <avpos.x,avpos.y,1.77301>;
llLookAt(lookat, 1.0, 1.0);
}
else if(dist < 8)
{
scale = (dist - 9.0) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
lookat = <avpos.x,avpos.y,1.77301>;
llLookAt(lookat, 1.0, 1.0);
}
else
{
lookat = <avpos.x,avpos.y,1.77301>;
llLookAt(lookat, 1.0, 1.0);
fire();
}
}
}


Is what I have so far.
The flaws right now are:
The monster llLookAt's weird, it should point it's x axis at the target, but instead just looks weird, definitely not facing forward.
The second is that I'd like it to stay on the ground, i.e., if the avatar flies, it can't follow. That, I suppose, could be fixed with some multiplying by 0 on the vector.z.
Third, that if, else if, else, script seems to work, it puts the monster at a good distance like it should, but for some reason the else isn't getting triggered when it's in this distance.
if further away than 14m, go within 15m.
elseif closer than 8, move away until further than 8m.
else (else you gotta be in the right range) fire();
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
08-10-2006 21:35
From: Eaglebird Cameron
The flaws right now are:
The monster llLookAt's weird, it should point it's x axis at the target, but instead just looks weird, definitely not facing forward.
The second is that I'd like it to stay on the ground, i.e., if the avatar flies, it can't follow. That, I suppose, could be fixed with some multiplying by 0 on the vector.z.
Third, that if, else if, else, script seems to work, it puts the monster at a good distance like it should, but for some reason the else isn't getting triggered when it's in this distance.
if further away than 14m, go within 15m.
elseif closer than 8, move away until further than 8m.
else (else you gotta be in the right range) fire();

llLookAt() makes Z-axis face the target. To have X-axis face it instead, you'll need llRotLookAt() instead, along with your vector converted into rotation.

also check out the page at http://secondlife.com/badgeo/wakka.php?wakka=llLookAt for code snippet that might help.

to stay on ground, llGround() call may be of use (to find out what height the monster should be at, and such)

third issue i have no idea, although it's possible your monster is sent on its merry way by one of earlier if() options and then never kind of gets within right distance to actually shoot. hard to tell o.O;
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-10-2006 23:25
From: Joannah Cramer
llLookAt() makes Z-axis face the target. To have X-axis face it instead, you'll need llRotLookAt() instead, along with your vector converted into rotation.

also check out the page at http://secondlife.com/badgeo/wakka.php?wakka=llLookAt for code snippet that might help.

to stay on ground, llGround() call may be of use (to find out what height the monster should be at, and such)

third issue i have no idea, although it's possible your monster is sent on its merry way by one of earlier if() options and then never kind of gets within right distance to actually shoot. hard to tell o.O;


I may use a while statement to try and figure it out, see if it's stopping after the else if and going back to state entry or whatnot

I also still have to make it roam for no_sensor
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-11-2006 12:11
This is what I have after a few edits, no ground checking yet..
CODE

vector avpos;
vector currentpos;
float dist;
vector offset;
vector attackpos;
vector destination;
float scale;
//monster's height is 1.77301
vector lookat;
vector AXIS_FWD = <1,0,0>;
rotation FWDAXIS(vector axis, vector target)
{
return (llGetRot() * llRotBetween(axis * llGetRot(), target - llGetPos()));
}
fire()
{
llSay(0,"I shotted u in teh face");
}
default
{
on_rez(integer startParam)
{
llResetScript();
llPlaySound("dd60502e-1baa-aa9b-0d35-2b30a110dcfa", 2.0);
}
state_entry()
{
vector pos = llGetPos();
llSetStatus(STATUS_ROTATE_Z, TRUE);
llSleep(0.1);
llMoveToTarget(pos,0.1);
key id = llGetOwner();
llSensorRepeat("","",AGENT,50,PI,.4);
}
sensor(integer total_number)
{
avpos = llDetectedPos(0);
currentpos = llGetPos();
offset = avpos - currentpos;
dist = llVecMag(offset);
if(dist > 14)
{
scale = (dist - 15.0) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
llRotLookAt(FWDAXIS(AXIS_FWD, <avpos.x,avpos.y,1.77301>), 1, 1);
}
else if(dist < 8)
{
scale = (dist - 9.0) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
llRotLookAt(FWDAXIS(AXIS_FWD, <avpos.x,avpos.y,1.77301>), 1, 1);
}
else if (8 < dist < 14)
{
llRotLookAt(FWDAXIS(AXIS_FWD, <avpos.x,avpos.y,1.77301>), 0.8, 0.8);
fire();
}
}
}

the problem is now that it still lookats weird. The forward axis is x, and I've set that, but it doesn't seem to want to cooperate.
Is there any way I could disable pitch and roll altogether?
Grazel Cosmo
Registered User
Join date: 12 Mar 2005
Posts: 28
08-11-2006 12:53
I've not worked with lookat functions so can't tell you how to do it but you should be able to. The reason it is probably seeming weird is I suspect the lookat fucntions in the way particles hit their target: they aim for the center of the target (so on an AV that's the crotch). If the target AV is higher or lower than the monster it will tilt up or down to try to match and may also be tilting some as well along the Y axis to try to line up.

Forewarning: make sure when you do put in the ground checks that the monster will break off trying to reach a target if its more than 15m in the air above it so therefore alway sout of reach (maybe even ignoring the target if its 15m above the ground to begin with).

Also keep in mind that whenever the sensor goes off it can potentially pick up a new 0 since 0 will be the AV closest to the monster at hte time the sensor goes off and since SetPos is limites to 10m 'bursts' if you want the monster to 'lock' on a target you should save the key of the target to have it always go after that key unless its not in sensor range anymore (or doesn't turn up in hte results if there's more than 16 AVs within sensor range).
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-11-2006 13:35
Well, you can try:
CODE
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y, FALSE);

but probably you are also/instead going to have to calculate the rotation carefully. Here's a way to do that:
CODE
rotation currRot = llGetRot();
vector localX = llRot2Fwd(currRot);
vector localY = llRot2Left(currRot);
vector localZ = llRot2Up(currRot);

vector dir = llVecNorm(targetPos - llGetPos());

//Project direction onto local x-y plane and determine angle about local z
float theta = llAtan2(dir * localY, dir * localX);

rotation desiredRelativeRot = llAxisAngle2Rot(localZ, theta);

// I'm pretty sure I have the order of the multiplication correct, but if things look wierd try switching the order
llRotLookAt(currRot * desiredRelativeRot, STRENGTH, DAMPING);
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-11-2006 14:23
From: Hewee Zetkin
Well, you can try:
CODE
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y, FALSE);


Doesn't get the result I'm looking for. It seems to not rotate at all anymore after that, but before that, it rotates itself to some odd rotation before it stops doing anything at all.
From: Hewee

but probably you are also/instead going to have to calculate the rotation carefully. Here's a way to do that:
CODE
rotation currRot = llGetRot();
vector localX = llRot2Fwd(currRot);
vector localY = llRot2Left(currRot);
vector localZ = llRot2Up(currRot);

vector dir = llVecNorm(targetPos - llGetPos());

//Project direction onto local x-y plane and determine angle about local z
float theta = llAtan2(dir * localY, dir * localX);

rotation desiredRelativeRot = llAxisAngle2Rot(localZ, theta);

// I'm pretty sure I have the order of the multiplication correct, but if things look wierd try switching the order
llRotLookAt(currRot * desiredRelativeRot, STRENGTH, DAMPING);


Could you help me out and explain what exactly this is doing, so that I can merge it and test it with my script, instead of copypasting and possibly messing it up altogether? :P
:edit:
Ok, let's see:
I get my current rotation, rotate that forward to get my forward rotations, get the unit vector of the vector between myself and the target, apply arc-tangent? to my rotation and into the float theta, then calculate my rotation for llRotLookAt by multiplying my desiredrot by my current rotation.
:edit2:
also multiplication is communicative, so I don't think you could've screwed it up :P
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
08-11-2006 14:58
From: Eaglebird Cameron
This is what I have after a few edits, no ground checking yet..
CODE

//monster's height is 1.77301
llRotLookAt(FWDAXIS(AXIS_FWD, <avpos.x,avpos.y,1.77301>), 1, 1);

just something to consider, you are making your monster thing look at point which is 1.77 m above 'bottom' of the sim. With the ground level in sims being ~20 m or more, this means your monster will be staring at some point buried deep into ground, which can make it look really weird.

you might want to try replace that value with z component of your monster's position (currentpos.z) or something similar... just a thought o.O;
From: someone
also multiplication is communicative, so I don't think you could've screwed it up :P

Unfortunately that's not case with quaternions. a * b gives you very different results than b * a when it comes to them ^^;
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-11-2006 15:13
From: Eaglebird Cameron
Doesn't get the result I'm looking for. It seems to not rotate at all anymore after that, but before that, it rotates itself to some odd rotation before it stops doing anything at all.

Hmm. Okay. I haven't really messed with those flags myself. It was just a guess.
From: someone
Could you help me out and explain what exactly this is doing, so that I can merge it and test it with my script, instead of copypasting and possibly messing it up altogether? :P

Sure. The localX, localY, and localZ vectors are set to indicate the basis of the object's coordinate frame in terms of the global basis vectors. Think of it like this: if you are on the outside looking at the object , its x (red) axis would point in the direction indicated by localX, and similarly for the y (green) and z (blue) axes.

Once this local reference frame is determined, what you want is the direction in ONLY the local x-y plane. The next step thus projects (finds the components of) the direction vector onto the localX and localY unit vectors (if you switch over for a moment to thinking about the object's point of view, it is like drawing a, "vertical," line from a point to the, "horizontal," plane).

What you want to do is rotate the local x-axis to look at this projected point. You are rotating about the local, "vertical" (the localZ axis) by an angle that is between the local, "forward" (the localX axis) and the direction vector mapped onto the horizontal plane.

Actually (if the object is physical, wihch it seems to be) you might want to store the (original/)last set orientation in a global variable and use it instead of setting 'currRot' to the value returned by 'llGetRot()'. That way collisions won't have the possibility of totally screwing up your, "vertical."
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-11-2006 16:35
From: Hewee Zetkin
Hmm. Okay. I haven't really messed with those flags myself. It was just a guess.

Sure. The localX, localY, and localZ vectors are set to indicate the basis of the object's coordinate frame in terms of the global basis vectors. Think of it like this: if you are on the outside looking at the object , its x (red) axis would point in the direction indicated by localX, and similarly for the y (green) and z (blue) axes.

Once this local reference frame is determined, what you want is the direction in ONLY the local x-y plane. The next step thus projects (finds the components of) the direction vector onto the localX and localY unit vectors (if you switch over for a moment to thinking about the object's point of view, it is like drawing a, "vertical," line from a point to the, "horizontal," plane).

What you want to do is rotate the local x-axis to look at this projected point. You are rotating about the local, "vertical" (the localZ axis) by an angle that is between the local, "forward" (the localX axis) and the direction vector mapped onto the horizontal plane.

Actually (if the object is physical, wihch it seems to be) you might want to store the (original/)last set orientation in a global variable and use it instead of setting 'currRot' to the value returned by 'llGetRot()'. That way collisions won't have the possibility of totally screwing up your, "vertical."


Ah, well, that makes sense.
Can I snip the code up and have something in my global, and set only stuff that changes per position in my if else statements, or should I leave everything intact like it is now (I'd post the script now but the sim I was in is lagged out and the login server won't shake.)
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-12-2006 00:35
This is the code I have now

:edit:..
or maybe not. That was the still old one. I forgot I moved the script into a simple object to test it out.
brb with script
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-12-2006 12:33
CODE

vector avpos;
vector currentpos;
float dist;
vector offset;
vector attackpos;
vector destination;
float scale;
//monster's height is 1.77301
vector lookat;
vector AXIS_FWD = <1,0,0>;
rotation FWDAXIS(vector axis, vector target)
{
return (llGetRot() * llRotBetween(axis * llGetRot(), target - llGetPos()));
}
fire()
{
llSay(0,"I shotted u in teh face");
}
default
{
on_rez(integer startParam)
{
llResetScript();
llPlaySound("dd60502e-1baa-aa9b-0d35-2b30a110dcfa", 2.0);
}
state_entry()
{
llSetStatus(STATUS_ROTATE_Z, TRUE);
llSetHoverHeight(1.77301, FALSE, .1);
key id = llGetOwner();
llSensorRepeat("","",AGENT,50,PI,.5);
}
sensor(integer total_number)
{
avpos = llDetectedPos(0);
currentpos = llGetPos();
offset = avpos - currentpos;
dist = llVecMag(offset);
if(dist > 14)
{
scale = (dist - 15.5) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
rotation currRot = llGetRot();
vector localX = llRot2Fwd(currRot);
vector localY = llRot2Left(currRot);
vector localZ = llRot2Up(currRot);
vector dir = llVecNorm(offset);
//Project direction onto local x-y plane and determine angle about local z
float theta = llAtan2(dir * localY, dir * localX);
rotation desiredRelativeRot = llAxisAngle2Rot(localZ, theta);
// I'm pretty sure I have the order of the multiplication correct, but if things look wierd try switching the order
llRotLookAt((currRot * desiredRelativeRot), 5, .1);
}
else if(dist < 12)
{
scale = (dist - 13.5) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
rotation currRot = llGetRot();
vector localX = llRot2Fwd(currRot);
vector localY = llRot2Left(currRot);
vector localZ = llRot2Up(currRot);
vector dir = llVecNorm(offset);
float theta = llAtan2(dir * localY, dir * localX);
rotation desiredRelativeRot = llAxisAngle2Rot(localZ, theta);
llRotLookAt((currRot * desiredRelativeRot), 5, .1);
}
else if(10 < dist < 15)
{
rotation currRot = llGetRot();
vector localX = llRot2Fwd(currRot);
vector localY = llRot2Left(currRot);
vector localZ = llRot2Up(currRot);
vector dir = llVecNorm(offset);
float theta = llAtan2(dir * localY, dir * localX);
rotation desiredRelativeRot = llAxisAngle2Rot(localZ, theta);
llRotLookAt((currRot * desiredRelativeRot), 5, .1);
fire();
}
}
no_sensor()
{
//roam
}
}
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-13-2006 00:13
Looks about right. I'd make the following changes:

1.) Refactor the code common to all the if-else clauses to a point before the whole if-else construct. Otherwise you are begging for defects (if not now, then as soon as you have to change something). It will make it a lot more readable also.

2.) Like I said, I think collisions have the potential to screw your, "up," axis up. Heh. So instead of doing a
currRot = llGetRot();

each time you want to adjust your facing, you might consider making it a global variable and doing it once in the 'state_entry' and/or 'on_rez' event handlers. If you do this you might also refactor to change the name to 'originalRot' or something, as it better reflects the actual use (though you could also set the variable to the new desired rotation each time; no real need though as all it REALLY does is keep a snapshot of the z-direction). Gah! Sorry if I'm rambling!
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-13-2006 00:18
From: Hewee Zetkin
Looks about right. I'd make the following changes:

1.) Refactor the code common to all the if-else clauses to a point before the whole if-else construct. Otherwise you are begging for defects (if not now, then as soon as you have to change something). It will make it a lot more readable also.







2.) Like I said, I think collisions have the potential to screw your, "up," axis up. Heh. So instead of doing a
currRot = llGetRot();
each time you want to adjust your facing, you might consider making it a global variable and doing it once in the 'state_entry' and/or 'on_rez' event handlers. If you do this you might also refactor to change the name to 'originalRot' or something, as it better reflects the actual use (though you could also set the variable to the new desired rotation each time; no real need though as all it REALLY does is keep a snapshot of the z-direction). Gah! Sorry if I'm rambling!




I figured that since, depending on distance and etc., each should have its own set of instructions and statements. That way I don't get a rotation from < 15m when I need to be >4m.

I suppose since llRotLookAt is always looking at the closest av, I could consolidate and move it all into the sensor event, out of the ifelse statements.

CODE

vector avpos;
vector currentpos;
float dist;
vector offset;
vector attackpos;
vector destination;
float scale;
//monster's height is 1.77301
vector lookat;
vector AXIS_FWD = <1,0,0>;
rotation FWDAXIS(vector axis, vector target)
{
return (llGetRot() * llRotBetween(axis * llGetRot(), target - llGetPos()));
}
fire()
{
llSay(0,"I shotted u in teh face");
}
default
{
on_rez(integer startParam)
{
llResetScript();
llPlaySound("dd60502e-1baa-aa9b-0d35-2b30a110dcfa", 2.0);
}
state_entry()
{
llSetStatus(STATUS_ROTATE_Z, TRUE);
llSetHoverHeight(1.77301, FALSE, .1);
key id = llGetOwner();
llSensorRepeat("","",AGENT,30,PI,.5);
}
sensor(integer total_number)
{
avpos = llDetectedPos(0);
currentpos = llGetPos();
offset = avpos - currentpos;
dist = llVecMag(offset);
rotation currRot = llGetRot();
vector localX = llRot2Fwd(currRot);
vector localY = llRot2Left(currRot);
vector localZ = llRot2Up(currRot);
vector dir = llVecNorm(offset);
//Project direction onto local x-y plane and determine angle about local z
float theta = llAtan2(dir * localY, dir * localX);
rotation desiredRelativeRot = llAxisAngle2Rot(localZ, theta);
// I'm pretty sure I have the order of the multiplication correct, but if things look wierd try switching the order
llRotLookAt((currRot * desiredRelativeRot), 5, .1);
if(dist > 14)
{
scale = (dist - 15.5) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
}
else if(dist < 12)
{
scale = (dist - 13.5) / dist;
attackpos = currentpos + (offset * scale);
llMoveToTarget(attackpos, 1);
}
else if(10 < dist < 15)
{
fire();
}
}
no_sensor()
{
//roam
}
}
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-13-2006 00:28
The logic looks pretty good to me. Test it out a bit and post your results. Let's see how good it is in practice. :)
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-13-2006 00:44
From: Hewee Zetkin
The logic looks pretty good to me. Test it out a bit and post your results. Let's see how good it is in practice. :)

before the change it seemed alright. Still won't stay on the ground though.

I've also found a problem with llMovetoTarget.
The float tau, seconds.
It means 1 = 1 second all the time. If I'm all the way across the sim, I can cross it in 1 second. If I've got .01m to move, it takes me one second to move there.

I'm guessing a time distance formula used to calculate how long it should take the object to move x distance would be needed, but I don't know exactly how to implement it.
Eaglebird Cameron
YTMND *********
Join date: 1 Jul 2006
Posts: 68
08-13-2006 02:01
It verks!
The only things to do now are
1) Keep it on the ground
2) make it follow terrain along with keeping on the ground.
3) set an equation for the distance and time required to go that distance
4) get a current rotation on rez so that it can reference the 0x and 0y rotations incase they get skewed by bumping or anything
5) make it actually fire (simple popgun script)
6) animate it to look right, if at all possible.

in order of importance.
4 is last because it has four legs that probably won't animate right.
Unless maybe I use hidden legs. But crap, you still need to have them linked seperately to hide and show them, don't you?
1 2