• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

local vs global variables

Status
Not open for further replies.
Level 12
Joined
Jan 2, 2016
Messages
973
Which variables are better?
I have a trigger, that creates LOTS of local variables every time it runs, and it runs kind a often. So I started wondering if it isn't better just to use some global variables, not to create/destroy the local ones every time the trigger runs.
JASS:
    local unit m_targ = udg_GDD_DamagedUnit
    local unit shooter = udg_GDD_DamageSource
    local location m_ut_pt = GetUnitLoc(shooter)
    local location m_point = GetUnitLoc(m_targ)
    local real x = GetLocationX(m_ut_pt)
    local real y = GetLocationY(m_ut_pt)
    local unit s_targ
    local real health = GetWidgetLife(m_targ)
    local timer time = CreateTimer()
    local integer id = GetUnitTypeId(shooter)
    local integer targets = LoadInteger(udg_Table, id, 'targ')
    local integer a_type = LoadInteger(udg_Table, id, 'atyp')
    local real range = LoadReal(udg_Table, id, 'rang')
    local real dist = LoadReal(udg_Table, id, 'para')
    local boolean upg = LoadBoolean(udg_Table, id, 'upgr')
    local boolean al_hits_main_tar = LoadBoolean(udg_Table, id, 'ahmt')
    local integer missile = LoadInteger(udg_Table, id, 'misl')
    local real ofst_ang = LoadReal(udg_Table, id, 'ofst')
    local real dam
    local real init_ang = AngleBetweenPoints(m_ut_pt, m_point) + ofst_ang
    local location para_pt = PolarProjectionBJ(m_ut_pt,dist,init_ang)
    local unit dummy = CreateUnitAtLoc(GetOwningPlayer(shooter), 'h00C', m_ut_pt, 0.00)
    local real max_hp
    local group g
    local integer count
    local integer d_id = GetHandleId(dummy)
    local timer table_clear = CreateTimer()
    local integer left_c
    local integer right_c
    local unit array left
    local unit array right
    local integer dice
 
Level 12
Joined
May 22, 2015
Messages
1,051
Well you can simplify this. It is possible (and recommended) to never use points in any of your JASS ever (some exceptions I guess, like reusable points that you don't want to hardcode).

EX:
JASS:
    local location m_ut_pt = GetUnitLoc(shooter)
    local real x = GetLocationX(m_ut_pt)
    local real y = GetLocationY(m_ut_pt)

You could skip the location one and just use GetUnitX() and GetUnitY(). You would, of course, need to modify the other lines that were using that point.

It could be taht some of these are unnecessary. I usually just reuse my variables and leave comments to direct myself.

Where are you creating all of these and storing them in a hashtable? Seems like a lot of loads. It's possible with vJASS to use structs, but I have never used those before lol.

Anyway, I don't think there will be any difference by using globals instead. It will just be really annoying to read with "udg_..." for every variable. It will also clutter your global variables when you go to add / edit / delete others. Prefixing your globals for this is helpful to reduce clutter, but then makes the code even MORE annoying with "udg_MS_..." in front of all the variables.
 
Locals are good to get autonomous functions.

But if you need to create/destroy handles frequently, then help might be used.
For temp groups usually only 1 global group can be used that is never destroyed.
Reals may often be used over locations, so no need to create/remove them.
For timers there exist for example a recylcler system.

But using other primitve local types for temp variables is good actually.
 
Level 12
Joined
May 22, 2015
Messages
1,051
I need that point to calculate distance between points, and angle between points.
I know I can calculate the distance with sqrt(x2-x1)^2 + (y2-y1)^2)...
and angle would be atg((y2-y1)/|x2-x1|), but is that 'lighter' way to do it?

It's definitely better to do those calculations yourself. The functions that calculate it for you have to do the exact same thing, except being BJ functions means they might call excessive functions and using points means you have to create and delete them which is more variables and more stuff to do. Working with raw numbers will be faster.
 
Level 12
Joined
Jan 2, 2016
Messages
973
Okay, so I need to:
1) replace each point with 2 reals
2) replace the unit group with a global group

What about the unit variables?
Are they better as globals or are they better as locals?
And.. is there a point to set a local variable to a global one, or can I just use the global one, and it will be the same/better (set shooter = udg_GDD_DamageSource; set target = udg_GDD_DamagedUnit)

EDIT:
By the way. Can I write mathematical equasions like "(x_ta - x_sh)^2" or do I need to use the Power function?
 
