• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[Snippet] GetLastCastAbility

It's not fixed

JASS:
            set myTab[0].real[GetHandleId(lastCastAbilityUnit)] = lastCastAbilityX
            set myTab[1].real[GetHandleId(lastCastAbilityUnit)] = lastCastAbilityY
            set myTab[2][GetHandleId(lastCastAbilityUnit)] = lastCastAbility
            set myTab[3].unit[GetHandleId(lastCastAbilityUnit)] = lastCastAbilityTarget

I still see that and Table. You should be using GetUnitUserData.

edit
You should also store data for only indexed units, so you'll have to actually show a unit indexer as a requirement and have an IsUnitIndexed check ; ). You should ignore all units that aren't indexed, treat them as null.
 
Nestharus, he fixed the things in quote, I didnt fix this as I did not have time for it.
Edit: Ive fixed the problem when unit dies.
Also I tried to implement support for Unit Indexing systems but its impossible because you wont be able to filter/unfilter then.
The reason being the size of array vs the raw code size of abilities.
Sure I can do for things like
JASS:
function LastCastAddFilter takes integer abilcode returns nothing
    return indexbanned[abilcode - 0x41000000] = 0
endfunction

function LastCastRemoveFilter takes integer abilcode returns nothing
    return indexbanned[abilcode - 0x41000000] = 1
endfunction
but the difference between 'A000' and 'ZZZZ' is 425351770 and its still quite off the 8191 limit dont you think? :D
Also abilities can have codes like 'AHgt' which is 1095264116, which is already 4745076 higher then the limit.
Also I cant substract anymore because if you was aboout to ban ability 'A000' then you would get negative value in array and thats never good.

ALSO, why would I use UnitIndexer when It works perfectly fine with Table and Handles(after this little update)
 
Last edited:
Bro, my bad, use Table to ban/unban the abils, but use a unit index (GetUnitUserData) for array sets.

ALSO, why would I use UnitIndexer when It works perfectly fine with Table and Handles(after this little update)

Table read is user slow compared to array read, table write is also uber slow compared to array write. get handle id is crazy slow compared to get unit user data.
 
http://www.thehelper.net/threads/getunituserdata-vs-loadinteger.127233/ (for empty table, as table fills, it gets much slower).

As for GetHandleId, it is a bit faster than H2I, and H2I was known to be about one of the absolute slowest operations you could do.

I'm only asking for GetHandleId vs GetUnitUserData, hence my quote, i already know in which scale an hashtable is slower comparing to an array.
I'm really doubtful about wc3 myths without any proof, as it is often completely wrong.
 
I'm really doubtfull about wc3 myths without any proof.

H2I was benched long, long ago, and when the new patch first came out, GetHandleId was benched compared to H2I. I can't find the benchmarks for them as they are extremely old, but I remember the big discussion on how GetHandleId was only a little bit faster than H2I and I remember H2I as being one of the slowest possible operations you can do (if not the very slowest).
 
I'm not going to believe it without any test code, it's really easy to fuck up a benchmark.
And frankly i don't care to test it myself, i just hate random statements.

It was tested at wc3c under major scrutiny similar to Anitarf's benchmark thread. SC2 was also benched compared to wc3 on wc3c, I just can't find the threads : \.
 
Structs are only arrays and functions, so it's not necessary to use structs for anything. Though by using them you might be able to make your code look a hella lot better, that's why we're using them. After all, OO > Functional (I'm talking in general though, I haven't seen your code since its first release lol)
 
wtf is this

JASS:
            /*
            *   to register the units to unit indexer
            */
            
            local rect r = GetWorldBounds()
            local real x
            local group g = CreateGroup()
            local unit first
            call GroupEnumUnitsInRange(g, 0., 0., 10000., null)
            loop
                set first = FirstOfGroup(g)
                exitwhen first == null
                call GroupRemoveUnit(g, first)
                set x = GetUnitX(first)
                call SetUnitX(first, GetRectMaxX(r))
                call SetUnitX(first, x)
            endloop

That is completely pointless code. UnitIndexer registers units flawlessly. Let it do its job.

