| 02-26-2004, 11:28 PM | #1 |
Here is my little JASS script to find the closest unit, and it works beautifully, the first time. For some reason it is very very spotty after the first use, sometimes it does return sometimes it doesn't. Can anyone help me figure out why its not returning properly? Code:
function GetClosestUnit takes unit who, group pool returns unit
local location temploc = GetUnitLoc(who)
local real x = 0
local real distance = 9999999.0
local location temploc01 = null
local unit u = null
local unit actualunit = null
local real distance01 = 0
call GroupRemoveGroup(pool, GetUnitsOfPlayerAll(GetOwningPlayer(who)))
call GroupRemoveUnitSimple(who, pool)
loop
set u = FirstOfGroup(pool)
exitwhen u == null
set temploc01 = GetUnitLoc(u)
call GroupRemoveUnitSimple(u, pool)
set x = DistanceBetweenPoints(temploc01,temploc)
set distance01 = x
if (distance01 < distance) then
set distance = x
set actualunit = u
endif
call RemoveLocation(temploc01)
set temploc01 = null
set u = null
endloop
call DestroyGroup(pool)
call RemoveLocation(temploc)
set temploc = null
set distance = 9999999.0
set pool = null
return actualunit
endfunction[edit] oh and how does FirstOfGroup() vary from GroupPickRandomUnit()? |
| 02-27-2004, 12:34 AM | #2 |
FirstOfGroup is a native from common.j, the otherone is probably from Blizzard.j. When I handle groups of units I usually use these functions form common.j. Code:
native CreateGroup takes nothing returns group native DestroyGroup takes group whichGroup returns nothing native GroupAddUnit takes group whichGroup, unit whichUnit returns nothing native GroupRemoveUnit takes group whichGroup, unit whichUnit returns nothing native GroupClear takes group whichGroup returns nothing native FirstOfGroup takes group whichGroup returns unit FirstOfGroup probably returns the same unit if called multiple times, GroupPickRandomUnit probably returns different units each time. |
| 02-27-2004, 12:41 AM | #3 |
FirstOfGroup is consistent, GroupPickRandomUnit is not. That said, the reason your script is probably failing is because there's a maximum amount of time War3 will let a trigger run before it assumes the trigger has fallen into an infinite loop and kills it. Your function, being rather cpu intensive, probably goes over it. However, sing FirstOfGroup would optimize your function a ton, so I'd try it. |
| 02-27-2004, 02:23 AM | #4 |
Thanks dataangel, that really helped clear it up. I fixed it up above. There is one thing that really mistyfies me though, it finds the closest unit in a fraction of a second, but it won't work again unit about 2 seconds after it has been used. It would seem that after it had found the closest unit, wouldn't it take a fraction of a second to run the rest? [edit]Umm, you know the filter units owned by triggering unit part? For some reason it isn't working and I can't figure out why. [edit#2]I optimized the function and got it down to 1 function now, but it still has the same problem of about a 2 second cooldown. |
| 02-27-2004, 10:12 AM | #5 |
I can only see a few qualms: 1. This function is not neeeded: call GroupRemoveUnitSimple(who, pool) 2. You're setting the Distance between the units to a integer value before setting it to real value, thus, losing some precision (btw, why didn't you just set it directly to the real variable?). However, you may have some wacky reason for this. 3. You are Destroying the Group that is passed to this....this is not reccomended, atleast if you wanna release this function, as then if a user passes to it some group he's using for other things, it gets destroyed. So, unless this is only for your private use and you know about this, I would reccomend you to only Destroy the group if some boolean is set to true (like bj_wantdestroygroup or sumtin) However, i can't see why it wouldn't work the second time....unless you're reusing the same groups, which you Destroy after the first time. Cubasis |
| 02-27-2004, 09:19 PM | #6 |
1. Sorry about that mistake. I imported it into WC last night to see if it had improved performance, and it gave me the integer != real bit, but it was late so I forgot to change the integer to a real here. 2. That function is needed or else the the unit will always be picked. Now if the person passing args was smart and removed him before hand then it won't matter, but if you just pass GetUnitsWithinRangeOfLocAll() then you have a problem. 3. I fixed this by creating a new local group. But after all of this, for some stupid reason, it still takes about 3 seconds before it will work again. It will always work, but it takes a long time to cooldown. Its stupid. It seems to have some other oddities about it. It seems to 'fire' quicker when I am facing the closest unit, or when I am very close to the unit. The thing that doesn't make sense is, it find the closest unit nearly instantly, but why does it take so long to be called again? The rest of the trigger should be run in a matter of nanoseconds compared to finding the actual unit. |
| 02-27-2004, 11:01 PM | #7 |
I finally found the answer!!!! Okay, so it is not something to do with my function, it is blizzards fault. I was testing the map unsing heros for some reason and then exploding the closest one. Well, after multiple debugging tests I figured out what the problem is. The heros aren't really gone when you think they are. They last there for about 3 more seconds, so I was using explode on the heros thinking it would immediatly remove them, however it still said that the exploded hero was the closest one for about 3 seconds. My function runs so fast I don't even notice it. I tested it with normal units now, and it runs like a beauty. Does anyone know how to work around the dumb hero thing? |
| 02-27-2004, 11:37 PM | #8 |
use remove unit. |
| 02-28-2004, 09:50 PM | #9 |
Right... that would work in some cases, but since it is going to be a function used in every instance possible where you need it. If there was a hero killed in the area and then you tried to use this, it would return the dying hero. Same way if a unit is killed not exploded, as long as his corpse is there it returns him. I need to find a way around this. Nevermind about my last post, I figured it out. Thanks for helping me guys. |
