• 🏆 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!

[JASS] Comparing point to playable map border point

Status
Not open for further replies.

Ardenian

A

Ardenian

Why does this not work ?

JASS:
loop
exitwhen udg_SUG_Point = Location(GetRectMaxX(bj_mapInitialPlayableArea), GetRectMinY(bj_mapInitialPlayableArea))) == true
endloop

How do I properly check if a point is equal to the playable area border at the bottom right ?
 
Level 12
Joined
Jan 2, 2016
Messages
973
Well, you have no actions... it's like you are checking if 1 is equal to 10 over and over again.
you need to use an "if" instead of loop if udg_SUG_Point == Location(blablabla) then
I don't know what exactly are you trying to do tho.
 
Locations are actually objects in memory. When you use Location(0, 0), that creates a completely new object in memory that contains the coordinates (0, 0). However, what happens if you make another location at (0, 0)?

Try this out:
JASS:
if Location(0, 0) == Location(0, 0) then
    call BJDebugMsg("Equal!")
else
    call BJDebugMsg("Not equal!")
endif

Our intuitive guess would say that it should print "equal". However, it doesn't. It prints "Not equal!", because the equality operator == only checks if the objects are the same in memory; it isn't sophisticated enough to check that they contain the same coordinates. For this reason, some programming languages will allow you to rewrite the behavior of == when comparing special objects, such as Locations. We can't rewrite the behavior of == in JASS, but we can always just write a function to help ourselves out!
JASS:
function AreLocationsEqual takes location a, location b returns boolean
    return GetLocationX(a) == GetLocationX(b) and GetLocationY(a) == GetLocationY(b)
endfunction

That will directly compare the coordinates to see if they are equal. In most cases, that will work. However, real variables are a bit imprecise at times. They don't always make intuitive sense when we compare them with ==, because they might be represented differently internally even if they are really close in value. To make a human analogy: if I am loading up a truck and I want the average apple to weigh 6 oz, I probably won't care whether it is 6.2 oz or 5.8 oz per apple. As long as it is reasonably close, I'll let it slide. But if it gets too far on either end, such as 5.5 oz or 7 oz, then it'll be concerning. As such, you might want to write an "approximately equal" function that handles that for you:
JASS:
function ApproximatelyEqual takes real a, real b, real epsilon returns boolean
    return RAbsBJ(a - b) <= epsilon
endfunction

In your case, you might want to do something like this:
JASS:
set x = GetLocationX(udg_SUG_Point)
set y = GetLocationY(udg_SUG_Point)
set rx = GetRectMaxX(bj_mapInitialPlayableArea)
set ry = GetRectMinY(bj_mapInitialPlayableArea)
exitwhen ApproximatelyEqual(x, rx, 0.1) and ApproximatelyEqual(y, ry, 0.1)

You can change 0.1 to whatever precision you want.
 

Ardenian

A

Ardenian

Well, it is some time ago I played around with Jass and I thought the check for two locations is A = B == true

Thank you very much, PurgeandFire and WereElf, it is clear to me now!

I would give rep, but both of you are just too helpful and I already did.
 
Just as a little helpful tip: = will always be for assignment. For example, setting a variable to a value:
set a = 5
When you want to compare two values, use double-equals ==:
if 5 == 4 + 1 then
You usually don't need to bother with the == true part. I find it helpful to phrase it as a question whenever I happen to come across any boolean statement. In the example above, I would think in my head: "is 5 equal to (4 + 1)?" That is basically how the computer sees it. In most cases, you don't need to add that extra "true" check.
 

Ardenian

A

Ardenian

Ahh, thank you!

Something related:
JASS:
function ApproximatelyEqual takes real x, real y, real epsilon returns boolean
    return RAbsBJ(x - y) <= epsilon
endfunction

Do I have to assign local real x and real y as such in the previous function ( where I call this function) or does it create it automatically on the new function ( nothing to add anywhere) ?
 
Do I have to assign local real x and real y as such in the previous function ( where I call this function) or does it create it automatically on the new function ( nothing to add anywhere) ?

