• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] caculating shortest pathable way to a point

Status
Not open for further replies.
Level 11
Joined
Sep 12, 2008
Messages
657
is it possible to caculate the fastest road from point A to B,
and make sure the path is walkable?

like..
create peasents on diffrence of 0.005 seconds between each spawn,
on that same path, making sure its pathable?

* solved *

New problem:

i have 2 units,
1 is the caster
2 is the target

i got their points (x, y),
but i need to know the angle from point 1 to point 2, so they will crash into each other.

example:
if i got a unit with 180 degrees,
and a unit left to it.
and the first unit moves forward with same 180 degrees,
they will never meet.
how do i find the angle the first unit has to move to meet that other unit?

important:
i wont be on for the next 2 days so ill read answers when i come back.
(israel holiday, we cant use electronic's for the next 2 days..)

thanks in advance.
 
Last edited:
In Jass I would do:
JASS:
    globals
        private     location    loc             = Location(0, 0)
    endglobals
    
	function GetLocZ takes real x, real y returns real
        call MoveLocation(loc, x, y)
        return GetLocationZ(loc)
    endfunction
    
    function GetUnitZ takes unit u returns real
        return GetLocZ(GetUnitX(u), GetUnitY(u)) + GetUnitFlyHeight(u)
    endfunction

    function AngleBetweenVectors takes vector first, vector second returns real
        return Atan2(second.y - first.y, second.x - first.x)
    endfunction

    function VectorFromUnit takes unit u returns vector
        return vector.create(GetUnitX(u), GetUnitY(u), GetUnitZ(u))
    endfunction

...
local vector start = VectorFromUnit(caster)
local vector end = VectorFromUnit(target)
local real facing = AngleBetweenVectors(caster, target) * bj_RADTODEG

//: facing now has the angle between caster to target in degrees. without bj_RADTODEG it is in radians.
 
Last edited:
@Anachron
Why are you using 3d-points to get the angle on the xy-plane?

@topic
JASS:
set angleInRadians = Atan2(yTarget - yStart, xTarget - xStart)
so if you want the start unit to face the target you would do something like
JASS:
local unit target
local unit start
set x = GetUnitX(target)
set y = GetUnitY(target
set x2 = GetUnitX(start)
set y2 = GetUnitY(start)
call SetUnitFacing(start, bj_RADTODEG * Atan2(y-y2, x-x2))

note that you can't set a units facing angle instantly that way but with lots of work you can do it this way http://www.wc3c.net/showthread.php?t=105830

important:
i wont be on for the next 2 days so ill read answers when i come back.
(israel holiday, we cant use electronic's for the next 2 days..).
that's hard
how could any religion justify that :eekani:
bet there is no 4000 years old book with the text "you shall not use your pc at this special day!!!!"

I have to help some distant relatives to move flat so I will be occupied with a few tons of useless stuff over the weekend x)
 
Level 11
Joined
Sep 12, 2008
Messages
657
well.. the problem is:

JASS:
call CreateUnitAtLoc(GetOwningPlayer(KageManeCaster[KM[3]]), ShadowRawI, l3, 0)

l3 = a location where it shall be created at.
GetUnitX(Unit) + Distance * Cos (GetUnitFacing(Unit) * bj_DEGTORAD)
GetUnitY(Unit) + Distance * Sin (GetUnitFacing(Unit) * bj_DEGTORAD)

how do i know what i set instead of GetUnitFacing,
to get the new location? tyvm.
 
Last edited:
Level 11
Joined
Sep 12, 2008
Messages
657
problem 1 and 2 arent so diffrent..
exept a bit changes..
problem 1 i did *solved* because i found how to check if its pathable or not..
sorry.. if some 1 answers problem 2, you can get the answer too.
 
Level 11
Joined
Sep 12, 2008
Messages
657
thats the location l3?
set l3 = Atan2(GetUnitY(target)-GetUnitY(caster), GetUnitX(target)-GetUnitX(caster))?
im testing anyways.

thanks again watermelon=]

edit, it requires both real X, real Y to set up a location.. (moving it atleast)..
so.. how do i make it work?^^
 
Level 11
Joined
Sep 12, 2008
Messages
657
Ohh... totaly sorry, ill read it now.
Really sorry >.>

edit:

JASS:
    function AngleBetweenVectors takes vector first, vector second returns real
        return Atan2(second.y - first.y, second.x - first.x)
    endfunction

second is not of a type that allows a . syntax?
any help?^^

funny.. my friend found a solution..
and ironcly, its same as watermelon's xD
i just didnt know how to use it.

JASS:
    function Angles takes unit caster, unit target returns real
    return Atan2(GetUnitY(target)-GetUnitY(caster), GetUnitX(target)-GetUnitX(caster))
    endfunction

JASS:
        set x = GetUnitX(Caster) + DistancePerLoop * Cos (Angles(Caster, Target))
        set y = GetUnitY(Caster) + DistancePerLoop * Sin (Angles(Caster, Target))
 
Last edited:
Level 18
Joined
Jan 21, 2006
Messages
2,552
Okay Anachron, the reason we ignored your post.

  • D4RK_G4ND4LF pointed out that you're using 3D vectors to calculate 2D angles. There is such a thing as a 2D vector, in which very similar operations are capable without an irrelevant z-coordinate.
  • You posted code that obviously requires a Vector library but you haven't stated this anywhere, and you haven't given any referrals to what you were using.

dardas said:
thats the location l3?
set l3 = Atan2(GetUnitY(target)-GetUnitY(caster), GetUnitX(target)-GetUnitX(caster))?
im testing anyways.

thanks again watermelon=]

