• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] GetLastCastAbility

Level 31
Joined
Jul 10, 2007
Messages
6,306
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.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
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:
Level 31
Joined
Jul 10, 2007
Messages
6,306
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.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
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.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
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).
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
I LOVE, how Mag recommended me Table and now you are blaming me for using table. Blame him for recommending it :D

I think GetHandleId() is not that bad, Im not extreme speedfreak, I love speed but I dont mind if its 0.0001 second slower
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
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)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
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
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
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)
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
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.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
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.
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
Wait what? A TableArray of size 1? I know you used TableArray because you needed multiple in the past, but right now the entire purpose of the Table/Array/ is gone.. You could just as well use a regular Table
 
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.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
The problem with the If myTab[blabla] == 1 and not != 1 is because every unstored value has value off 0 so every spell will return 0
1 line :D the idea with one variable shortens the code by 4 lines at least :D
Ill check it asap tho
 
Level 4
Joined
Jan 27, 2010
Messages
133
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;
}
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,182
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 :(
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
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
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,182
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:
Top