You can just copy and paste it as it is. The parameters section takes real x, real y, real epsilon handles what arguments the function should take in.

Here is an analogy: let's say you want to make a sandwich. It can get tiresome to make it yourself, so you decide to build a machine. You don't always want it to make a regular sandwich; sometimes you want to switch it up with turkey or lettuce, etc. So if you designed this machine, you would probably want to put in ingredients. You can think of it as a function:
JASS:
function SandwichMachine takes meat, veggies, sauces returns Sandwich

Those "variables" are simply passed to you. You don't need to declare them. Similarly, in regular JASS functions, those parameters count as variables you can use. You can manipulate them, destroy them--whatever you want! They behave almost exactly like local variables. If it helps, you can visualize it that way. Let's consider a really basic function that adds two numbers:
JASS:
function Add takes integer a, integer b returns nothing
    return a + b
endfunction
Let's say you call: call Add(2, 4). When the code is actually ran, '2' is bound to 'a' and '4' is bound to 'b' (but only inside that function), so visualizing them as local variables is pretty accurate.
 

Ardenian

A

Ardenian

Great PurgeandFire, thank you!

So, this works, after your explanation:

JASS:
function SandwichMachine takes meat, veggies, sauces returns Sandwich
    return Sandwich
endfuntion

function Iwantasandwich takes nothing returns nothing
    set udg_Sandwich = SandwichMachine( ingredient1, ingredient2, ingredient3)
    return
endfunction
 
Last edited by a moderator:
Level 17
Joined
Dec 11, 2014
Messages
2,004
Great PurgeandFire, thank you!

So, this works, after your explanation:

JASS:
function SandwichMachine takes meat, veggies, sauces returns Sandwich
    return Sandwich
endfuntion

function Iwantasandwich takes nothing returns nothing
    set udg_Sandwich = SandwichMachine( ingredient1, ingredient2, ingredient3)
    return //DOES NOT HAVE TO BE HERE
endfunction

Just remove the empty return and it'll perfectly work (it still does compile though).
And add a "c" to that endfun/*c*/tion.
Btw you know custom variables are vJASS structs, right...? Like Sandwich or stuff like that...
 

Ardenian

A

Ardenian

Just remove the empty return and it'll perfectly work (it still does compile though).
And add a "c" to that endfun/*c*/tion.
Btw you know custom variables are vJASS structs, right...? Like Sandwich or stuff like that...
Ohh, so I have do not return something I don't need to add a line with an mepty 'return' ? Great to know, thanks!

Uh, no, I am not sure what you mean. Do you mean that variables declared as globals but not being globals are vJass structs ?
I mean, I could just create a global <insert type here> variable and name it Sandwich.
 
Level 12
Joined
Jan 2, 2016
Messages
973
Uh, no, I am not sure what you mean. Do you mean that variables declared as globals but not being globals are vJass structs ?
I mean, I could just create a global <insert type here> variable and name it Sandwich.
Then the trigger will look more like:
JASS:
function SandwichMachine takes unit meat, real veggies, integer sauces returns real
    local real ham = I2R(GetHandleId(meat)-0x100000)
    return ham*veggies+I2R(sauces)
endfunction
Or something like that.
 

Ardenian

A

Ardenian

Hm, I think I understand, thank you!
So it creates like a new class of variables, as integer, real and boolean, for example, if I use a struct ?
 
Level 12
Joined
Jan 2, 2016
Messages
973
Hmm, I didn't realize you were talking about structs.
I admit I haven't used any of these yet, but I've seen some examples...
I think it will look more like:
JASS:
struct Sandwich
    real meat
    integer veggies
    real sauces
endstruct

function SandwichMachine takes real meat, integer veggies, real sauces, returns Sandwich
    local Sandwich Subway = Sandwich.create()
    set Subway.meat = meat
    set Subway.veggies = veggies
    set Subway.sauces = sauces
    return Subway
endfunction

You can see more realistic examples here.
 
Status
Not open for further replies.
Top