Need a bit of math help

Post » Sat Aug 28, 2010 8:59 am

Hello everybody. I am making some modifications to the placement of a firing marker in my mod. This marker appears at a random x and a random y coordinate above the target marker. I have this working. However, the problem I am running into is making the fire marker face the target marker in order to fire at it. I can figure out the angle positioning on my own, however getting the object to turn to face the object is a different story. Here is an example with sample fire marker locations:

Key: T - Target, F - Fire marker, any arrow is facing direction

Standard:
F>
F> T F>
F>

Needed:

FV
F> T F<
F^

I'm sure there is a math formula to calculate the fire marker's position relative to the target and adjust its facing angle (which would be X I assume) accordingly, but this is out my range of expertise. I hope someone with higher math skills can assist me with this. Credit will, of course, be given to those who help and I will walk away with a bit more knowledge than I had. Thank you.
User avatar
Brad Johnson
 
Posts: 3361
Joined: Thu May 24, 2007 7:19 pm

Post » Sat Aug 28, 2010 9:22 am

This function may do the math for you. http://geck.gamesas.com/index.php/GetHeadingAngle
User avatar
Tessa Mullins
 
Posts: 3354
Joined: Mon Oct 22, 2007 5:17 am

Post » Sat Aug 28, 2010 8:33 am

Well that was MUCH simpler than I thought it would have been. I figured it'd be a complex code to figure it out, not a simple function. Thanks for pointing this out to me.
User avatar
Craig Martin
 
Posts: 3395
Joined: Wed Jun 06, 2007 4:25 pm

Post » Sat Aug 28, 2010 12:14 pm

Well I like to think I am good at math so let me give this a go. Also, if this is wrong, sorry. I got halfway through and realized it might be, but I am posting just for the benefit of it. Figured it could not hurt. The one issue is this involves using Sine, Cosine, and Tangent. I am not sure if you can use these in scripting, I have never tried anything like this, but I assume you could? Cipscis could probably answer that, he is the scripting god around here. But I will go for it assuming that you can.

You may remember (depending on how old you are, or far you went in math in highschool/college) learning about SOH CAH TOA. We will use this. Simply finding two sides of a right triangle, then figuring out the angle needed. We find out the distance the T is from F on the Y and X axis, then plug it in. I will do a partial script, then you can fill in the blanks.

scn YourScriptFloat XDistanceFloat YDistanceFloat AngleToFireRef FRefRef TRefBegin GameMode	Set XDistance to FRef.GetPos X - TRef.GetPos X ;Get the distance on the x-axis they are apart	Set YDistance to FRef.GetPos Y - TRef.GetPos Y ;Get the distance on the y-axis they are apart	If XDistance < 0 ;If the distance is negative, make it positive since you cant have negative side of triangle		Set XDistance to (-XDistance)	EndIf	If YDistance < 0 ;Same thing, cant be negative.		Set YDistance to (-YDistance)	EndIf	Set AngleToFire to Tan(XDistance/YDistance)	FRef.SetAngle Z AngleToFireEnd


