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

The Filtering System

Level 4
Joined
Jul 4, 2012
Messages
78
then you are working on it at the moment? i remember someone said something like that before but we rejected it because we concluded that it will sacrifice a lot of performance.
but i trust you. go on and let us see what comes out :) i'm counting on you Bribe xD
and by 'arrow' i think you meant 'array', yeah? than you.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
very useful, but I have some :)

I think you don't need to do those checks when filter == 0, but the problem is only stupidities that would input 0 integer. But since you write /* + if UnitFilter(Target,null,0) then in the description, and we must consider any possibilities, so it's not stupid to fix that little thing

and I don't get why you use hexadecimal instead of normal integer (decimal)

and how about this concept:
JASS:
constant integer ALIVE = 1
constant integer NON_ALIVE = -1
so input will be 0, then if you fix minor thing I have mentoined above we don't need to uselessly do those checks anymore

I'm sorry if I do some mistakes because I have fking tootache while reading the code :ugly:

EDIT:
and how about using loop to shorten the code?
 
Level 4
Joined
Jul 4, 2012
Messages
78
very useful, but I have some :)

I think you don't need to do those checks when filter == 0, but the problem is only stupidities that would input 0 integer. But since you write /* + if UnitFilter(Target,null,0) then in the description, and we must consider any possibilities, so it's not stupid to fix that little thing

and I don't get why you use hexadecimal instead of normal integer (decimal)

and how about this concept:
JASS:
constant integer ALIVE = 1
constant integer NON_ALIVE = -1
so input will be 0, then if you fix minor thing I have mentoined above we don't need to uselessly do those checks anymore

I'm sorry if I do some mistakes because I have fking tootache while reading the code :ugly:

EDIT:
and how about using loop to shorten the code?

When you define some filters via giving a specific hex number, this system returns you a group/unit which has the units not fitting in those filters removed/rejected, so obviously when no filter is given ( filter = 0 ), all units will pass. if i didn't make the system this way, users had to define an special filter that when given, it made all units pass the filtering, but it is ok now. and by the way, users are not supposed to define negative hex as filters.... this WILL cause conflicts :/

no you don't made any mistakes, you gave some opinions and they were good. ty

about using loop; i, Nestharus and Bribe tried to make it that way, but it is nearly impossible or if its possible, it is not efficient or even worth it, the filters don't use same natives.

i'm currently very busy in university, maybe when the pressure dropped off a bit, i will consider what you said and update it if your sayings were useful in making easier API.

Thank you.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
and I don't get why you use hexadecimal instead of normal integer (decimal)

Thats very common for flags. Why? Because it makes your life easier. With decimal values you would have to calculate the next power of two when adding a new flag:

1, 2, 4, 8, 16, 32, 64, 128, etc.

With hex numbers you have:

1, 2, 4, 8, 10, 20, 40, 80, 100, 200, etc.

You see? With hex numbers you just count 1, 2, 4, 8 then you just attach a zero to the number and start again from 1.

Less thinking, less errors, better readability.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
this gives them a huge range of modifications and configurations
I don't think so, it just make filtration become more elegant, simple, and easier.. For the coder, not for the GUI ers :p except they are not too lazy to learn how to use this library correctly, and maybe
but simply i didn't said that in API :) i will add it :)
is not a really good decision, since most jass coder just understand how to use it because it's easy. and almost all user (GUIers) wont open the requirements (in this case, is your library)

Idk know is that my statement about usability of this library is good or not, since it's very easy to learn and use this library (yes, perhaps this will become a breakthrough, that would be recommended in almost spell in thw :thumbs_up:)

