• 🏆 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] Unit Type Filter

Level 7
Joined
Apr 30, 2011
Messages
359
JASS:
//========================================================================================
//      
//      Unit Type Filter
//      -*- overcold_ice -*-
//      
//     -[*] Requirements:
//          - JNGP
//          - latest version of JassHelper
//      
//     -[*] Optional Requirements:
//          - /*New*/Table
//              [url]http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/[/url]
//      
//          For your unit type filter needs
//      Provides all 27 types of UnitType filter to modify
//      Those types' filter can be disabled, set to true or false
//      If it's true, the filtered unit's IsUnitType value of it must be true also
//      to make the filter returns true
//      The same goes to false, both must be false to make the filter returns true
//      This will be ignored if the type is disabled
//      Each types is disabled by default, and false by default
//      
//     -[*] API:
//      
//      struct UnitTypeFilter extends array
//          static method create takes nothing returns UnitTypeFilter
//          method destroy takes nothing returns nothing
//              allocator/deallocator for the struct
//      
//          method enableFilter takes unittype UnitType, boolean Enabled returns nothing
//              enable/disable UnitTypeFilter of type UnitType
//          method setFilter takes unittype UnitType, boolean Flag returns nothing
//              set UnitTypeFilter of type UnitTypeFilterId to Flag
//              if it's true, the filtered unit's IsUnitType must be true also to make
//              the filter returns true
//              the same goes to false, both must returns false to make the filter returns
//              false
//          method doFilter takes unit FilteredUnit returns boolean
//              checks if every UnitTypes on the unit match the filter
//              if it matches the filter, returns true
//              otherwise, false
//      
//========================================================================================
library UnitTypeFilter requires optional /*New*/Table
    
    static if LIBRARY_Table then
        private module Init
            private static method onInit takes nothing returns nothing
                set .table = TableArray [8192]
            endmethod
        endmodule
    endif
    
    struct UnitTypeFilter extends array
        static if LIBRARY_Table then
            private static TableArray table
        else
            private static hashtable ht = InitHashtable()
        endif
        
        private static integer c
        private        integer r
        
        static method create takes nothing returns thistype
            local thistype this = thistype(0).r
            
            if this == 0 then
                set .c   = .c + 1
                set this = .c
            else
                set thistype(0).r = this.r
            endif
            
            return this
        endmethod
        
        method enableFilter takes unittype f, boolean e returns nothing
            static if LIBRARY_Table then
                set .table [this].boolean [-GetHandleId(f)] = e
            else
                call SaveBoolean(.ht, this, -GetHandleId(f), e)
            endif
        endmethod
        method setFilter takes unittype f, boolean b returns nothing
            static if LIBRARY_Table then
                set .table [this].boolean [GetHandleId(f)] = b
            else
                call SaveBoolean(.ht, this, GetHandleId(f), b)
            endif
        endmethod
        
        method doFilter takes unit u returns boolean
            local unittype ut
            local integer  id
            local integer  i  = 0
            
            loop
                set ut = ConvertUnitType(i)
                set id = GetHandleId(ut)
                
                static if LIBRARY_Table then
                    if .table [this].boolean [-id] then
                        if IsUnitType(u, ut) != .table [this].boolean [id] then
                            set ut = null
                            
                            return false
                        endif
                    endif
                else
                    if LoadBoolean(.ht, this, -id) then
                        if IsUnitType(u, ut) != LoadBoolean(.ht, this, id) then
                            set ut = null
                            
                            return false
                        endif
                    endif
                endif
                
                exitwhen i == 26
                set i = i + 1
            endloop
            
            set ut = null
            
            return true
        endmethod
        
        method destroy takes nothing returns nothing
            static if LIBRARY_Table then
                call .table [this].flush()
            else
                call FlushChildHashtable(.ht, this)
            endif
            
            set this.r        = thistype(0).r
            set thistype(0).r = this
        endmethod
    endstruct
endlibrary
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
The bitFilter requirement is superfluous, and overall this resource reminds me of some of the features of CustomFilter by Anachron.

My opinion is that it would take as much, if not more, work to use this than is worth it. Not to mention it's a slower approach both in implementation and execution (learning curve and in-game processing).

You might get better results writing a tutorial explaining some good filters to use. I honestly don't see the real value in this resource. You can also program it to not require constant integers, if you use the handle ID's of the unit types directly.

JASS:
    //unittype's are 0-26, so you can just use GetHandleId whenever you need an index, instead of referencing the constant.
    constant unittype UNIT_TYPE_HERO                        = ConvertUnitType(0)
    constant unittype UNIT_TYPE_DEAD                        = ConvertUnitType(1)
    constant unittype UNIT_TYPE_STRUCTURE                   = ConvertUnitType(2)

    constant unittype UNIT_TYPE_FLYING                      = ConvertUnitType(3)
    constant unittype UNIT_TYPE_GROUND                      = ConvertUnitType(4)

    constant unittype UNIT_TYPE_ATTACKS_FLYING              = ConvertUnitType(5)
    constant unittype UNIT_TYPE_ATTACKS_GROUND              = ConvertUnitType(6)

    constant unittype UNIT_TYPE_MELEE_ATTACKER              = ConvertUnitType(7)
    constant unittype UNIT_TYPE_RANGED_ATTACKER             = ConvertUnitType(8)

    constant unittype UNIT_TYPE_GIANT                       = ConvertUnitType(9)
    constant unittype UNIT_TYPE_SUMMONED                    = ConvertUnitType(10)
    constant unittype UNIT_TYPE_STUNNED                     = ConvertUnitType(11)
    constant unittype UNIT_TYPE_PLAGUED                     = ConvertUnitType(12)
    constant unittype UNIT_TYPE_SNARED                      = ConvertUnitType(13)

    constant unittype UNIT_TYPE_UNDEAD                      = ConvertUnitType(14)
    constant unittype UNIT_TYPE_MECHANICAL                  = ConvertUnitType(15)
    constant unittype UNIT_TYPE_PEON                        = ConvertUnitType(16)
    constant unittype UNIT_TYPE_SAPPER                      = ConvertUnitType(17)
    constant unittype UNIT_TYPE_TOWNHALL                    = ConvertUnitType(18)    
    constant unittype UNIT_TYPE_ANCIENT                     = ConvertUnitType(19)
    
    constant unittype UNIT_TYPE_TAUREN                      = ConvertUnitType(20)
    constant unittype UNIT_TYPE_POISONED                    = ConvertUnitType(21)
    constant unittype UNIT_TYPE_POLYMORPHED                 = ConvertUnitType(22)
    constant unittype UNIT_TYPE_SLEEPING                    = ConvertUnitType(23)
    constant unittype UNIT_TYPE_RESISTANT                   = ConvertUnitType(24)
    constant unittype UNIT_TYPE_ETHEREAL                    = ConvertUnitType(25)
    constant unittype UNIT_TYPE_MAGIC_IMMUNE                = ConvertUnitType(26)
 
Level 7
Joined
Apr 30, 2011
Messages
359
will this work:
local unittype ut = ConvertUnitType(0)
local integer id = GetHandleId(ut)

and how can i make those HandleIds into formatted integers like this: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, . . . ?

and what are HandleIds' value exactly?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
What is the difference between enableFilter and setFilter?

Anyway, where's the demo map, the demo script, and the practical application? It looks like you want the user to call the function for each unit type to filter, resulting in something far less efficient than simply calling IsUnitType a few times and also far less intuitive.

I will schedule this for graveyarding.
 
Top