Now this will give you a basic angle. But I think you would have to do more, this can at least get you started. Since the angle wont be talking about the world angle, (1-360) but rather just in relation to eachother (1-180) so you will have to find out what quadrant (1-4) F is in compared to T in order to set the actual angle it would have to face. Now this can be done with some checks involving whether the XDistance and YDistance are positive or negative. Like such. (Quadrants are the 90 degree sections of the 360 deg circle. Going from 1 to 4, counter clockwise, staring at 3 o'clock.)

This would go somewhere within your script before it sets them positive if they were negative. (So right before the line "If XDistance < 0")

If XDistance < 0 && YDistance < 0 ;Quadrant 3	Set AngleToFire to 180EndIfIf XDistance < 0 && YDistance > 0 ;Quadrant 2	Set AngleToFire to 90EndIfIf XDistance > 0 && YDistance < 0 ;Quadrant 4	Set AngleToFire to 270EndIfIf XDistance > 0 && YDistance > 0 ;Quadrant 1	Set AngleToFire to 0EndIf


Then you would change the last line to add the AngleToFire to this value, essentially compensating for where F is in relation to T. (Be it up down left or right.) Merging that into the script, it ends up looking something like this.

scn YourScriptFloat XDistanceFloat YDistanceFloat AngleToFireRef FRefRef TRefBegin GameMode	Set XDistance to FRef.GetPos X - TRef.GetPos X	Set YDistance to FRef.GetPos Y - TRef.GetPos Y	If XDistance < 0 && YDistance < 0 ;Quadrant 3		Set AngleToFire to 180	EndIf	If XDistance < 0 && YDistance > 0 ;Quadrant 2		Set AngleToFire to 90	EndIf	If XDistance > 0 && YDistance < 0 ;Quadrant 4		Set AngleToFire to 270	EndIf	If XDistance > 0 && YDistance > 0 ;Quadrant 1		Set AngleToFire to 0	EndIf	If XDistance < 0		Set XDistance to (-XDistance)	EndIf	If YDistance < 0		Set YDistance to (-YDistance)	EndIf	Set AngleToFire to (AngleToFire + Tan(XDistance/YDistance))	FRef.SetAngle Z AngleToFireEnd


Now the only thing I am missing is that you have to set FRef and TRef to the target, and firemarkers ref before doing this. Otherwise it obviously wouldnt know what the hell your talking about. Forgive if I am wrong, but I think that would just about do it. I tend to make stupid mistakes in math, so I could have messed something up there, someone else should check it. But you can always try it out and if it does not work we can go from there. Also, again this is assuming we can use Tangent. If we cant I havent a clue how we would do it.

Gunmaster95
User avatar
Lewis Morel
 
Posts: 3431
Joined: Thu Aug 16, 2007 7:40 pm

Post » Sat Aug 28, 2010 5:49 pm

This function may do the math for you. http://geck.gamesas.com/index.php/GetHeadingAngle

:facepalm: I hate it when I cant see that people have reponded whilst I am furiously typing away. :P I guess that function does it for you. Oh well, the practice was good for me. :D
User avatar
TOYA toys
 
Posts: 3455
Joined: Sat Jan 13, 2007 4:22 am

Post » Sat Aug 28, 2010 2:24 pm

:facepalm: I hate it when I cant see that people have reponded whilst I am furiously typing away. :P I guess that function does it for you. Oh well, the practice was good for me. :D


One never knows when someone will wander on in and find a use for what one posts in here eh ..... !

This bit of math seems close to what I need for my hummer mod, in order to detect where the player is standing relative to the hummer's body angle when he activates the hummer. Getheadingangle refuses to work as I need it to, always returning a value of zero (works when I test against player to hummer, but not hummer to player).

It is not working exactly as I need it to, but I'm going to keep messing with it and see what comes.
User avatar
Crystal Clear
 
Posts: 3552
Joined: Wed Aug 09, 2006 4:42 am

Post » Sat Aug 28, 2010 4:01 pm

I could use just a LITTLE help with this, if anyone's willing.

I have this script which Gunmaster95 started making almost working right. What happens is - - your Hummer is sitting in the world, at some angle. You are standing in the world, somewhere around the hummer. When you walk up to the hummer and activate it, the hummer attempts to detect where you are standing in relation to it, and therefore, determine if you've clicked on, say, the trunk, or the hood, or the driver's side, or the passenger's side.

(It is too bad that getheadingangle does not work with this particular object because it would solve it).

The script works almost right, but with this problem. It is forcing a total of 4 quadrants upon everything it does. So what this means is.

If the Hummer is at any of these z-angles, it seems to judge your relative position perfectly:

45
135
225
315


but if the hummer is at any of these z-angles, it is misjudging them by like, an eighth of a turn or something:

0
90
180
270

So it is like, as you stand in the world and rotate the hummer smoothly on its z-axis, it can't update your position relative to it smoothly. It is stuck in these 4 quadrants.

I think I might see why in the script this is happening (but not sure). It might be because of the parts which look like this:

	If XDistance < 0 && YDistance < 0 ;Quadrant 3		Set Position to 180	EndIf	If XDistance < 0 && YDistance > 0 ;Quadrant 2		Set Position to 90	EndIf	If XDistance > 0 && YDistance < 0 ;Quadrant 4		Set Position to 270	EndIf	If XDistance > 0 && YDistance > 0 ;Quadrant 1		Set Position to 0	EndIf


That code does seem to push the deal of 4 absolute quadrants into the thing?

I don't see how to make the script make for the smooth sort of turn I want instead of being stuck in quadrants. Does anyone who's better with math see how? I did try messing with stuff like, the difference between Xdistance and Ydistance and seeing how it could be applied but, if that's even the fix for this, I didn't get it right. (in fact it was a cluster [censored]).

The script section in its entirety is here. It has some odd stuff (such as the number 135). I don't know why the Hummer is in love with the number 135. Anyway:

scn blahFloat XDistanceFloat YDistanceFloat PositionRef FRefRef TReffloat tempfloatfloat HummerAnglefloat correctionbegin onactivateif isactionref player	set TREF to PlayerHummerREF	set HummerAngle to PlayerHummerREF.getangle z	if Hummerangle < 0 ;who knows why it does that		set Hummerangle to Hummerangle + 360	endif	set FREF to PlayerREF	Set XDistance to FRef.GetPos X - TRef.GetPos X	Set YDistance to FRef.GetPos Y - TRef.GetPos Y	If XDistance < 0 && YDistance < 0 ;Quadrant 3		Set Position to 180	EndIf	If XDistance < 0 && YDistance > 0 ;Quadrant 2		Set Position to 90	EndIf	If XDistance > 0 && YDistance < 0 ;Quadrant 4		Set Position to 270	EndIf	If XDistance > 0 && YDistance > 0 ;Quadrant 1		Set Position to 0	EndIf	If XDistance < 0		Set XDistance to (-XDistance)	EndIf	If YDistance < 0		Set YDistance to (-YDistance)	EndIf	set tempfloat to XDistance/YDistance	Set Position to Position + Tan tempfloat; if the hummer is at z-angle 135, none of this needs correction. Donno why 135 is the magic number.	set correction to HummerAngle - 135	set Position to Position + correction	if Position > 360		set Position to Position - 360	endif	if Position < 0			set Position to Position + 360	endif	if (Position >= 315 || position <= 45) ;front of vehicle		set Mode to 2	elseif position > 45 && Position < 135 ;driver's side		set Mode to 0	elseif Position >= 135 && position <= 225 ;rear		set mode to 1	else ; this is > 225 & < 315		showmessage HummerPassengMSG		return	endif;.....etc

User avatar
Chris Johnston
 
Posts: 3392
Joined: Fri Jul 07, 2006 12:40 pm

Post » Sat Aug 28, 2010 11:46 am

The line

Set Position to Position + Tan tempfloat

should be

Set Position to Position + Tan tempfloat 1

since you need the arctangent not the tangent (you're calculating the angle from the ratio, not the ratio from the angle). There's also a chance that the line above it could give a divide by zero error, so it should be wrapped in an

if YDistance != 0

conditional. If YDistance is 0, you've either got 90 or 270 degrees, depending on whether x is positive or negative, respectively.
User avatar
JD bernal
 
Posts: 3450
Joined: Sun Sep 02, 2007 8:10 am

Post » Sat Aug 28, 2010 3:41 pm

I added in the (1) after tempfloat and its not working so well, it is pretty chaotic when you walk around the hummer and click on it this way. Can you tell what other changes would have to be made? I tried removing my 'correction' of 135, it didn't help, so I am not sure where else to change things.
User avatar
Rachel Briere
 
Posts: 3438
Joined: Thu Dec 28, 2006 9:09 am

Post » Sat Aug 28, 2010 4:49 pm

It'd probably be easier for me to write it from scratch than to figure out what you've already got. The major headache is that fallout uses a weird system for measuring angles - clockwise from the y axis rather than counter clockwise from the x. You can get around that though by switching x and y. The main thing I'm unsure of is if the arctan function returns an angle between -90 and 90, or between 0 and 180. If its between 0 and 180, the code below should work.

dx = FRef.getpos y - TRef.getpos ydy = FRef.getpos x - TRef.getpos xif dx == 0    if dy >= 0        set angle to 90    else        set angle to 270    endifelseif dy > 0    set tempFloat to dy / dx    set angle to tan tempFloat 1else    set tempFloat to dy / dx    set angle to tan tempFloat 1    set angle to angle + 180endifif angle < 0    set angle to angle + 360elseif angle >= 360    set angle to angle - 360endifset angle to angle - Hummerangleif angle < 0    set angle to angle + 360endif


An angle of zero would then mean the player is directly in front of the bumper, 90 would be the passenger side, 180 the trunk, 270 the driver's side.

Another thing I'm unsure of though is how the axis are set up for the hummer. Hopefully the z axis points up, and the y axis points towards the front of the truck. That should be something you could check in nifskope. If it's anything else, you'll need to correct the Hummerangle you get via getangle (or adjust your conditionals to take it into account, but that's another headache).
User avatar
Brentleah Jeffs
 
Posts: 3341
Joined: Tue Feb 13, 2007 12:21 am

Post » Sat Aug 28, 2010 12:34 pm

works when I test against player to hummer, but not hummer to player


This really is the same angle though since you know the hummer.getAngle Z and player.getAngle Z angles :P

Taking for granted that the player is always facing the Hummer onActivate, what you need to calculate their relative position is the difference of the

 playerAngle Z - hummerAngle Z


this value makes the solution to your problem well-defined since you can now calculate the angle between two vectors (angle Z is calculated based on the heading, at least for the player. For the Hummer it will probably be its heading as well, but at any rate it will be relative to a constant point in the Hummer. The following calculations are done with the hypothesis that hummer.getAngle Z returns the heading angle of the hummer relative to the world. If by any chance it is different you can measure it and change it accordingly).

- In order for the player to activate the trunk he must be "approximately" collinear to the hummer, meaning the difference is zero +- a tolerance value
- If the player is facing e.g. the right seat they are vertical but with a "minus" sign, so the difference would be -90 +- a tolerance value
- If the player is facing e.g. the left seat they are vertical but with a "plus" sign, so the difference would be 90 +- a tolerance value

and so on.

As long as your "arcs" do not conflict it is pretty well defined.

If for some reason you DO face conflicting arcs, you could also add a dx,dy check and you're good to go :D If you also want to input a psycho condition, you can also check for altitude differences, in case the player is standing on the car when activating :P

The script would be something like this:

dz = player.getAngle Z - hummer.getAngle Zif dz > -15 && dz <= 15 ; 0 +- 15 degrees........... ;open trunkelseif dz > 75 && dz <= 105 ; 90 +-15 degrees..........  ;activate left seatelseif dz >-75 && dz <= -105 ; -90 +- 15 degress..........  ;activate left seatelseif dz >165 && dz <= 195 ; 180 +- 15 degrees..........  ;activate engineelse..........  ;if none of the arcs is valid show a message or something. You could also make the tolerance big enough so that there are no "invalid" arcs,            ;in this case where you have four arcs, the tolerance would have to be +-45 degrees instead of the 15 I put in the example.endif


note that the above only really works if the hummer Z angle is in the 1st quadrant, since it can only be 0-360 (359?)

The way to work around this would be an anagoge of your angles to the first quadrant, like this:

set HA to hummer.getAngle Z set PA to player.getAngle Zif HA > 0 && HA <= 90..... ; do nothing, we're okelseif HA > 90 && HA <= 180     set HAAnagoged to HA - 90     set PAAnagoged to PA - 90elseif HA > 180 && HA <= 270     set HAAnagoged to HA - 180     set PAAnagoged to PA - 180elseif HA > 270 && HA <= 360     set HAAnagoged to HA - 270     set PAAnagoged to PA - 270endif


What is good about this approach is that you don't care what the Player Angle is; even if it's 45 it will e.g. become - 45 which, when put into the

playerAngle Z - hummerAngle Z


equation your relative difference will still be the same :P

I don't have FO3 installed right now to write the script but let me know if I missed something ;)

Edit: Seeing it again, you could probably bypass the anagoge if you insert an absolute value to the 180 degree check e.g:

if abs(dz)> 165 && abs(dz)<=195...

User avatar
Claire Jackson
 
Posts: 3422
Joined: Thu Jul 20, 2006 11:38 pm

Post » Sat Aug 28, 2010 8:41 am

@ otm - Wait what? Wouldnt the script he already has set up account for the player not standing at exactly a 90* increment? That was what his whole issue was, and you cant use getting the hummers angle in relation to the player, as he stated. So what was that all about? All I see is that you are taking a chunk of the script and expanding it to make it more complicated, but serve the same purpose? Correct me if I'm wrong, because I did just wake up.
User avatar
Trey Johnson
 
Posts: 3295
Joined: Thu Oct 11, 2007 7:00 pm

Post » Sat Aug 28, 2010 7:14 pm

otm's right, his method would work and would be a lot simpler. Kudos :celebration: It works because the player has to be facing the hummer to activate it. You don't necessarily have to be facing the hummer's center point to activate it though, so the angle will often be a bit off, but probably not enough to break what you need it for.

*Edit - thinking about your application though, you'll want to be able to tell when the player is activating the gas tank, which is a pretty narrow range of angles. Since the player could be facing directly perpendicular to the hummer but be in a position to activate either the fuel door or the passenger side door, you'd need to use the original method, because otm's method would return the same angle in either case.
User avatar
Jhenna lee Lizama
 
Posts: 3344
Joined: Wed Jun 06, 2007 5:39 am

Post » Sat Aug 28, 2010 4:35 pm

otm's right, his method would work and would be a lot simpler. Kudos :celebration: It works because the player has to be facing the hummer to activate it. You don't necessarily have to be facing the hummer's center point to activate it though, so the angle will often be a bit off, but probably not enough to break what you need it for.

*Edit - thinking about your application though, you'll want to be able to tell when the player is activating the gas tank, which is a pretty narrow range of angles. Since the player could be facing directly perpendicular to the hummer but be in a position to activate either the fuel door or the passenger side door, you'd need to use the original method, because otm's method would return the same angle in either case.


Well I have been trying the various code in these posts - - so far have not been able to get it to work, and the numbers coming out are chaotic. But this could be me doing something wrong, I have a few things left to try.

I don't need to activate the fuel tank in a narrow angle or anything. I just need each of the 4 areas of the hummer to detect properly. The entire "hood" is the intended fuel area, and then each side of the vehicle does something different, and the back is the trunk.

There's also the fact that the code I have now almost works right (it is pasted into an earlier post). Its trouble is, the hummer doesn't tolerate small changes away from angles 45, 135, 225, and 315 well. When you turn the hummer so that it is in between those angles, it acts like it's still in them, so the perceived activaton areas on the hummer are shifted a bit.
User avatar
Rudy Paint fingers
 
Posts: 3416
Joined: Sun Nov 11, 2007 1:52 am

Post » Sat Aug 28, 2010 2:53 pm

I don't understand how to make this part:



dz = player.getAngle Z - hummer.getAngle Zif dz > -15 && dz <= 15 ; 0 +- 15 degrees........... ;open trunkelseif dz > 75 && dz <= 105 ; 90 +-15 degrees..........  ;activate left seatelseif dz >-75 && dz <= -105 ; -90 +- 15 degress..........  ;activate left seatelseif dz >165 && dz <= 195 ; 180 +- 15 degrees..........  ;activate engineelse..........  ;if none of the arcs is valid show a message or something. You could also make the tolerance big enough so that there are no "invalid" arcs,            ;in this case where you have four arcs, the tolerance would have to be +-45 degrees instead of the 15 I put in the example.endif



work as one process with this part:




The way to work around this would be an anagoge of your angles to the first quadrant, like this:

set HA to hummer.getAngle Z set PA to player.getAngle Zif HA > 0 && HA <= 90..... ; do nothing, we're okelseif HA > 90 && HA <= 180     set HAAnagoged to HA - 90     set PAAnagoged to PA - 90elseif HA > 180 && HA <= 270     set HAAnagoged to HA - 180     set PAAnagoged to PA - 180elseif HA > 270 && HA <= 360     set HAAnagoged to HA - 270     set PAAnagoged to PA - 270endif




Would it be possible to put this whole thing into more of one sort of process where the variable names are consistant and so on? I don't understand enough about the math behind this to be able to put these pieces together myself.
User avatar
Sudah mati ini Keparat
 
Posts: 3605
Joined: Mon Jul 23, 2007 6:14 pm

Post » Sat Aug 28, 2010 7:50 pm

I'm not sure I understand why that second block of code is necessary. All it does is make it so that HA is always between 0 and 90 - but for this application, you're definitely going to want the angle to be between 0 and 360.

Have you checked out the model though to see how the axis are arranged? Also, while in game, bump the hummer around with the drone gun so that its facing various angles, and each time, enter the console, click on the hummer, and type "getangle z". I've noticed some weird things when using getangle with things other than actors - z angle is usually reported correctly, but the x and y angles are somehow effected by the z angle. If the hummer's vertical axis is something other than the z axis, none of this code will work, and you'll probably need to go into nifskope and edit the axis.

I'm using a technique similar to otm's in Powered Power Armor (the upcoming release). I'm trying to be able to tell when the player is targeting the back of an NPC wearing power armor, and to do so, I just subtract the target's getangle z from the player's getangle z, and add 360 if the result is negative. It works, and there's no need for that anagoge stuff because the quadrant has no effect on anything. Your application is virtually the same, its calculating the same angle - the difference between where the player is pointing and where the hummer (target) is pointing. If the hummer's axis are set up right, the following code will work:

set HA to TRef.getangle zset PA to FRef.getangle zset angle to PA - HAIF angle < 0    set angle to angle + 360ENDifIF angle >= 45 && angle < 135   ; do stuff, you're facing the driver's sideELSEif angle >= 135 && angle < 225    ; do stuff, you're facing the hoodELSEif angle >= 225 && angle < 315    ; do stuff, you're facing the passenger sideELSE    ; do stuff, you're facing the trunkENDif

User avatar
Emma Parkinson
 
Posts: 3401
Joined: Wed Jul 26, 2006 5:53 pm

Post » Sat Aug 28, 2010 12:04 pm

Wow, well this works exactly the way you would expect from looking at the code BUT there's something which needs help yet... its...

set TREF to PlayerHummerREFset HummerAngle to PlayerHummerREF.getangle zif Hummerangle < 0 ;who knows why it does that	set Hummerangle to Hummerangle + 360elseif HummerAngle > 360	set HummerAngle to HummerAngle - 360endifset FREF to PlayerREFset HA to TRef.getangle zset PA to FRef.getangle zset angle to PA - HAIF angle < 0    set angle to angle + 360ENDifset angle to angle + 90 ;its always 90 degrees off.if angle > 360	set angle to angle - 360endifIF angle >= 45 && angle < 135   ; do stuff, you're facing the driver's side	set Mode to 0	showmessage HummerDoorDebugMsg	returnELSEif angle >= 135 && angle < 225	set Mode to 2    ; do stuff, you're facing the hoodELSEif angle >= 225 && angle < 315	   ; do stuff, you're facing the passenger side		showmessage HummerPassengMSG		returnELSE    ; do stuff, you're facing the trunk	set Mode to 1ENDif



The trouble is.

It totally depends on the player to be facing the hummer's center. This makes for some comical results.

I can stand next to the passenger's side door, look forward toward the front of the vehicle, be looking at the left fender, and activate, and it opens the trunk instead of the hood. I can tell that this is happening because the player's angle relative to the hummer's angle is the same as it would have been if I had been standing behind the hummer and been activating straight toward its center. So, it judges for the trunk-opening.

It works perfectly in terms of, if you rotate the hummer in front of the player, it always behaves predictably and in a sense, correct. But the hummer is too big visually as compared with the player, kinda, for this to look right. I can make for dramatic differences in the behavior by standing next to the hummer, turning to my left or right, and activating, instead of activating dead-on.

What I'm hoping is that, for example, if I am standing at the passenger's door, no matter what my own angle is, it'll see my position relative to the hummer's and determine that I am intending to activate the passenger side.
User avatar
Rebecca Clare Smith
 
Posts: 3508
Joined: Fri Aug 04, 2006 4:13 pm

Post » Sat Aug 28, 2010 2:04 pm

*Edit - thinking about your application though, you'll want to be able to tell when the player is activating the gas tank, which is a pretty narrow range of angles. Since the player could be facing directly perpendicular to the hummer but be in a position to activate either the fuel door or the passenger side door, you'd need to use the original method, because otm's method would return the same angle in either case.



That's pretty much what I was saying. You can't really fix it to be more precise without considerably more work than it would take to make the other method work, but you should be able to substitute in:

dx = FRef.getpos y - TRef.getpos ydy = FRef.getpos x - TRef.getpos xif dx == 0    if dy >= 0        set PA to 90    else        set PA to 270    endifelseif dy > 0    set tempFloat to dy / dx    set PA to tan tempFloat 1else    set tempFloat to dy / dx    set PA to tan tempFloat 1    set PA to angle + 180endifif PA < 0    set PA to PA + 360elseif PA >= 360    set PA to PA - 360endifset PA to PA + 180  ; the angle you just calculated faces in the opposite direction relative to the other method, so either make this correction or adjust the conditionals by 180 degreesif PA < 0    set PA to PA + 360elseif PA >= 360    set PA to PA - 360endif


for the line

set PA to FRef.getangle z

*Edit - I think another way to correct for the 180 degree shift after changing methods would be to swap "FRef.getpos x - TRef.getpos x" out for "TRef.getpos x - FRef.getpos x", and do the same for the dx calculation (my eyes have crossed).
User avatar
rheanna bruining
 
Posts: 3415
Joined: Fri Dec 22, 2006 11:00 am

Post » Sat Aug 28, 2010 11:11 pm

I tried it and it didn't work so well :/ what I saw didn't even make sense to me I'm afraid.

Like when the hummer was at an angle of 135, activating the front worked, but any other area acted as though I was activating the driver's door.

I turned the hummer to angle zero and I was accessing the trunk and other areas but, they didn't correspond with my position vs. the hummer.

hmm..
User avatar
Jennifer May
 
Posts: 3376
Joined: Thu Aug 16, 2007 3:51 pm

Post » Sat Aug 28, 2010 11:50 am

I just did a check in the console, and arctan returns an angle between -90 and 90, not 0 and 180, so that's almost definitely the problem. The code should then be:

dx = TRef.getpos y - FRef.getpos y        ;<---------- includes the 180 degree angle correctiondy = TRef.getpos x - FRef.getpos x        ;<----------if dx == 0    if dy >= 0        set PA to 90    else        set PA to 270    endifelseif dx > 0                                          ;<-------- this is the only other difference, dx instead of dy    set tempFloat to dy / dx    set PA to tan tempFloat 1else    set tempFloat to dy / dx    set PA to tan tempFloat 1    set PA to angle + 180endifif PA < 0    set PA to PA + 360elseif PA >= 360    set PA to PA - 360endif

User avatar
Rebecca Dosch
 
Posts: 3453
Joined: Thu Jan 18, 2007 6:39 pm

Post » Sat Aug 28, 2010 10:44 am

Something is still strange with it. The results are confusing in ways I don't understand.

Like, when I turn the hummer to z-angle of zero, I can stand at the corner of the trunk and the passenger side, and when I pivot back and forth, it'll activate different functions.

But then, if I stand right alongside the hummer, it will only activate one function (but not necessarily the right one)

Here's what I put - - does anything stand out as being messed up?

set TREF to PlayerHummerREFset HummerAngle to PlayerHummerREF.getangle zif Hummerangle < 0 ;who knows why it does that	set Hummerangle to Hummerangle + 360elseif HummerAngle > 360	set HummerAngle to HummerAngle - 360endifset FREF to PlayerREFset HA to TRef.getangle z;------set dx to TRef.getpos y - FRef.getpos y        ;<---------- includes the 180 degree angle correctionset dy to TRef.getpos x - FRef.getpos x        ;<----------if dx == 0    if dy >= 0        set PA to 90    else        set PA to 270    endifelseif dx > 0                                          ;<-------- this is the only other difference, dx instead of dy    set tempFloat to dy / dx    set PA to tan tempFloat 1else    set tempFloat to dy / dx    set PA to tan tempFloat 1    set PA to angle + 180endifif PA < 0    set PA to PA + 360elseif PA >= 360    set PA to PA - 360endif;-------------------;set PA to FRef.getangle z   <---------- commented outset angle to PA - HAIF angle < 0    set angle to angle + 360ENDifset angle to angle + 90 ;its always 90 degrees off.if angle > 360	set angle to angle - 360endifIF angle >= 45 && angle < 135   ; do stuff, you're facing the driver's side	set Mode to 0	showmessage HummerDoorDebugMsg	returnELSEif angle >= 135 && angle < 225	set Mode to 2    ; do stuff, you're facing the hoodELSEif angle >= 225 && angle < 315	   ; do stuff, you're facing the passenger side		showmessage HummerPassengMSG		returnELSE    ; do stuff, you're facing the trunk	set Mode to 1ENDif

User avatar
SUck MYdIck
 
Posts: 3378
Joined: Fri Nov 30, 2007 6:43 am

Post » Sat Aug 28, 2010 8:58 am

I don't see anything in that script that references the player's z angle, so it must be that the node used by getpos is in a different location than the node you pivot around, and your reported position changes a bit as you rotate. That shouldn't be too big of a deal though.

It might be accessing the wrong functions, but is it consistent, and does it access the same functions regardless of where the hummer is pointing, so long as you're standing in the same spot relative to it? If so its just a matter of adjusting the conditionals to produce the right results (I see you've got that 90 degree correction factor, that could probably just be handled by the conditionals). If not, something weird's going on. Did the other method more or less work? If so, the problem's with the PA calculation section. Otherwise, If it was having the same problems you're seeing now, it might be related to the hummer axis.
User avatar
Beth Belcher
 