Edit:
I'm sorry, I will take back all my words about the useability, I think it's just so much easier learning your filtration method than normal Jass method :p
and the pproblem is always on GUIers themselves, just want to mention the fact,, Almost all GUIers is very lazy just to read one function or more, or even learn it..
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
The code doesn't compile. Here is the fixed one:
JASS:
    library FilteringSystem /* v3.4.0 */  

    /*
    ************************************************************************************************************************
    *        Filtering System's API v3.4.0
    *        by The Wrecker
    *
    *        Credits:
    *               - God : God supports anyone.
    *               - Nestharus : Algorithm of this system is
    *                 shaped in time by ideas of him, and as you
    *                 see, the algorithm is perfect; many other
    *                 thanks to him for many other useful hints.
    *                 THIS SYSTEM OWES ITS QUALITY TO Nestharus.
    *               - Magtheridon96 : His hints made the way
    *                 to create this system easier and more
    *                 efficient, many thanks to him. His
    *                 advocacy for this system was awesome:
    *                 [url]http://www.hiveworkshop.com/forums/jass-resources-412/filtering-system-240887/index7.html#post2471786[/url]
    *
    *                    by TheWrecker
    *
    *        [url]http://www.hiveworkshop.com/forums/jass-resources-412/filtering-system-240887/[/url]
    *
    *    Contents:
    *
    *        - Functions
    *        - How to use Filters
    *        - How to use Filtering System
    *        - Settings
    *        - Full Example
    *        - Side Functions
    *        - Constants (filters)
    *
    ************************************************************************************************************************
    *    Functions:
    *
    *        - function UnitFilter takes unit whichUnit, player whichPlayer, integer filter returns boolean
    *
    *            + It will check if 'whichUnit' meets given conditions or not.
    *            + 'whichPlayer' is only required when Alliance and Visibility filters
    *              are applied and must be passed 'null' when not using Alliance and
    *              Visibility filters.
    *            + 'filter' is an integer explained in section "How to use Filters".
    *   
    *        - function ItemFilter takes item whichItem, integer filter returns boolean
    *
    *            + It checks if 'whichItem' passes given filters or not.
    *            + 'filter' is an integer explained in section "How to use Filters".
    *
    *        - function PlayerFilter takes player whichPlayer, player otherPlayer, integer filter returns boolean
    *
    *            + It checks whether 'whichPlayer' meets given filters or not.
    *            + 'otherPlayer' is the other player used to check two-player related
    *              filters: Shared Units, Shared Vision, Alliance.
    *              if not using the above filters, you can pass 'null' as 'otherPlayer'.
    *            + 'filter' is an integer explained in section "How to use Filters".
    *
    ************************************************************************************************************************
    *    How to use Filters:
    *
    *        - 'filter' is an hexadecimal integer which is made like this:
    *            Filter1 + Filter2 + Filter3 + ...
    *                + You don't have to do any mathematics, only type your
    *                  desired filters' names like above.
    *
    *        - Filters in Filtring System are in 3 groups: Unit, Item, Player.
    *            + Use each group only with its related filtering function.
    *
    *        - Filter rules are as below:
    *            <Filter1 and Filter2 are opposites like Dead and Alive>
    *            + Filter1: Units matching it will pass.
    *            + Filter1 + Filter 2: NO UNIT WILL PASS.
    *            + nothing: All units will pass.
    *            + If you didn't get what above means take a look to section
    *              "Full Example"
    *
    ************************************************************************************************************************
    *    How to use Filtering System:
    *
    *        - vJass and Jass:
    *            + A simple line:
    *                if [Unit/Player/Item]Filter(argument1,argument2[if exists],'filter') then
    *                //Scripts
    *                endif
    *
    *        - GUI:
    *            + A Custom Script (New Action -> General -> Custom Script) line:
    *                Custom Script : if [Unit/Player/Item]Filter(argument1,argument2[if exists],'filter') then
    *                //Scripts
    *                Custom Script : endif
    *
    ************************************************************************************************************************
    *    Settings:
    *
    *        - Ward and Dummy classificators:
    *
    * */globals/*
    *   
    *           CONFIGURABLE PART
    *   
    *     */
            constant integer ABILITY_WARD_CLASSIFIER = 'Alit'/*
    *       This system checks for a spell to realize the fact that a unit is
    *       a ward or not, because perhaps you add a ward classification to a unit
    *       to remove its spell icons, but that unit is not really a ward, so instead
    *       of checking for classification we use a spell to define ward classification;
    *       change it to your desired spell or leave it as it is.
    *       
    *     */
            constant integer ABILITY_DUMMY_CLASSIFIER = 'Aloc'/*
    *       This system checks for a spell to realize the fact that a unit is
    *       a dummy or not, change this to your desired spell or leave it as it is, note
    *       that this system doesn't do anything about dummies, in fact when it finds this
    *       spell in a unit, it completely ignores that unit and that unit will not pass
    *       the filtering, so if you want a specific unit to not pass this filtering, add
    *       this spell to it.
    *       
    *           END OF CONFIGURABLE PART
    *
    ************************************************************************************************************************
    *    Full Example:
    *
    *        - Alive, enemy ranged heroes:
    *            + if UnitFilter(Target,Caster,FS_UNIT_ALIVE + FS_UNIT_ENEMY + FS_UNIT_HERO + FS_UNIT_RANGED) then
    *            + NOTE : ORDER OF FILTERS IS NOT IMPORTANT.
    *
    *        - Non-Summoned undead units:
    *            + if UnitFilter(Target,null,FS_UNIT_UNDEAD + FS_UNIT_NON_SUMMONED) then
    *
    *        - All units:
    *            + if UnitFilter(Target,null,0) then
    *            + Pay attention to zero (0).
    *
    *        - No unit:
    *            + if UnitFilter(Target,null,FS_UNIT_ALIVE + FS_UNIT_DEAD) then
    *            + 'FS_UNIT_HERO + FS_UNIT_NON_HERO','FS_UNIT_ALLY + FS_UNIT_ENEMY' and
    *              other opposites can be placed as 'FS_UNIT_ALIVE + FS_UNIT_DEAD'.
    *
    *        - Ally computer players with shared vision:
    *            + if PlayerFilter(Player1,Player2,FS_PLAYER_ALLY + FS_PLAYER_COMPUTER + FS_PLAYER_VISION) then
    *
    *        - Sellable, Campaign class items which are not owned:
    *            + if ItemFilter(Item,FS_ITEM_SELLABLE + FS_ITEM_CAMPAIGN + FS_ITEM_NON_OWNED) then
    *
    ************************************************************************************************************************
    *    Side Functions:
    *
    *        Because of the unique algorithm of this system, there are unpredicted functions
    *        that this system can have, one of them is known and others may be found later.
    *
    *            - Mixing the filters into single filter (Constraints):
    *              (found by Magtheridon96)
    *
    *                This is the method of mixing some filters and converting them into a
    *                single filter to use that single filter instead of using many filters
    *                more and more again. An example should show you the way:
    *               
    *                    integer USUAL = FS_UNIT_ALIVE + FS_UNIT_ENEMY + FS_UNIT_ORGANIC
    *
    *                this way, you will type in 'USUAL' everytime your filter contain these
    *                three filters instead of typing all three of them.
    *
    *                    + Be sure that no filter is repeated two times in a single
    *                      constraint.
    *                    + If sum of some constraints contain repeated filters, be sure
    *                      to substract that filter until there is only one filter of that
    *                      type left, an example is needed:
    *
    *                          USUAL = FS_UNIT_ALIVE + FS_UNIT_ENEMY + FS_UNIT_ORGANIC
    *                          HERO_2 = FS_UNIT_ALIVE + FS_UNIT_ENEMY + FS_UNIT_IMMUNE
    *                          UNDEAD_9 = FS_UNIT_ALIVE + FS_UNIT_UNDEAD
    *                          USUAL_HERO = USUAL + FS_UNIT_HERO
    *
    *                          If you want to use USUAL + HERO_2 + UNDEAD_9, be sure to
    *                          use it this way (FS_UNIT_ALIVE is repeated 3 times,
    *                          FS_UNIT_ENEMY is repeated 2 times):
    *                          USUAL + HERO_2 + UNDEAD_9 - 2*FS_UNIT_ALIVE - FS_UNIT_ENEMY
    *
    *                To use this method, you have to define your own constraints using
    *                this way:
    *
    *                    globals
    *                        constant integer CONSTRAINT_NAME = COND1 + COND2 + ...
    *                    endglobals
    *
    *                If you are GUI, you have to put these three lines in three adjacent
    *                Custom Script lines.
    *
    ************************************************************************************************************************
    *    Constants (filters):
    *        - These are the filters available:
    *
    *    FS_UNIT_ENEMY
    *    FS_UNIT_ALLY
    *    FS_UNIT_ALIVE
    *    FS_UNIT_DEAD
    *    FS_UNIT_ORGANIC
    *    FS_UNIT_STRUCTURE
    *    FS_UNIT_MECHANICAL
    *    FS_UNIT_HERO 
    *    FS_UNIT_NON_HERO
    *    FS_UNIT_IMMUNE        //magic immunity, ofcourse!
    *    FS_UNIT_NON_IMMUNE     
    *    FS_UNIT_SUMMONED       
    *    FS_UNIT_NON_SUMMONED     
    *    FS_UNIT_VISIBLE       
    *    FS_UNIT_INVISIBLE    
    *    FS_UNIT_WARD       
    *    FS_UNIT_NON_WARD   
    *    FS_UNIT_ANCIENT       
    *    FS_UNIT_NON_ANCIENT     
    *    FS_UNIT_GROUND         
    *    FS_UNIT_FLYING        
    *    FS_UNIT_MELEE         
    *    FS_UNIT_RANGED        
    *    FS_UNIT_UNDEAD 
    *    FS_UNIT_NON_UNDEAD
    *
    *    FS_ITEM_OWNED       
    *    FS_ITEM_NON_OWNED      
    *    FS_ITEM_RUNE        //includes runes, tomes, powerups, etc.
    *    FS_ITEM_NON_RUNE   
    *    FS_ITEM_SELLABLE     
    *    FS_ITEM_NON_SELLABLE    
    *    FS_ITEM_PAWNABLE        
    *    FS_ITEM_NON_PAWNABLE 
    *    FS_ITEM_PERMANENT    
    *    FS_ITEM_NON_PERMANENT  
    *    FS_ITEM_CHARGED       
    *    FS_ITEM_NON_CHARGED  
    *    FS_ITEM_POWERUP      
    *    FS_ITEM_NON_POWERUP  
    *    FS_ITEM_ARTIFACT    
    *    FS_ITEM_NON_ARTIFACT  
    *    FS_ITEM_PURCHASABLE     
    *    FS_ITEM_NON_PURCHASABLE  
    *    FS_ITEM_CAMPAIGN        
    *    FS_ITEM_NON_CAMPAIGN    
    *    FS_ITEM_MISC            
    *    FS_ITEM_NON_MISC       
    *    FS_ITEM_VISIBLE       
    *    FS_ITEM_HIDDEN
    *
    *    FS_PLAYER_ENEMY      
    *    FS_PLAYER_ALLY      
    *    FS_PLAYER_USER     
    *    FS_PLAYER_COMPUTER   
    *    FS_PLAYER_PLAYING   
    *    FS_PLAYER_LEFT     //also includes non-used slots.
    *    FS_PLAYER_NEUTRAL    
    *    FS_PLAYER_NON_NEUTRAL
    *    FS_PLAYER_VISION       //shared vision.
    *    FS_PLAYER_NON_VISION 
    *    FS_PLAYER_CONTROL        //shared unit control.
    *    FS_PLAYER_NON_CONTROL
    *
    ************************************************************************************************************************
    *                          -----END OF API-----
    */

            
            constant integer    FS_UNIT_ENEMY              = 0x1
            constant integer    FS_UNIT_ALLY               = 0x2
            constant integer    FS_UNIT_ALIVE              = 0x4
            constant integer    FS_UNIT_DEAD               = 0x8
            constant integer    FS_UNIT_ORGANIC            = 0x10
            constant integer    FS_UNIT_STRUCTURE          = 0x20
            constant integer    FS_UNIT_MECHANICAL         = 0x40
            constant integer    FS_UNIT_HERO               = 0x80
            constant integer    FS_UNIT_NON_HERO           = 0x100
            constant integer    FS_UNIT_IMMUNE             = 0x200
            constant integer    FS_UNIT_NON_IMMUNE         = 0x400
            constant integer    FS_UNIT_SUMMONED           = 0x800
            constant integer    FS_UNIT_NON_SUMMONED       = 0x1000
            constant integer    FS_UNIT_VISIBLE            = 0x2000
            constant integer    FS_UNIT_INVISIBLE          = 0x4000
            constant integer    FS_UNIT_WARD               = 0x8000
            constant integer    FS_UNIT_NON_WARD           = 0x10000
            constant integer    FS_UNIT_ANCIENT            = 0x20000
            constant integer    FS_UNIT_NON_ANCIENT        = 0x40000
            constant integer    FS_UNIT_GROUND             = 0x80000
            constant integer    FS_UNIT_FLYING             = 0x100000
            constant integer    FS_UNIT_MELEE              = 0x200000
            constant integer    FS_UNIT_RANGED             = 0x400000
            constant integer    FS_UNIT_UNDEAD             = 0x800000
            constant integer    FS_UNIT_NON_UNDEAD         = 0x1000000
            
            constant integer    FS_ITEM_OWNED              = 0x1
            constant integer    FS_ITEM_NON_OWNED          = 0x2
            constant integer    FS_ITEM_RUNE               = 0x4
            constant integer    FS_ITEM_NON_RUNE           = 0x8
            constant integer    FS_ITEM_SELLABLE           = 0x10
            constant integer    FS_ITEM_NON_SELLABLE       = 0x20
            constant integer    FS_ITEM_PAWNABLE           = 0x40
            constant integer    FS_ITEM_NON_PAWNABLE       = 0x80
            constant integer    FS_ITEM_PERMANENT          = 0x100
            constant integer    FS_ITEM_NON_PERMANENT      = 0x200
            constant integer    FS_ITEM_CHARGED            = 0x400
            constant integer    FS_ITEM_NON_CHARGED        = 0x800
            constant integer    FS_ITEM_POWERUP            = 0x1000
            constant integer    FS_ITEM_NON_POWERUP        = 0x2000
            constant integer    FS_ITEM_ARTIFACT           = 0x4000
            constant integer    FS_ITEM_NON_ARTIFACT       = 0x8000
            constant integer    FS_ITEM_PURCHASABLE        = 0x10000
            constant integer    FS_ITEM_NON_PURCHASABLE    = 0x20000
            constant integer    FS_ITEM_CAMPAIGN           = 0x40000
            constant integer    FS_ITEM_NON_CAMPAIGN       = 0x80000
            constant integer    FS_ITEM_MISC               = 0x100000
            constant integer    FS_ITEM_NON_MISC           = 0x200000
            constant integer    FS_ITEM_VISIBLE            = 0x400000
            constant integer    FS_ITEM_HIDDEN             = 0x800000
            
            constant integer    FS_PLAYER_ENEMY            = 0x1
            constant integer    FS_PLAYER_ALLY             = 0x2
            constant integer    FS_PLAYER_USER             = 0x4
            constant integer    FS_PLAYER_COMPUTER         = 0x8
            constant integer    FS_PLAYER_PLAYING          = 0x10
            constant integer    FS_PLAYER_LEFT             = 0x20
            constant integer    FS_PLAYER_NEUTRAL          = 0x40
            constant integer    FS_PLAYER_NON_NEUTRAL      = 0x80
            constant integer    FS_PLAYER_VISION           = 0x100
            constant integer    FS_PLAYER_NON_VISION       = 0x200
            constant integer    FS_PLAYER_CONTROL          = 0x400
            constant integer    FS_PLAYER_NON_CONTROL      = 0x800

        endglobals
        
        function UnitFilter takes unit whichUnit, player whichPlayer, integer filter returns boolean
            set filter = filter + 0x1
            if filter > 0x2000 then
                if filter > 0x1000000 then
                    set filter = filter - 0x1000000
                    if IsUnitType(whichUnit, UNIT_TYPE_UNDEAD) then
                        return false
                    endif
                endif
                if filter > 0x800000 then
                    set filter = filter - 0x800000
                    if not IsUnitType(whichUnit, UNIT_TYPE_UNDEAD) then
                        return false
                    endif
                endif
                if filter > 0x400000 then
                    set filter = filter - 0x40000
                    if not IsUnitType(whichUnit, UNIT_TYPE_RANGED_ATTACKER) then
                        return false
                    endif
                endif
                if filter > 0x200000 then
                    set filter = filter - 0x200000
                    if not IsUnitType(whichUnit, UNIT_TYPE_MELEE_ATTACKER) then
                        return false
                    endif
                endif
                if filter > 0x100000 then
                    set filter = filter - 0x100000
                    if not IsUnitType(whichUnit, UNIT_TYPE_FLYING) then
                        return false
                    endif
                endif
                if filter > 0x80000 then
                    set filter = filter - 0x80000
                    if not IsUnitType(whichUnit, UNIT_TYPE_GROUND) then
                        return false
                    endif
                endif
                if filter > 0x40000 then
                    set filter = filter - 0x40000
                    if IsUnitType(whichUnit, UNIT_TYPE_ANCIENT) then
                        return false
                    endif
                endif
                if filter > 0x20000 then
                    set filter = filter - 0x20000
                    if not IsUnitType(whichUnit, UNIT_TYPE_ANCIENT) then
                        return false
                    endif
                endif
                if filter > 0x10000 then
                    set filter = filter - 0x10000
                    if GetUnitAbilityLevel(whichUnit,ABILITY_WARD_CLASSIFIER)!=0 then
                        return false
                    endif
                endif
                if filter > 0x8000 then
                    set filter = filter - 0x8000
                    if GetUnitAbilityLevel(whichUnit,ABILITY_WARD_CLASSIFIER)==0 then
                        return false
                    endif
                endif
                if filter > 0x4000 then
                    set filter = filter - 0x4000
                    if IsUnitVisible(whichUnit,whichPlayer) then
                        return false
                    endif
                endif
                if filter > 0x2000 then
                    set filter = filter - 0x2000
                    if not IsUnitVisible(whichUnit,whichPlayer) then
                        return false
                    endif
                endif
            endif
            if filter < 0x2001 then
                if filter > 0x1000 then
                    set filter = filter - 0x1000
                    if IsUnitType(whichUnit, UNIT_TYPE_SUMMONED) then
                        return false
                    endif
                endif
                if filter > 0x800 then
                    set filter = filter - 0x800
                    if not IsUnitType(whichUnit, UNIT_TYPE_SUMMONED) then
                        return false
                    endif
                endif
                if filter > 0x400 then
                    set filter = filter - 0x400
                    if IsUnitType(whichUnit, UNIT_TYPE_MAGIC_IMMUNE) then
                        return false
                    endif
                endif
                if filter > 0x200 then
                    set filter = filter - 0x200
                    if not IsUnitType(whichUnit, UNIT_TYPE_MAGIC_IMMUNE) then
                        return false
                    endif
                endif
                if filter > 0x100 then
                    set filter = filter - 0x100
                    if IsUnitType(whichUnit, UNIT_TYPE_HERO) then
                        return false
                    endif
                endif
                if filter > 0x80 then
                    set filter = filter - 0x80
                    if not IsUnitType(whichUnit, UNIT_TYPE_HERO) then
                        return false
                    endif
                endif
                if filter > 0x40 then
                    set filter = filter - 0x40
                    if not IsUnitType(whichUnit,UNIT_TYPE_MECHANICAL) then
                        return false
                    endif
                endif
                if filter > 0x20 then
                    set filter = filter - 0x20
                    if not IsUnitType(whichUnit,UNIT_TYPE_STRUCTURE) then
                        return false
                    endif
                endif
                if filter > 0x10 then
                    set filter = filter - 0x10
                    if IsUnitType(whichUnit,UNIT_TYPE_STRUCTURE) or IsUnitType(whichUnit,UNIT_TYPE_MECHANICAL) then
                        return false
                    endif
                endif
                if filter > 0x8 then
                    set filter = filter - 0x8
                    if GetWidgetLife(whichUnit)>0.405 and IsUnitType(whichUnit,UNIT_TYPE_DEAD)==false then
                        return false
                    endif
                endif
                if filter > 0x4 then
                    set filter = filter - 0x4
                    if GetWidgetLife(whichUnit)<=0.405 or IsUnitType(whichUnit,UNIT_TYPE_DEAD) then
                        return false
                    endif
                endif
                if filter > 0x2 then
                    set filter = filter - 0x2
                    if IsUnitEnemy(whichUnit,whichPlayer) then
                        return false
                    endif
                endif
                if filter > 0x1 then
                    set filter = filter - 0x1
                    if not IsUnitEnemy(whichUnit,whichPlayer) then
                        return false
                    endif
                endif
            endif
            if GetUnitAbilityLevel(whichUnit,ABILITY_DUMMY_CLASSIFIER)!=0 then
                return false
            endif
            return true
        endfunction
        
        function ItemFilter takes item whichItem, integer filter returns boolean
            set filter = filter + 0x1
            if filter > 0x2000 then
                if filter > 0x800000 then
                    set filter = filter - 0x800000
                    if not IsItemVisible(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x400000 then
                    set filter = filter - 0x40000
                    if IsItemVisible(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x200000 then
                    set filter = filter - 0x200000
                    if GetItemType(whichItem)==ITEM_TYPE_MISCELLANEOUS then
                        return false
                    endif
                endif
                if filter > 0x100000 then
                    set filter = filter - 0x100000
                    if GetItemType(whichItem)!=ITEM_TYPE_MISCELLANEOUS then
                        return false
                    endif
                endif
                if filter > 0x80000 then
                    set filter = filter - 0x80000
                    if GetItemType(whichItem)==ITEM_TYPE_CAMPAIGN then
                        return false
                    endif
                endif
                if filter > 0x40000 then
                    set filter = filter - 0x40000
                    if GetItemType(whichItem)!=ITEM_TYPE_CAMPAIGN then
                        return false
                    endif
                endif
                if filter > 0x20000 then
                    set filter = filter - 0x20000
                    if GetItemType(whichItem)==ITEM_TYPE_PURCHASABLE then
                        return false
                    endif
                endif
                if filter > 0x10000 then
                    set filter = filter - 0x10000
                    if GetItemType(whichItem)!=ITEM_TYPE_PURCHASABLE then
                        return false
                    endif
                endif
                if filter > 0x8000 then
                    set filter = filter - 0x8000
                    if GetItemType(whichItem)==ITEM_TYPE_ARTIFACT then
                        return false
                    endif
                endif
                if filter > 0x4000 then
                    set filter = filter - 0x4000
                    if GetItemType(whichItem)!=ITEM_TYPE_ARTIFACT then
                        return false
                    endif
                endif
                if filter > 0x2000 then
                    set filter = filter - 0x2000
                    if GetItemType(whichItem)==ITEM_TYPE_POWERUP then
                        return false
                    endif
                endif
            endif
            if filter < 0x2001 then
                if filter > 0x1000 then
                    set filter = filter - 0x1000
                    if GetItemType(whichItem)!=ITEM_TYPE_POWERUP then
                        return false
                    endif
                endif
                if filter > 0x800 then
                    set filter = filter - 0x800
                    if GetItemType(whichItem)==ITEM_TYPE_CHARGED then
                        return false
                    endif
                endif
                if filter > 0x400 then
                    set filter = filter - 0x400
                    if GetItemType(whichItem)!=ITEM_TYPE_CHARGED then
                        return false
                    endif
                endif
                if filter > 0x200 then
                    set filter = filter - 0x200
                    if GetItemType(whichItem)==ITEM_TYPE_PERMANENT then
                        return false
                    endif
                endif
                if filter > 0x100 then
                    set filter = filter - 0x100
                    if GetItemType(whichItem)!=ITEM_TYPE_PERMANENT then
                        return false
                    endif
                endif
                if filter > 0x80 then
                    set filter = filter - 0x80
                    if IsItemPawnable(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x40 then
                    set filter = filter - 0x40
                    if not IsItemPawnable(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x20 then
                    set filter = filter - 0x20
                    if IsItemSellable(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x10 then
                    set filter = filter - 0x10
                    if not IsItemSellable(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x8 then
                    set filter = filter - 0x8
                    if IsItemPowerup(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x4 then
                    set filter = filter - 0x4
                    if not IsItemPowerup(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x2 then
                    set filter = filter - 0x2
                    if IsItemOwned(whichItem) then
                        return false
                    endif
                endif
                if filter > 0x1 then
                    set filter = filter - 0x1
                    if not IsItemOwned(whichItem) then
                        return false
                    endif
                endif
            endif
            return true
        endfunction
        
        function PlayerFilter takes player whichPlayer, player otherPlayer, integer filter returns boolean
            if filter > 0x800 then
                set filter = filter - 0x800
                if GetPlayerAlliance(whichPlayer,otherPlayer,ALLIANCE_SHARED_CONTROL) then
                    return false
                endif
            endif
            if filter > 0x400 then
                set filter = filter - 0x400
                if not GetPlayerAlliance(whichPlayer,otherPlayer,ALLIANCE_SHARED_CONTROL) then
                    return false
                endif
            endif
            if filter > 0x200 then
                set filter = filter - 0x200
                if GetPlayerAlliance(whichPlayer,otherPlayer,ALLIANCE_SHARED_VISION) then
                    return false
                endif
            endif
            if filter > 0x100 then
                set filter = filter - 0x100
                if not GetPlayerAlliance(whichPlayer,otherPlayer,ALLIANCE_SHARED_VISION) then
                    return false
                endif
            endif
            if filter > 0x80 then
                set filter = filter - 0x80
                if (whichPlayer==Player(12) or whichPlayer==Player(13) or whichPlayer==Player(14) or whichPlayer==Player(15)) then
                    return false
                endif
            endif
            if filter > 0x40 then
                set filter = filter - 0x40
                if (not(whichPlayer==Player(12) or whichPlayer==Player(13) or whichPlayer==Player(14) or whichPlayer==Player(15))) then
                    return false
                endif
            endif
            if filter > 0x20 then
                set filter = filter - 0x20
                if GetPlayerSlotState(whichPlayer)!=PLAYER_SLOT_STATE_LEFT then
                    return false
                endif
            endif
            if filter > 0x10 then
                set filter = filter - 0x10
                if GetPlayerSlotState(whichPlayer)!=PLAYER_SLOT_STATE_PLAYING then
                    return false
                endif
            endif
            if filter > 0x8 then
                set filter = filter - 0x8
                if GetPlayerController(whichPlayer)!=MAP_CONTROL_COMPUTER then
                    return false
                endif
            endif
            if filter > 0x4 then
                set filter = filter - 0x4
                if GetPlayerController(whichPlayer)!=MAP_CONTROL_USER then
                    return false
                endif
            endif
            if filter > 0x2 then
                set filter = filter - 0x2
                if IsPlayerEnemy(whichPlayer,otherPlayer) then
                    return false
                endif
            endif
            if filter > 0x1 then
                set filter = filter - 0x1
                if IsPlayerAlly(whichPlayer,otherPlayer) then
                    return false
                endif
            endif
            return true
        endfunction

    endlibrary
Please update it.

EDIT:
JASS:
if GetWidgetLife(whichUnit)>0.405 and IsUnitType(whichUnit,UNIT_TYPE_DEAD)==false then
Just use this native function to check unit alive (but first you need to declare it somewhere):
JASS:
native UnitAlive takes unit id returns boolean

JASS:
            if GetUnitAbilityLevel(whichUnit,ABILITY_DUMMY_CLASSIFIER)!=0 then
                return false
            endif
            return true
=>
JASS:
            return GetUnitAbilityLevel(whichUnit,ABILITY_DUMMY_CLASSIFIER)==0
Thought I don't understand why it should return false if filter unit is a dummy? Since IIRC units with locust couldn't be enumerated.

EDIT:
I have tried to implement this in one of my spell and it works fluently. And it allows me to pick targets dynamically. This is very impressive :) Great job!
 
Last edited:
Level 8
Joined
Feb 3, 2013
Messages
277
Is this faster than?
JASS:
private function filter takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)
endfunction

private function doSomething takes nothing returns nothing
    call GroupEnumUnitsInRange(g, 0, 0, 300., function filter)
    set fog = FirstOfGroup(g)
    while (fog != null)
        call UnitDamageTarget(cast, fog, dmg, false, false, null, null, null)
        ..
        ..
    endwhile
endfunction
 

Deleted member 219079

D

Deleted member 219079

Is this faster than?
Ofc not.

Why do you use nxnnnnn stuff?

Do they use less memory, are they faster to cpu to handle or what?

Is there a tutorial on hive about hexadecimal? :/

The algorithm is very nicely thought out, I would've never thought of something like this :) +rep
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Let's say I need a custom filter that is not included in the filter constants. Can I just replace one of the existing constants I don't need with my custom filter (renaming the constant, but keeping the memory field as it is)?

no, you have to change the if-statement associated with the constant

JASS:
            if filter > 0x10 then
                set filter = filter - 0x10
                if GetPlayerSlotState(whichPlayer)!=PLAYER_SLOT_STATE_PLAYING then
                    return false
                endif
            endif

Notice the PLAYER_SLOT_STATE_PLAYING bit? That's the PLAYER_STATE_PLAYING or whatever constant.
 
Level 13
Joined
May 24, 2005
Messages
609
Yeah, ofc I would change the condition to the custom condition I need. I just wanted to make sure that it is save to replace those constants and conditions by others (means that I just can use any condition I want on the 0x10 memory for example).
 
Level 18
Joined
Nov 21, 2012
Messages
835
It's usefull for filtering units, I'm going to use it.
However I found mistake in UnitFilter function
JASS:
if filter > 0x400000 then // ranged
    //set filter = filter - 0x40000 // should be 400000
    set filter = filter - 0x400000
    if not IsUnitType(whichUnit, UNIT_TYPE_RANGED_ATTACKER) then
also I always checked for ground unit by not IsUnitType(whichUnit, UNIT_TYPE_FLYING). By checking UNIT_TYPE_GROUND it won't pass units with movement of type hover/amphibious if I remember corectly. So let me sugest this for detecting ground unit:
JASS:
if filter > 0x80000 then
   set filter = filter - 0x80000 //ground
   //if not IsUnitType(whichUnit, UNIT_TYPE_GROUND) then
   if IsUnitType(whichUnit, UNIT_TYPE_FLYING) then
       return false
   endif
endif

I'm not sure about ward classification.
Should I add ABILITY_WARD_CLASSIFIER to all ward-type units to allow check for this ability by Filtering System?
 
Level 4
Joined
Jul 4, 2012
Messages
78
It's usefull for filtering units, I'm going to use it.
However I found mistake in UnitFilter function
JASS:
if filter > 0x400000 then // ranged
    //set filter = filter - 0x40000 // should be 400000
    set filter = filter - 0x400000
    if not IsUnitType(whichUnit, UNIT_TYPE_RANGED_ATTACKER) then
also I always checked for ground unit by not IsUnitType(whichUnit, UNIT_TYPE_FLYING). By checking UNIT_TYPE_GROUND it won't pass units with movement of type hover/amphibious if I remember corectly. So let me sugest this for detecting ground unit:
JASS:
if filter > 0x80000 then
   set filter = filter - 0x80000 //ground
   //if not IsUnitType(whichUnit, UNIT_TYPE_GROUND) then
   if IsUnitType(whichUnit, UNIT_TYPE_FLYING) then
       return false
   endif
endif

I'm not sure about ward classification.
Should I add ABILITY_WARD_CLASSIFIER to all ward-type units to allow check for this ability by Filtering System?

oh thanks, fixed it.

what you said about the ground units' check is correct, but i decided to leave it as is, to strictly pass Ground movement-type. If someone needs to include floating and hovering units they can easily change the corresponding part in the function, one of major points of this system was and is configurability.

You should only add ward classifier ability to actual wards, e.g. observer wards; as i have mentioned in the description section of the ward classifier, assigning ward classification to units can be done with different intentions in mind but the unit could be not an actual ward; so u can elect to detect actual wards with the ward classifier ability instead.
 
  • Like
Reactions: AGD
Top