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

[Snippet] UnitInRangeEvent

Level 31
Joined
Jul 10, 2007
Messages
6,306
out of range event can be a separate resource and also depends on what you are doing

out of range event for auras can be optimized to 1 trigger rather than 2 for example


Also, the pros is the access to source unit, cleanup and trigger merging ; P


Don't think that there are any cons


Out of range event is easiest with 1 timer per unit in range and an if statement checking if the unit is still in range. This can be achieved with Timer Tools.
 
I'd like to see some benchmarks of this versus a periodic group enum with null filter, with a FirstOfGroup loop, every .10 seconds (because that is how often this event checks anyway).

It's going to be a trillion times better on RAM at worst. And it will support the out-of range event which an aura would need anyway, so a true aura is not going to lose any overhead, save for adding this overkill system into the map.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
You aren't serious are you...


I'm not even going to bother benchmarking that. The group enumeration is going to lose in a very major way >.<.


you never do a group enum in a timer >.<.



If you don't understand why, think of 1 evaluated boolean expression for every single unit within range on a timer as compared to letting the c++ handle it in something like a quad tree. The group enumeration loses hands down -.-.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
They likely handle it via a quad tree >.>. That's the only sane way to do it.


Read my edit. You are talking about c++ code vs 1 evaluated boolean expression for every single unit. Which one do you think is going to win? Tons of evaluated boolean expressions or the c++ code. Experience dictates that the c++ code will win.



Bribe, you are seriously comparing c++ code to wc3 trigger evaluations...
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I'm saying that you don't have to do group enumerations to detect out of range event >.>.


This by itself is not useless at all...


Look at what I did with AuraStruct. Did I do group enumerations in there to detect out of range? no >.>. Also, the out of range depended on many more factors than just range >.>.


Out of range can and should be an entirely separate resource.
 
Now that I have seen the implementation in AuraStruct, I can see the method
to the madness here. While I can't really bring myself to believe there is any
purpose for this library outside of auras, the execution of the code here is
pretty tight and I like the way you convert the range to an integer. Although
the map max range is way less than 4,294,967.294 ;)

I hope I am doing the right thing here by approving this. It is just so hard to
tell the way this is set up but it looks mostly right.
 
You talk about group enums like they are going to crash the entire map. I imagine you might have a few dozen auras at the most, and a few dozen group enums every 0.03125 seconds doesn't even affect the performance any of my maps, and I have the crappiest computer of anyone here.

Not to mention with an event like this you'd only run it every 0.3 seconds like you have for your aura system, so what would be the point of talking about efficiency then?
 
600 units on the map already lags my map just by their existence ;)

A group enum in a short range like 900-1200 is going to pick up a few dozen units at most, which is not going to crash a map. Maybe I should build a map with lots of units and about 20 0.3-frequency group enums, using FirstOfGroup loops, not the filter, because filters are slow, and there is going to be lots of room for other things because the efficiency there is extraordinary.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
hm... that wouldn't be too bad I suppose ; ), but still not as good as using UnitInRangeEvent when you can : P.

JASS:
    GroupEnum(group) //null filter
    loop
        set unit = FirstOfGroup(group)
        exitwhen null == unit
        call GroupRemoveUnit(unit)
    endloop

not too bad at all


and GroupEnum with a filter was benched against a first of group loop right? Also, try benching first of group against a linked list loop.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I can tell you by experience that this kind of loop has a serious "bug" (because how groups are internally handled).

Make sure there are several times the same unit rawcode (or something like that) in your group.
Now use your loop, it will never end as FirstOfGroup will sooner or later always return the same unit.


Ok, i was the bug ...

http://www.hiveworkshop.com/forums/2024255-post24.html
 
Last edited:
I can tell you by experience that this kind of loop has a serious "bug" (because how groups are internally handled).

Make sure there are several times the same unit rawcode (or something like that) in your group.
Now use your loop, it will never end as FirstOfGroup will sooner or later always return the same unit.
Huh? Never had this problem when I used FirstOfGroup loops.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I'm pretty sure (but it was some years ago, maybe it's fixed ?!)

EDIT : I've tried several things i can't reproduce the bug, maybe it's fixed, maybe i was drunk, maybe not.

There is still the ghost problem (nothing related to the unit, just removed units) though, ofc it's only for groups that you keep during time :

JASS:
globals
    group Group = CreateGroup()
endglobals

//===========================================================================
function F takes nothing returns nothing
    local unit u = FirstOfGroup(Group)
    call BJDebugMsg("run")
    loop
    exitwhen u == null
        call BJDebugMsg(I2S(GetHandleId(u)))
        call GroupRemoveUnit(Group,u)
    set u = FirstOfGroup(Group)
    endloop
    set u = null

endfunction

function InitTrig_Test takes nothing returns nothing
    
    call GroupAddUnit(Group,CreateUnit(Player(0),'hpea',0,0,0))
    call GroupAddUnit(Group,CreateUnit(Player(0),'hfoo',0,0,0))
    call GroupAddUnit(Group,CreateUnit(Player(0),'Hpal',0,0,0))
    
    call TimerStart(CreateTimer(),1,false,function F)
    call GroupEnumUnitsInRect(Group,GetWorldBounds(),null)
    
    //call RemoveUnit(FirstOfGroup(Group))
endfunction

Test it, it works fine.
Now uncomment the last line : yes the first FirstOfGroup returns a null unit.

EDIT EDIT : Ok, memory is back, the bug was me because of a lame group approach ...

I attempt a naive approach few years ago, i expected that added/removed unit with the native Group functions added/removed the units like a queue (first in, first out).
It is true in special cases, but that doesn't make it as a rule, i just didn't (and don't) know how groups are internally handled.

JASS:
globals
    group Group = CreateGroup()
endglobals

//===========================================================================
function F takes nothing returns nothing
    local unit first = FirstOfGroup(Group)
    local unit u = first

    if first == null then
        return
    endif
    loop
        call BJDebugMsg(I2S(GetHandleId(u)))
        call GroupRemoveUnit(Group,u)
        call GroupAddUnit(Group,u)
    set u = FirstOfGroup(Group)
    exitwhen u == first
    endloop
    set u = null
    set first = null

endfunction

function InitTrig_Test takes nothing returns nothing
    
    call GroupAddUnit(Group,CreateUnit(Player(0),'hpea',0,0,0))
    call GroupAddUnit(Group,CreateUnit(Player(0),'hfoo',0,0,0))
    //call GroupAddUnit(Group,CreateUnit(Player(0),'hpea',0,0,0))
    
    call TimerStart(CreateTimer(),0,false,function F)
    call GroupEnumUnitsInRect(Group,GetWorldBounds(),null)
    
endfunction

It works, but if you uncomment the line it won't (it also won't work with a not already used unit rawcode, i suppose i was "lucky" when i did my old test)
 
Last edited:
Level 7
Joined
Dec 3, 2006
Messages
339
Oh wow; interesting that such a bug exists this is the first i've heard of it. Guess i'll have to use no collision rather than using the ghost ability then for things. :D


EDIT: Man, I really gotta stop skimming threads. lol.
 
Last edited:
Top