• 🏆 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] GetUnitX, GetUnitY inaccuracy

Status
Not open for further replies.
When I call GetUnitX and GetUnitY on a unit, they are returning the X and Y of the unit +16 rather than its true coordinate, but only when the unit in question has collision size >= 16 and is not UNIT_TYPE_STRUCTURE. However, as we cannot query the unit's collision size in JASS, this would seem to suggest that there is no way to accurately determine the coordinates of a unit.

That seems absurdly stupid to me. How do I accurately determine the coordinates of a unit in JASS (or vJASS)? Has anyone decompiled game.dll and built a special one for mods, where we can accurately determine the coordinates of a unit maybe?

I just feel like I'm missing something, I was never aware that this was an issue before, I had put my faith in GetUnitX and GetUnitY.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
as mentioned in another thread, decompiling game.dll is against the ToS and you can get sued if you do so.

The unit's coordiantes is always where its center of collision is, there shouldnt be any major inaccuracy(note: major being bigger than .1)

Buildings have collision maps, so their positions arent exactly in the center
 
are you sure GetUnitX/GetUnitY is inaccurate? How do you know it is 16 coordinates off?

If you need to factor collision size into your spells, use the IsUnitInRange() functions:
JASS:
constant native IsUnitInRange       takes unit whichUnit, unit otherUnit, real distance returns boolean
constant native IsUnitInRangeXY     takes unit whichUnit, real x, real y, real distance returns boolean
constant native IsUnitInRangeLoc    takes unit whichUnit, location whichLocation, real distance returns boolean
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
JASS:
    set u = CreateUnit(GetTriggerPlayer(), 'hfoo', 11.11, 22.22, 0)
    call BJDebugMsg("Unit location = (" + R2S(GetUnitX(u)) + ", " + R2S(GetUnitY(u)) + ")")
    
    call SetUnitX(u, 33.33)
    call SetUnitY(u, 99.99)
    call BJDebugMsg("Unit location = (" + R2S(GetUnitX(u)) + ", " + R2S(GetUnitY(u)) + ")")
    
    call SetUnitPosition(u, 45.45, 54.54)
    call BJDebugMsg("Unit location = (" + R2S(GetUnitX(u)) + ", " + R2S(GetUnitY(u)) + ")")
    
    call SetUnitPositionLoc(u, Location(66.66, 77.77))
    call BJDebugMsg("Unit location = (" + R2S(GetUnitX(u)) + ", " + R2S(GetUnitY(u)) + ")")

Results:
"Unit location = (11.000, 22.000)"
"Unit location = (33.330, 99.990)"
"Unit location = (45.450, 54.540)"
"Unit location = (66.660, 77.770)"

CreateUnit() is inaccurate to round numbers.

SetUnitX()/SetUnitY(), SetUnitPosition(), SetUnitPositionLoc(), GetUnitX()/GetUnitY() are accurate enough to make everything work.

results made with unit collision size 0, 31 and 1024(default max)

From my tests... R2SW() is inaccurate... serious inaccurate.
 
Apparently if you collision is 16, moving your unit will cause it to go off-center. I was trying to center a crypt field in a circle of power and it would only center correctly when it's collision was 32 or 8.

I tested various collision sizes (up to 128) and it seems as though 16, 24 and 48+ are all off-center values. The other multiples of 8 up to 48 seem to center correctly.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,196
It likely returns the mechanical origin of the unit hence it should be the accurate position of the unit. Searching an area which contains that position will (should) return the unit.

I think the problem here is you do not care where the unit is, but rather where the centre of the unit actor is. This has nothing to do with the mechanical position of the unit.

So why is the unit offset? I agree it does not make much sense but could possibly come from how stuff was done in a 2D situation such as SC1 or WC2. There unit art position would likely be the lower left corner (or some other corner) since they were sprites. They probably adapted that into 3D with WC3 so that the unit is located at some sort of corner and then both its actor and collision are offset by some amount. The reason it relates so poorly to collision size could be some sort of correction they added to make collision size less relevant or that the origin is vaguely near the unit centre for large collision units.

I agree that it is kind of stupid but you must remember WC3 was a game that sort of came about rather than was designed so (like SC2 was). Origin should be the centre since that is the most natural and logical position for it to be but that does not mean it has to be.
 
Status
Not open for further replies.
Top