Also, you aren't clearing out data when a unit is deindexed. Because you don't do this, a unit could have invalid last cast data from a unit that used to have that index.

unit A casts spell War Stomp on index 3000
unit A is removed
unit B is created with index 3000
unit B last cast is War Stomp as it was never cleared
 
well, wonder why there is
JASS:
//***************************************************************
//***************************************************************

    //When unit dies, null the numbers
    
    private function DiesFunc takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local integer i = GetUnitUserData(u)
        set lastCastUnitAbility[i] = 0
        set lastCastUnitTarget[i] = null
        set lastCastUnitX[i] = 0
        set lastCastUnitY[i] = 0
        set u = null
        return false
    endfunction

    private module DiesInit
        private static method onInit takes nothing returns nothing
            local region re = CreateRegion()
            local trigger t = CreateTrigger()
            local rect r = GetWorldBounds()
            local integer i = 0
            call RegionAddRect(re, r)
            call TriggerRegisterEnterRegion(t, re, null)
            
            //Could have used RegisterPlayerUnitEvent for this but you dont choose which trigger you want
            //to register it into
            
            loop
                call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_DEATH, null)
                exitwhen i == 11
                set i = i + 1
            endloop
            call TriggerAddCondition(t, Condition(function DiesFunc))
            set r = null
            set re = null
            set t = null
        endmethod
    endmodule

    private struct DIES
        implement DiesInit
    endstruct
Also I wasnt sure if he does it autaomatically so Ive added it just to be sure :D If it does then Ill just remove it(and it cleary does when you point into that)
 
hmm...Nes when I think about it right now, why would UnitIndexer use worldbounds when it wont do that move unit hmm...silly me

Mag...Im nulling the values when unit dies or leaves World Bounds, couldnt find a way to make the UnitIndexer deindex it, tryed call RegisterUnitIndexEvent(Condition(function DiesFunc), UnitIndexer.DEINDEX) and it fired yes but the UnitUserData was already 0 and it made it impossible to null.
 
It looks much better ; ).

However, GetUnitUserData shouldn't be 0. I never set it to 0 ; p. I actually use GetUnitUserData in the system and that is what GetIndexedUnitId is set to...

If it works with GetIndexedUnitId and not with GetUnitUserData, something was wrong with ur code because they are both the same. Well, GetIndexedUnitId does return a variable, but that variable was set to GetUnitUserData.
 
You don't need the local unit u in your deindex function.


Also, it would be better to add a lastCastAbilityUnitCaster array, and remove all those non-array variables.

Replace them with one variable that stores the unit index of the unit to last cast a spell, and when you want to get the values of the last cast ability, just look them up from the array while using the unit index you stored as an array index.

Also, instead of checking if the value in the table is 1 and returning, how about checking if the value is not 1, then running all the code.
It shortens your function by a line.
 
You don't need to declare variables private in a zinc library, they are private by default...

(and remember you can group them together if you want to change visibility)
JASS:
public {
     integer hiHo = 32;
     boolean kudso = false;
}
 
nothing personal but this system or whatever you want to call it seems odd to me, most thing mentioned in the "you can do this" can be stored in very simple variables im sure you know how so I don't need to show which. There is a few features that would be a little harder to code but id just use a hashtable for that rather than this system since I got to import a unitindexer and something called table.

I hope i'm not too evil :(
 
no lol, but well, you dont need to waste the 10-15 minutes(maybe more, if you have troubles as I usually do :D) writing it by your own but you can download it.
If you dont want to use it, its fine, I dont force anyone to do so, its here for lazy asses
at the end, if I wanted I could make myself unit indexer too but why would I spend 2 hours or so doing it when I can come here to page 2 topic Unit indexer, download the map download the script copy the spell change Id and Im done :D but I understand that you see its uselessness
 
I can understand that its useful for people it's the additional things that I need to download if I want a system or a lib in Vjass cases it says you only need those 4 other libs it just makes me angry that they can't use a normal trigger so I can download the thing I want and nothing else. but to the topic again, the idea for this is good but id use a function who do that shiet for me without any unit indexers :)
 
Last edited:
Back
Top