Last edited:
Level 12
Joined
May 22, 2015
Messages
1,051
Okay, so I need to:
1) replace each point with 2 reals
2) replace the unit group with a global group

What about the unit variables?
Are they better as globals or are they better as locals?
And.. is there a point to set a local variable to a global one, or can I just use the global one, and it will be the same/better (set shooter = udg_GDD_DamageSource; set target = udg_GDD_DamagedUnit)

Using globals like that can be dangerous since they could be affected by other things.

However, it is important to note that there are times that it is definitely safe. As an example, my DDS that I made for myself has some global variables:
udg_source
udg_victim
(they are actually arrays now to handle multiple damage instances all at once, but ignore that for now)

Anyway, when I want to add new effects to the DDS, I add conditions to specific triggers that are run inside the DDS. These triggers have no events and are only run by the DDS, but it allows me to dynamically add code to the DDS (mostly so unused classes don't have all their checks being made).

Anyway, inside these functions that I add as conditions to those triggers, I use udg_source and udg_victim. There is no danger using them here (unless I mess up with my DDS, but ignore that as well). The point is that if a function gets run immediately without any delay (not even a 0s timer), then it is safe to use globals.

If you build things as part of systems, it is easier to reuse globals.

A more simple example built off the same idea is my attack event "system" (it really isn't much of a system lol). I have a trigger the fires when a unit is a attacked, and that trigger set udg_attackSource = GetAttacker() and set udg_attackVictim = GetTriggerUnit() and then runs this other trigger. I add conditions to this other trigger to run "a unit is attacked" code and use those globals. This skips fetching the attacker and attacked unit for every one of those functions. This was not the primary purpose of doing it, but that is a small thing I gained. The real reason was so I could fire fake attack events with other triggers (coded a doublestrike ability). Anyway, just hoping to explain how the globals can be used.
 
Level 12
Joined
Jan 2, 2016
Messages
973
My questions was more like "is there any difference in the trigger's performance when using global variables instead of local ones?".

Global ones don't need to be declared, and nullified every time the trigger runs.
Global ones can be used in called functions, without the function "taking" them.

So.. I'm wondering if using local ones are faster or something.

+ Please check the Edit in my last post xP
 
Level 12
Joined
May 22, 2015
Messages
1,051
My questions was more like "is there any difference in the trigger's performance when using global variables instead of local ones?".

Global ones don't need to be declared, and nullified every time the trigger runs.
Global ones can be used in called functions, without the function "taking" them.

So.. I'm wondering if using local ones are faster or something.

+ Please check the Edit in my last post xP

No idea if there is a power function of if "^2" works. You could just assign the number to a real named "a" and then do "a * a".

Nulling a variable is a very tiny action. Globals are nice, sometimes, but they are harder to follow when reading code and they are prone to errors. I don't know if passing in many parameters changes the speed of the function. I doubt it really matters.

Local variables are way easier to work with because of shorter, more accurate names without all the prefix nonsense and they will never interfere with other instances of the function. I would not worry about how much you have. Just note that you can maybe trim them at times. They may be very slightly faster, but imo it is not worth it to get that little bit of speed to make your code potentially really ugly.
 
Level 12
Joined
May 22, 2015
Messages
1,051
Oh, I just remembered. I need to create 1 dummy at the m_ut_pt.
Can I create it at x and y (without assigning a point to them)?

Yes. There is a CreateUnit function that is like:
set u = CreateUnit(player, 'type', x, y, angle)

If you use JASS, you can get by without ever making a single point object ever. You don't have to destroy x or y values (just real variables) and you don't need to null them, so it will be a lot less random little lines like that.

You can also skip using local variables if you only ever use them once. Just add them when you need them. Also, really, don't worry about having a lot of them. If you definitely need them, then there's not much you can do.
 
Level 7
Joined
Nov 19, 2015
Messages
283
EDIT:
By the way. Can I write mathematical equasions like "(x_ta - x_sh)^2" or do I need to use the Power function?

I read somewheere that using the Power function is slower than using x*x.
If you want speed I would recommend this:

(x_ta - x_sh)*(x_ta - x_sh)

Im creating a library at the moment with all the maths to since Im switching fromusing point to coordinates. I can post it here if you want, I havn't got all the functions yet, but its a start and might help you.

JASS:
library GlobalVariables
globals
    location LOCATION = Location(0,0)
    constant real PI = 3.141593
    constant real DEGTORAD = 180.0/PI
    constant real RADTODEG = PI/180.0
endglobals
endlibrary

library PositionFunctions

function DistanceBetweenCoordinates takes real x1, real y1, real x2, real y2 returns real
    local real x = x2-x1
    local real y = y2-y1
    return SquareRoot(x*x+y*y)
endfunction

function AngleBetweenCoordinatesRad takes real x1, real y1, real x2, real y2 returns real
    return Atan2(y2-y1,x2-x1)
endfunction

function AngleBetweenCoordinatesDeg takes real x1, real y1, real x2, real y2 returns real
    return Atan2(y2-y1,x2-x1)* RADTODEG
endfunction


function PolarOffsetX takes real x, real distance, real angle returns real
    return x + distance*Cos(angle*DEGTORAD) 
endfunction

function PolarOffsetY takes real y, real distance, real angle returns real
    return y + distance*Sin(angle * DEGTORAD)
endfunction

endlibrary
 

EdgeOfChaos

E

EdgeOfChaos

Nice library, that's useful. There's no need for the constants though, since those already exist in WC3: bj_PI, bj_DEGTORAD, bj_RADTODEG. Despite their names, they are not actually bj functions but just constants and you won't need precision past ~4-5 decimals of Pi so there's no need to redeclare them.
 
Level 12
Joined
Jan 2, 2016
Messages
973
Well, I pretty much can handle any maths myself, but I'm kind a wondering about something else.
if I use the atg((y2-y1)/|x2-x1|), would it give me only angles between -90 and 90?
I could manually add a condition like "if x1 > x2 then set the angle to 180 + the old angle", but can this be avoided?

EDIT: I actually noticed that the WE has 2 Atan functions. 1 from Value, and 1 from x and y.
Does the 2-nd type return the real deg?

EDIT 2: I tested it with the DebugMsg function. Seems like the angle is from -90 to 270 deg, but the 0 is at 'north', so the -90 with this function is the actual 0.
 
Last edited:

EdgeOfChaos

E

EdgeOfChaos

The Atan function is arctangent. It will calculate the angle required to get the tangent (for example, atan(1)=pi/4 radians). Atan2 calculates the arctangent of y/x, which basically means the angle between the points. Both return angle in radians.

This is the definition of AngleBetweenPoints:
JASS:
function AngleBetweenPoints takes location locA, location locB returns real
    return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
endfunction
Copying this and putting point args instead of loc args should be fine. If you want to see what the result would be, go to wolframalpha.com and type in "atan2(a,b)" into the box.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
In real programming languages like C/C++ locals make either no difference at all or even are faster than global variable access. This is because most processors come with dedicated instructions for manipulating the stack and the top of stack is very likely to be in cache most of the time. Further more local variables often can be built into the resulting machine code as constants meaning that local declaration has no processor overhead.

In JASS local variables are slower than global variables. This is because the local declaration needs to be evaluated and local handles often need to be explicitly nulled before function return. Actual evaluation speed of the variable is about the same, with locals often having an advantage due to their shorter variable names (faster lookup).
 
Level 12
Joined
Jan 2, 2016
Messages
973
The Atan function is arctangent. It will calculate the angle required to get the tangent (for example, atan(1)=pi/4 radians). Atan2 calculates the arctangent of y/x, which basically means the angle between the points. Both return angle in radians.

This is the definition of AngleBetweenPoints:
JASS:
function AngleBetweenPoints takes location locA, location locB returns real
    return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
endfunction
Copying this and putting point args instead of loc args should be fine. If you want to see what the result would be, go to wolframalpha.com and type in "atan2(a,b)" into the box.

That's odd... when I tested it, I wasn't converting it from radians to degrees, but it was giving me the angle in degrees anyways...
However, I didn't realize Y was the 1-st argument, and X - the second. Probobly that's the reason I was getting '0' deg when it was supposed to be '90'. I will test it later, when I switch x's and y's places.

Anyways... this is a bit off topic, but still kind a related:
Is it better to make a custom function that calculates the angle between x1 x2 y1 y2, and call it every time I need the angle, or should I just write it manually every time I need it?
Example 1:
JASS:
function CustomAngle takes real x1, real y1, real x2, real y2 returns real
return Atan2( y2 - y1 , x2 - x1 )  //maybe *57,3.... time will tell
endfunction

//stuff
set ang = CustomAngle(x_u, y_u, x_t, y_t)
//more stuff
Example 2:
JASS:
//stuff
set ang = Atan2( y_t - y_u , x_t - x_u )  //maybe *57,3
//more stuff
 
Level 12
Joined
Jan 2, 2016
Messages
973
Actually I just noticed I was using Atan2BJ. It automatically converts the radians to deg. However, I switched it to native Atan2, and after a bit of testing, I found my mistake, which was causing a bug :D

Now my trigger is faster indeed. Before it was causing a 0,1 sec lag when runing for 1-st time (on the map), but now that lag is gone. It goes smoothly ^_^

And well, Bribe, my trigger doesn't exactly need both angle AND distance. Or when it does - it takes angle between x1, x2 , y1 and y2, and the distance between x3, x2, y3 and y2, so I kept just using the points xP
 
Level 7
Joined
Nov 19, 2015
Messages
283
Nice library, that's useful. There's no need for the constants though, since those already exist in WC3: bj_PI, bj_DEGTORAD, bj_RADTODEG. Despite their names, they are not actually bj functions but just constants and you won't need precision past ~4-5 decimals of Pi so there's no need to redeclare them.

Thanks. Yea, I know there are the BJ_constants but I just like renaming it I gues (it looks nicer :D). I saw other people's systems also do the same so I guess, I just followed their lead.

How many decimal places does Jass hold?

@Werelf: Did you get an answer for which one was better?
(Is it better to make a custom function that calculates the angle between x1 x2 y1 y2, and call it every time I need the angle, or should I just write it manually every time I need it?)
 
Level 7
Joined
Nov 19, 2015
Messages
283
The "real" type is a IEEE 32 bit floating point. I believe the extra bits of precision used by floating point units are lost during calculations due to the mechanics of JASS.

Ahh, Perhaps this is why some of my angles are a bit off. I use the law of cosine to predict where a unit will be and fire a missile towards that point however at certain angles it overshoots.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Ahh, Perhaps this is why some of my angles are a bit off. I use the law of cosine to predict where a unit will be and fire a missile towards that point however at certain angles it overshoots.
The precision is so great that even across the map over a minute it should still hit if the unit keeps moving straight. Sounds like the unit changes direction (new micro move) or that your maths are a bit off.
 
Level 12
Joined
Jan 2, 2016
Messages
973
Well, when I was truning the angles from radians to deg, I tried using 57,3, but it wasn't as good as I wanted it to be, then I tried 57,29578 but that didn't work either, so I just wrote 57,295779513082320876798154814105, and now it's working just fine.

Is using so precise numbers expensive (processor wise)? What's the 'optimal' amount of diggits I should put after the " . "?

EDIT: I just ran several tests. Seems like 57,29577951308 is the shortest version, that works properly (for me).
 
Last edited:
Level 7
Joined
Nov 19, 2015
Messages
283
Well, when I was truning the angles from radians to deg, I tried using 57,3, but it wasn't as good as I wanted it to be, then I tried 57,29578 but that didn't work either, so I just wrote 57,295779513082320876798154814105, and now it's working just fine.

Is using so precise numbers expensive (processor wise)? What's the 'optimal' amount of diggits I should put after the " . "?

Oh, that is an interesting find. I guess we might need to increase the length of some of our constants (eg. Pi)
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Well, when I was truning the angles from radians to deg, I tried using 57,3, but it wasn't as good as I wanted it to be, then I tried 57,29578 but that didn't work either, so I just wrote 57,295779513082320876798154814105, and now it's working just fine.
Please explain what you are doing (the script possibly?). The fact it makes such a large difference makes be doubt the reliability of whatever it is.

Also this is an English only forum, please use English localized numbers to avoid potential confusion. For example if you wrote 57,295 then is that "fifty-seven thousand two hundred and five" or "57.295".
Is using so precise numbers expensive (processor wise)? What's the 'optimal' amount of diggits I should put after the " . "?
The same 32 bit floats are manipulated in any case. Performance difference are probably as good as non-existent thanks to pipelining and if they do exist then it is still so small that it is beyond anything to worry about with JASS.

The number of decimal places the number can represent is variable. It is called "floating point" for a reason. Mechanically as far as you are concerned it is accurate to "6 to 9 significant decimal digits".

Oh, that is an interesting find. I guess we might need to increase the length of some of our constants (eg. Pi)
The resultant change might make some fraction of a degree difference at most. Chances are if you need such precision you might be doing something mechanically flawed.

For example instead of computing what angel to fire a missile to hit a moving target, you compute where the missile would impact the moving target and "lock on" to that point. Angle inaccuracy is then a non-issue as it will always impact the computed point, correcting any inaccuracies as it moves along.
 
Level 7
Joined
Nov 19, 2015
Messages
283
The resultant change might make some fraction of a degree difference at most. Chances are if you need such precision you might be doing something mechanically flawed.

For example instead of computing what angel to fire a missile to hit a moving target, you compute where the missile would impact the moving target and "lock on" to that point. Angle inaccuracy is then a non-issue as it will always impact the computed point, correcting any inaccuracies as it moves along.

What do you mean by lock on to that point?
I use my equation to work out the time it for my missile to connect with the unit. I then find the point at which they will meet and then fire in a straight line towards that point. By the time the missile gets there the unit is also there. However I am using very small missiles and high speeds. It works at most angles but some it overshoots. I've remade the equation multiple times but I thought it was due to all the calculations and rounding that made it inaccurate.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
I use my equation to work out the time it for my missile to connect with the unit. I then find the point at which they will meet and then fire in a straight line towards that point. By the time the missile gets there the unit is also there. However I am using very small missiles and high speeds. It works at most angles but some it overshoots. I've remade the equation multiple times but I thought it was due to all the calculations and rounding that made it inaccurate.
You do not move the missile in a direction, you move it to the point over the period of time. That way it will always impact the point. The mathematics for movement are then simple line segment formula where the fraction along the line you are is based on the time until impact (with at the destination when at impact time).
 
Level 12
Joined
Jan 2, 2016
Messages
973
Please explain what you are doing (the script possibly?). The fact it makes such a large difference makes be doubt the reliability of whatever it is.

You will probobly get lost in the script if I post it. It's not the simplest one. But I will exaplin what it's doing:
In trigger 'one' I'm configuring the angle at a cone's peak, and then calculating where the 'focus' of a parabola (pretty much like the center of a circle), with similar angle, should be. Then the main trigger is working like a cone spell, but with parabolic shape, instead of pure cone.

I am only getting a problem, when I set the angle to 180 deg. Then the distance to the 'focus' is equal to infinity. The world editor actually sets it to some really large number (about 35000000000). So, when the angle is 180 - the spell should work as AoE (hit all enemies in range, instead of only enemies in the parabola). When I was using locations in my trigger, and functions to get the angle/disance between locations, when the angle was set to 180 deg - everything was getting hit, but when I reworked my trigger to use only coordinates, and started calculating the angle/distance between coordinates myself - it wasn't hitting anything until I put 11+ decimal numbers when converting radians to degrees.

The same 32 bit floats are manipulated in any case. Performance difference are probably as good as non-existent thanks to pipelining and if they do exist then it is still so small that it is beyond anything to worry about with JASS.

The number of decimal places the number can represent is variable. It is called "floating point" for a reason. Mechanically as far as you are concerned it is accurate to "6 to 9 significant decimal digits".

Okay, it's good to know that it's not very 'costy'. However, as I mentioned before, nothing beneath 11 decimal digits works for me. (I haven't really tried 10 diggits with an '1' in the end, instead of '0', but meh..)
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
WereElf, most likely scenario is you did something differently in your script to get the results. Highly-defined real values will not produce such a dramatic difference. The only way to investigate this further is for you to do some reproducible tests to determine if that one minor change is the culprit or if it is contingent on something else you did which you overlooked.
 
Level 12
Joined
Jan 2, 2016
Messages
973
I used BJDebugMsg(), showing me some values.
My condition for the shot to happen is:
"SquareRoot((x_t-x_p)*(x_t-x_p)+(y_t-y_p)*(y_t-y_p)) <= (2*|dist|)/(1-cos(ofst_ang))"
when ofst_ang is "(Atan2(y_t-y_p,x_t-x_p)*57.29577951308)-init_ang"

In the debug message I was displaying the distance between the 'p' (x_p and y_p) and the 't' point (x_t and y_t), as well as the (2*|dist|)/(1-cos(ofst_ang)).
When I was using 57.3 - the distance was 344xxxxxxxx, and the condition was 311xxxxxxxx (or something like that), then when I was using 57.29578 - it was 33xxxxxxxxx. I don't know how big is it with 57.29577951308, but it's bigger than the distance..

Do have in mind that 'p' is infinately further than 't', so the angle between them is 180 deg (or 179.9999999 or 180.0000001.. something like that), so (1-cos(ofst_ang)) is really really close to 2, thust small changes in the angle make 2*|dist|/~close to 2~ much closer to |dist| (which is "infinity").

EDIT: Actually my way of making this work is quite "artificial". A parabola (in maths) can't do what I'm making it do. I'm kind a abusing the computers' limitations for my purposes. But I kind a find it easier to do it this way instead of adding an extra "if" (if angle has been set to 180 - hit all enemies in range).
 
Last edited:

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
I am only getting a problem, when I set the angle to 180 deg. Then the distance to the 'focus' is equal to infinity. The world editor actually sets it to some really large number (about 35000000000). So, when the angle is 180 - the spell should work as AoE (hit all enemies in range, instead of only enemies in the parabola). When I was using locations in my trigger, and functions to get the angle/disance between locations, when the angle was set to 180 deg - everything was getting hit, but when I reworked my trigger to use only coordinates, and started calculating the angle/distance between coordinates myself - it wasn't hitting anything until I put 11+ decimal numbers when converting radians to degrees.
Sounds like your mathematics might be a bit off.

(2*|dist|)/(1-cos(ofst_ang))
If ofst_ang is 0 or 360 the value of "(2*|dist|)/(1-cos(ofst_ang))" becomes undefined and will cause a thread crash (division by 0) or a stupidly large value if not exactly the angle.

Do have in mind that 'p' is infinately further than 't', so the angle between them is 180 deg (or 179.9999999 or 180.0000001.. something like that), so (1-cos(ofst_ang)) is really really close to 2, thust small changes in the angle make 2*|dist|/~close to 2~ much closer to |dist| (which is "infinity").
JASS is not a mathematical engine. It cannot process infinites well and will cause propagation of IEEE floating point infinite or 0 values.

Seeing the trigger and where the values come from would be very useful as I am still unsure of what you are trying to do.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
"SquareRoot((x_t-x_p)*(x_t-x_p)+(y_t-y_p)*(y_t-y_p)) <= (2*|dist|)/(1-cos(ofst_ang))"
when ofst_ang is "(Atan2(y_t-y_p,x_t-x_p)*57.29577951308)-init_ang"

Problem: ofst_ang is in degrees, then you pass it to Cos which takes radians - not degrees. The likely reason it worked when you used the GUI behavior is you also probably used CosBJ instead. Best to stick with radians.

bj_RAD2DEG works fine. Don't bother with hardcoded decimals when the existing constants are perfectly fine.
 
Level 12
Joined
Jan 2, 2016
Messages
973
Problem: ofst_ang is in degrees, then you pass it to Cos which takes radians - not degrees. The likely reason it worked when you used the GUI behavior is you also probably used CosBJ instead. Best to stick with radians.

bj_RAD2DEG works fine. Don't bother with hardcoded decimals when the existing constants are perfectly fine.

Yeah.. I didn't copy-paste this, I just wrote it manually. I am indeed using CosBJ. Sometimes when I remove the BJ from some functions - they stop working (f. ex RAbsBJ), so I'm not trying to figure out which functions have a native version.
The |dist| is in fact RAbsBJ(dist).

I guess I'll check out if it's working with normal Cos xP.

but hmm, bj_RAD2DEG is something like a variable? Or is it something like a function?
 
Level 17
Joined
Dec 11, 2014
Messages
2,004
It's a constant variable. You can see it by TESH by checking constant instead of function (JNGP only).

JASS:
YourReal * bj_RAD2DEG == YourReal * 180 / bj_pi // was it bj_Pi or bj_pi? Lol

That will return true; because that's what bj_RAD2DEG is (turning the arc of a circle with the radius 1 to degrees).

Also to use it, use the method up there.


Awwww Bribe a 'lil faster ;)
 
Last edited:
Level 12
Joined
Jan 2, 2016
Messages
973
I have it, but I don't use it. I do everything in WE.
I'm not sure if I have an old version of the JNGP or something, but when I open a map, that I've created with WE in JNGP - it gives me a message, that the map has been created in a newer version of the WE and some of it's functions may not work. + I can't test the maps directly. I need to open WC III and open the map form there.
 
Level 12
Joined
Jan 2, 2016
Messages
973
Hmm, when I try to use bj_RAD2DEG - I'm getting some error "Expected a name"
JASS:
call SaveReal(udg_Table, udg_UnitType , 'ofst', udg_OffsetAngle/bj_RAD2DEG)
It was working fine without the rad 2 deg

EDIT: It works with *bj_PI/180.... (I'm trying to convert deg to rad)
 
Status
Not open for further replies.
Top