| 03-13-2007, 02:00 PM | #1 |
Lets say i have 2 copys of the exact same map next to eachother, and want an ability to switch you between them. Rather easy to do. untill you realize that there are buildings and variable pathing on the other side. I have NO idea where to start in coding a function to detect if a unit can fit in the area around a location. This has to account for things like building, and preferably units too. A fully coded function would be nice but just giving me an idea where to start would be great too ![]() |
| 03-13-2007, 06:39 PM | #2 |
If you just do SetUnitLocation(GetUnitX(u), GetUnitY(u)) then it will force the unit into a pathable area |
| 03-13-2007, 06:57 PM | #3 |
Thats a rather... messy way to do it tho =/ as you may think you're gonna end up somewhere... and be verry displeased to be pushed rather far away. whereas if i can simply find out if an area is pathable and can fit the unit, i can display an error message instead. |
| 03-13-2007, 07:08 PM | #4 |
Well then, use the same concept. Create a dummy unit at the position that the person would teleport to, and use SetUnitLocation on it. After that, check if the dummy unit moved more than about 10 distance (don't check if it moved more than 0 distance because that will usually true because of the inexactness of reals in WC3). If it did, that means that the spot is not pathable and you can give an error message. If not, it means the spot is clear and you can move the player unit there. |
| 03-13-2007, 07:27 PM | #5 |
Hows about using your CheckPathability() function, grim001? |
| 03-13-2007, 08:21 PM | #6 |
Yeah, that does the same thing, it's just a little more complicated to set up. JASS:function CheckPathability takes unit u, real x, real y returns boolean local real ox = GetUnitX(u) local real oy = GetUnitY(u) if x > 9376. or x < -9632. or y > 9376. or y < -9632. then //map bounds return false endif call SetUnitX(u, -9472.) //move unit to safespot call SetUnitY(u, 9216.) call SetUnitPosition(checkpathabilityunit, x, y) //requires global unit here set x = GetUnitX(checkpathabilityunit)-x set y = GetUnitY(checkpathabilityunit)-y call SetUnitX(checkpathabilityunit, -9472.) //moves global unit back to safespot call SetUnitY(checkpathabilityunit, 9216.) call SetUnitX(u, ox) call SetUnitY(u, oy) return x*x+y*y <= 100. endfunction This function moves the original unit to a safespot while it's doing the check so that it doesn't screw up a pathability check in a spot that is very close to the unit's own location. This is very useful when you're making units slide but you want to make sure they don't slide inside of buildings or off cliffs or inside other units. JASS:function CheckPathability_IgnoreUnits takes real x, real y returns boolean if x > 9376. or x < -9632. or y > 9376. or y < -9632. then //map bounds return false endif call SetItemPosition(checkpathabilityitem,x,y) //requires global item call SetItemVisible(checkpathabilityitem, false) set x = GetItemX(checkpathabilityitem)-x set y = GetItemY(checkpathabilityitem)-y return x*x+y*y <=100 endfunction |
| 03-14-2007, 02:18 AM | #7 | |
Quote:
But wouldnt it be more effective to use multiple unit types for comparing units of diffrent sizes, instead of having to check multiple spots with items? and isnt there even a function to change a units colission size? whereas items are only 1 size ;) But, thanks! I have a good start point now! +rep |
| 03-14-2007, 02:47 AM | #8 | ||
Quote:
Quote:
|
| 03-14-2007, 03:27 AM | #9 | |
Quote:
Except for the fact that items can fit in some spaces some units cannot. Example: X = No ground pathing O = Ground pathable S = Spot the unit 'wants' to go to, is ground pathable XXOXXOXX XXOXXOXX OOOSOOOO XXOXXOXX XXOXXOXX Lets say each X or O is 1/4 the size of a farm. If the unit is a pesant, he should be able to go there. If the unit is a paladin / other hero, they should NOT, because they cant actually FIT there. But if you just check with an item which can fit there, then the largest part of checking if the ground is pathable is lost, because units of larger-then-items collision size will invalidate the system in such an instance. Unless im missing something. (With me, thats always a possability )What i was saying with that is that it would still be possable to check with an item, but for each point you check, you would have to check more and more point around the requested movement location inorder to find a pathable area. XXX XSO XOO you would have to find a space big enogh for a large unit around point S by individually checking each section. which is rather ineficient, even at such a small resolution. Edit: Heres what i've come up with: JASS:globals integer array udg_PathingUnits endglobals function CheckPathability takes real x, real y, integer pathing_type returns boolean local location l = Location( x, y ) local unit u = CreateUnitAtLoc( Player(15), udg_PathingUnits[pathing_type], l, 0.0 ) set x = GetUnitX(u) + x set y = GetUnitY(u) + y call RemoveUnit( u ) set u = null return x*x+y*y <= 100 endfunction function MoveUnitPathingSafe takes unit u, real x, real y, integer pathing_type returns boolean local location l if ( CheckPathability( x, y, pathing_type ) ) then set l = Location( x, y ) call SetUnitPositionLoc( u, l ) call RemoveLocation( l ) set l = null return TRUE endif return FALSE endfunction where udg_PathingUnits is an array of unit types set at map initialization. I haven't tested this yet, but from the testing i have done, this should work just fine. (but i may have made a mistake ^^') |
| 03-14-2007, 01:37 PM | #10 |
sure, you could even make an array of units 1-48 with different collision sizes... it depends on how much accuracy you want |