Posts: 3393
Joined: Tue Jun 13, 2006 1:39 pm

Post » Sat Aug 28, 2010 8:34 pm

When I was looking at it, it was not consistent no :/ Sorry for not replying sooner. I had wanted to reply with something meaningful as to what it's doing but, it's hard to make sense of quite what's happening.

I have an idea for a workaround but have not yet tried it. So I'm not sure where to go with it quite this sec.
User avatar
Adam Kriner
 
Posts: 3448
Joined: Mon Aug 06, 2007 2:30 am

Post » Sat Aug 28, 2010 5:56 pm

haha.

It is working great now! But, it's such a cheesy hack.

The one and only thing that was wrong with the behavior was, it only worked well when the player was facing the hummer.

GetHeadingAngle happens to work on the player.

So.

I used the line of code from the GECK wiki page on getheadingangle to calculate what the player's angle to the hummer would theoretically be if he were facing the hummer while activating it, and, I use that value instead of the real angle value. http://geck.gamesas.com/index.php/GetHeadingAngle . I don't actually force the player to turn to the Hummer, I just snatch the angle value and run away with it.

Thanks to everyone who helped me look at this.


begin onactivateif isactionref player;such a hack haha, mebbe i learn 2 math one day.set CorrectedPlayerAngle to Player.GetAngle Z + Player.GetHeadingAngle PlayerHummerREFif Location == 0		set Location to 1	endif; below code with help from Imp of the Perverse and others - -set TREF to PlayerHummerREFset HummerAngle to PlayerHummerREF.getangle zif Hummerangle < 0 ;who knows why it does that	set Hummerangle to Hummerangle + 360elseif HummerAngle > 360	set HummerAngle to HummerAngle - 360endifset FREF to PlayerREFset HA to TRef.getangle zset PA to CorrectedPlayerAngleset angle to PA - HAIF angle < 0    set angle to angle + 360ENDifset angle to angle + 90 ;its always 90 degrees off.if angle > 360	set angle to angle - 360endifIF angle >= 45 && angle < 135   ; do stuff, you're facing the driver's side	set Mode to 0;	showmessage HummerDoorDebugMsg;	returnELSEif angle >= 135 && angle < 225	set Mode to 2    ; do stuff, you're facing the hoodELSEif angle >= 225 && angle < 315	   ; do stuff, you're facing the passenger side		showmessage HummerPassengMSG		returnELSE    ; do stuff, you're facing the trunk	set Mode to 1ENDifetc...

User avatar
Carlitos Avila
 
Posts: 3438
Joined: Fri Sep 21, 2007 3:05 pm

Post » Sat Aug 28, 2010 3:10 pm

Pretty damn clever actually. Took me a bit to figure out exactly what was going on, but it returns the exact same result as the tangent method (except it works).
User avatar
Katie Samuel
 
Posts: 3384
Joined: Tue Oct 10, 2006 5:20 am


Return to Fallout 3