edit, it requires both real X, real Y to set up a location.. (moving it atleast)..
so.. how do i make it work?^^

dardas said:
l3 = a location where it shall be created at.
GetUnitX(Unit) + Distance * Cos (GetUnitFacing(Unit) * bj_DEGTORAD)
GetUnitY(Unit) + Distance * Sin (GetUnitFacing(Unit) * bj_DEGTORAD)

This was your question:

dardas said:
how do i know what i set instead of GetUnitFacing,

Okay, so you want l3 to be a location. You've already given the coordinates to this location (in terms of the unit's facing) in one of your above posts, so you know what you're going to need.

JASS:
radians = Atan2(GetUnitY(target)-GetUnitY(caster), GetUnitX(target)-GetUnitX(caster))
x = GetUnitX(caster)+Distance *Cos(radians)
y = GetUnitY(caster)+Distance *Sin(radians)
l3 = Location(x, y)

watermelon_1234 already clarified this he wasn't intending you to use Atan2(GetUnitY(target)-GetUnitY(caster), GetUnitX(target)-GetUnitX(caster)) as the actual l3 location but instead as the angle that you would use instead of what you had posted that you were using to calculate the coordinates to be used for the location.
 
Level 9
Joined
May 27, 2006
Messages
498
Well, as i previously stated, i have a problem of similar nature, so i'll just write in this thread :) Could use any help

Basically i am working on a Heroes of Might and Magic 3-like combat system. If you've never played that game, the combat system is turn-based, the combat field is made of hexagonal/square tiles, on which the units can stand and move.
I've managed to code most of the movement so that it's functional (tho kinda inefficient, as far as i can tell). But i still need to find out how to calculate a units' movement range when there is an obstacle on the way that is limiting it's movement.

Look at attached image examples. Red and green are two units. Grey cells show the movement range of red unit. Red wants to attack green, so it moves towards it. Yellow line is the way red unit will most probably follow to reach it's destination. In first case there is no obstacle on the way, so it's easy. But in second case, blue represents some obstacles, which red must bypass. The obstacles are random, and this includes terrain as well as other units.
It is important, because each unit has a limited movement, lets say red can move 5 tiles (cells). In both cases the enemy is in "technical" range (think pick units in range 500), but not in "real" range, since the unit has to go around, which would be far more than 5 tiles (cells) of movement it has.

I have to highlight those tiles that are in units' range (image 1, i've managed to code that, but i still need to find out how to highlight them in a way they are in image 2)

If anyone has any idea on how to accomplish that, i would be really grateful... Or, at least, tell me whether it's possible or not, since i'm clueless.
 

Attachments

  • ex0.jpg
    ex0.jpg
    31.5 KB · Views: 69
  • ex1.jpg
    ex1.jpg
    38.9 KB · Views: 59
Well, as i previously stated, i have a problem of similar nature, so i'll just write in this thread :) Could use any help

Basically i am working on a Heroes of Might and Magic 3-like combat system. If you've never played that game, the combat system is turn-based, the combat field is made of hexagonal/square tiles, on which the units can stand and move.
I've managed to code most of the movement so that it's functional (tho kinda inefficient, as far as i can tell). But i still need to find out how to calculate a units' movement range when there is an obstacle on the way that is limiting it's movement.

Look at attached image examples. Red and green are two units. Grey cells show the movement range of red unit. Red wants to attack green, so it moves towards it. Yellow line is the way red unit will most probably follow to reach it's destination. In first case there is no obstacle on the way, so it's easy. But in second case, blue represents some obstacles, which red must bypass. The obstacles are random, and this includes terrain as well as other units.
It is important, because each unit has a limited movement, lets say red can move 5 tiles (cells). In both cases the enemy is in "technical" range (think pick units in range 500), but not in "real" range, since the unit has to go around, which would be far more than 5 tiles (cells) of movement it has.

I have to highlight those tiles that are in units' range (image 1, i've managed to code that, but i still need to find out how to highlight them in a way they are in image 2)

If anyone has any idea on how to accomplish that, i would be really grateful... Or, at least, tell me whether it's possible or not, since i'm clueless.

if you have a rather small number of stepps you could loop through the grid like this:

Code:
  0
Code:
  1  
 101 
  1
Code:
  2  
 212 
21012
 212 
  2
until you reached your desired grid point with smallest number

for max steps do
pick all grids around previous grids
if grid is pathable
if grid has no number
assign current steps counter to grid
start from begining again

doing this twice (starting at start + goal at once) will increase performance but be more complicated
 
Level 9
Joined
May 27, 2006
Messages
498
Well, that's exactly what i am doing, but that works well only when there are no obstacles.
Maybe i didn't clarify it, my system loops through the grid and checks whether the grid cell is in range of unit (much like IsUnitInRange(u1, u2, range), the only difference is it uses integers [position on grid x,y]). So i just can't detect any obstacles because this function simply doesn't take them into consideration.

Now when i think about it, i could just make those obstacles a struct containing info about their borders, but even knowing that, i still have to find a way how to check whether the tile is behind an obstacle in comparison to the unit or not. And then calculate it's way around...
Well, i guess it's kinda too tricky to explain. Gotta try to figure it myself, i've got a few ideas already.
Tho i can send the map if anyone's interested in messing with this horrible thing i've coded.

@Gandalf after edit
Well, thats one of the solutions i've been thinking about now. Gotta check it.
 
Status
Not open for further replies.
Top