• 🏆 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
The main purpose of making the Filtering System was to shorten those long
many-line condition blocks to only one “if” statement so people don’t
have to waste their time writing same thing over and over again.

Advocacy/descriptive post (by Magtheridon96):
The Filtering System

This is usable by Jass, vJass and GUI users and it uses the JPAG standard.

You need a vJass parser to use this (Jass New Gen Pack or anything else),
i used JASS Helper 0.A.2.B (Cohader's Version).

CURRENT VERSION : 3.4.2
CURRENT PERFORMANCE : able to filter 3703 units with 5 conditions at same time in something less than 1 ms.


Create a blank trigger in your map and convert it to Custom Text, delete its contents
and paste the code below in it. [YOU MUST HAVE A VJASS PARSER]




JASS:
    library FilteringSystem /* v3.4.2 */

    /*
    ************************************************************************************************************************
    *        Filtering System's API v3.4.2
    *        by The Wrecker
    *
    *        Credits:
    *               - God : God supports everyone.
    *               - 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 Filtering 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 classifiers:
    *
    * */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:
    *
    *
    *            - Mixing the filters into single filter (Constraints):
    *              (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 subtract 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
    *    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
    *    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 - 0x400000
                    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 - 0x400000
                    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
 
Last edited:
Level 4
Joined
Jul 4, 2012
Messages
78
aahh, you mean making it binary? well of course that's one of the best ideas but does warcraft integer system support 17 digits? i'll do my best to make it like that way, thank you for the idea.

UPDATE: made given string be converted to lower case to prevent issues with capitals, some other small things.
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
You'd have 3 bytes, at 8 bits each, which is 24 bits, or 24 booleans. You have 17 in your resource.

From here, you can split them like so

byte1 = bits - bits/0x100*0x100
byte2 = (bits - bits/0x10000*0x10000)/0x100
byte3 = bits/0x10000

That will get you your 3 bytes, so you can read any specific byte you want

Next, you can use and/or to read specific bits

constant function B_AND takes integer byte1, integer byte2 returns integer

Want to read bit 0, then pass in byte 1

local boolean bit0 = B_AND(byte1, 0xfe) != 0
 
Level 13
Joined
Mar 29, 2012
Messages
530
JASS:
library FilteringSystem initializer init
    private function init takes nothing returns nothing
        static if udg_ABILITY_WARD_CLASSIFICATOR != 'Alit' then
            set udg_ABILITY_WARD_CLASSIFICATOR = 'Alit'
            set udg_ABILITY_DUMMY_CLASSIFICATOR = 'Aloc'
        endif
    endfunction
endlibrary

am i right? :D
 
Level 4
Joined
Jul 4, 2012
Messages
78
JASS:
library FilteringSystem initializer init
    private function init takes nothing returns nothing
        static if udg_ABILITY_WARD_CLASSIFICATOR != 'Alit' then
            set udg_ABILITY_WARD_CLASSIFICATOR = 'Alit'
            set udg_ABILITY_DUMMY_CLASSIFICATOR = 'Aloc'
        endif
    endfunction
endlibrary

am i right? :D

in vJass yes, but in vJass i already defined those as constants; in Jass you don't have any library to define, that's why i putted that if inside function
 
Level 4
Joined
Jul 4, 2012
Messages
78
They're actually harder to use, because you have to read your code in the end and most of it won't make sense to you :p

lol, yeah :D

Also, do binary stuff (like a tree) for your if statement checking. It'll increase your speed a bit ;)

by Tree, you mean put if s under each other? or something else? Nestharus please make thing bright for me i'm just 17 with a cliffhanger mind :D also as i told you in PM, i began re-learning binary and hex, then bitwise, then i'll use yours BitManip or will not use or something else and i'll make a binary version of this system and then give credits to you :D

UPDATE: cleaned out if s, your mind will no longer get knocked out when reading if statements.
 
Last edited:
He means you have to use a cascade of ifs instead of one contiguous block.

First, instead of using a string, use integer constants.
It'll allow you to optimize quite well.

Let's say you had a range between 0 and 8. This is what you would do:

JASS:
// Where i is an integer:

if i > 4 then
    if i > 6 then
        if i == 7 then
            // number is 7
        else
            // number is 8
        endif
    else
        if i == 5 then
            // number is 5
        else
            // number is 6
        endif
    endif
else
    if i > 1 then
        if i > 2 then
            if i == 4 then
                // number is 4
            else
                // number is 3
            endif
        else
            // number is 2
        endif
    else
        if i == 1 then
            // number is 1
        else
            // number is 0
        endif
    endif
endif

This minimizes number of comparisons required and normalizes it so you don't have a "worst case".

You can fix the above to have more elseifs. I left it this way so it can seem clearer.
 
Last edited:
Level 4
Joined
Jul 4, 2012
Messages
78
well, i completely agree with that and i'll make it that way, but i have a problem: how to use integer (your example contained 9 [0-8], my unit section contains 24) with 24 options? we have 10 numbers :) or perhaps i must use Base 32 xD ?

Edit: found this solution, in your opinions, is it good?

instead of 1,2,a,b,... now 01,02,11,12,...; the loop will check every 2 digit instead of every 1 digit, creating groups of two letters, still takes string and then turns it into integer.

JASS:
            local integer ic = 1
            local integer ie = StringLength(str)
            local integer ci = 0
            if ie>0 and ModuloInteger(ie,2)==0 then
                loop
                    exitwhen ic > ie
                        set ci = S2I(SubString(str,ic,ic+2))
                        if ci<9 then
                            if ci<5 then
                                if ci<3 then
                                    if ci==1 then
                                    //1
                                    else
                                    //2
                                    endif
                                else
                                    if ci==3 then
                                    //3
                                    else
                                    //4
                                    endif
                                endif
                            else
                                if ci<7 then
                                    if ci==5 then
                                    //5
                                    else
                                    //6
                                    endif
                                else
                                    if ci==7 then
                                    //7
                                    else
                                    //8
                                    endif
                                endif
                            endif
                        elseif ci<17 and ci>8 then
                            if ci<13 then
                                if ci<11 then
                                    if ci==9 then
                                    //9
                                    else
                                    //10
                                    endif
                                else
                                    if ci==11 then
                                    //11
                                    else
                                    //12
                                    endif
                                endif
                            else
                                if ci<15 then
                                    if ci==13 then
                                    //13
                                    else
                                    //14
                                    endif
                                else
                                    if ci==15 then
                                    //15
                                    else
                                    //16
                                    endif
                                endif
                            endif
                        else
                            if ci<21 then
                                if ci<19 then
                                    if ci==17 then
                                    //17
                                    else
                                    //18
                                    endif
                                else
                                    if ci==20 then
                                    //19
                                    else
                                    //20
                                    endif
                                endif
                            else
                                if ci<23 then
                                    if ci==21 then
                                    //21
                                    else
                                    //22
                                    endif
                                else
                                    if ci==23 then
                                    //23
                                    else
                                    //24
                                    endif
                                endif
                            endif
                        endif
                        set ic = ic + 2
                endloop
            endif
            set ci = 0
            return true

now i'm gonna sleep, have a good night, will update tomorrow, Zzzzzz.....

UPDATE: a whole change to algorithms. improving performance a lot, thanks to Magtheridon96 and Nestharus, giving credits now is necessary , given credits :)

EDIT: yyyyyyyyyyyaaaaaaaaaaaayyyyyyyy, reached 200 views :))
 
Last edited:
Level 4
Joined
Jul 4, 2012
Messages
78
updated to version 1.1.0.

the codes are now two digit integers instead of one number or one letter, making string given twice the length but reducing number of 'if's from 25 checks every loop to 5, increasing performance by 500%, which completely covers the con produced by making string twice the length.
 
Level 4
Joined
Jul 4, 2012
Messages
78
i will use bitwise as you instructed it Nestharus, the only problem i got at the moment is for example a "0115" representing enemy heroes in unit filter function will be turned to what when i convert this system to bitwise? write the format (hex,bin,dec,...) and the exact integer ty :))
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Ehm...

As you have 24 bits, it would be

0x004001
0b000000000100000000000001

Decimal, no idea, don't work with decimal

0x004001 & 0x004000 == 1

There is no & operator in JASS, so given an array of bits

bit[0] = 1
bit[1] = 0x2
bit[2] = 0x4
bit[3] = 0x8
bit[4] = 0x10
bit[5] = 0x20
bit[6] = 0x40
bit[7] = 0x80
bit[8] = 0x100
bit[9] = 0x200
bit[10] = 0x400
bit[11] = 0x800
bit[12] = 0x1000
bit[13] = 0x2000
bit[14] = 0x4000
bit[15] = 0x8000
bit[16] = 0x10000
bit[17] = 0x20000
bit[18] = 0x40000
bit[19] = 0x80000
bit[20] = 0x100000
bit[21] = 0x200000
bit[22] = 0x400000
bit[23] = 0x800000
bit[24] = 0x1000000
bit[25] = 0x2000000
bit[26] = 0x4000000
bit[27] = 0x8000000
bit[28] = 0x10000000
bit[29] = 0x20000000
bit[30] = 0x40000000

So (0x004001 - 0x004001/bit[15]*bit[15])/bit[14] == 1
And (0x004001 - 0x004001/bit[1]*bit[1])/bit[0] == 1

Notice the pattern
You have 01,15

Look at the math above for how to read them : P

For your binary, you'd start at 12, and then go halves etc ;). This'll give you regions to work in.


In hexadecimal, every digit represents 4 bits

Hexadecimal is 0123456789abcdef

0x0 = 0b0000
0x1 = 0b0001
0x2 = 0b0010
0x3 = 0b0011
0x4 = 0b0100
0x5 = 0b0101
0x6 = 0b0110
0x7 = 0b0111
0x8 = 0b1000
0x9 = 0b1001
0xa = 0b1010
0xb = 0b1011
0xc = 0b1100
0xd = 0b1101
0xe = 0b1110
0xf = 0b1111


Users will want to work in hexadecimal, not in decimal. Working in decimal is madness >.<

You want bits 9 and 20 enabled?

0x100200

which translates to 0b100000000001000000000

Remember that the smallest bit starts at 0, not 1. When you count the bits from right to left, start at 0, then you'll hit the correct 9 and 20 ;).


edit
Of course, here's something else cool you can do

Let's say that bit 20 was COND_1 and bit 9 was COND_2, then both of them put together is COND_1 + COND_2.

0x100000 + 0x000200 = 0x100200

So you can make a constant for each condition and then when users pass them in, rather than figuring out the hex (I mean they can if they want to), they can pass in the constants

COND_1 + COND_2 + COND_4, etc


edit
btw, Pow(2, bitPosition) == the number

Pow(2, 0) == 0x1
Pow(2, 1) == 0x2
Pow(2, 2) == 0x4
Pow(2, 3) == 0x8
Pow(2, 4) == 0x10

etc, but use an array, not Pow
 
Last edited:
Level 4
Joined
Jul 4, 2012
Messages
78
OMG. how did you write all this in 5 minutes? by the way i'll keep a backup of current system and begin making it bitwise then when it is created i won't delete this 'string' argument, i will just upload the new bitwise along with this one so people who even can't handle the bitwise (like me :p) use the stringed version xD now bb going to suicide ! the guy come along with the idea to assign a specific part in World Editor and HiveWorkshop to you was right :DDDD now i have to call my Software Engineer friend along with my math teacher to home and participate in bin/hex class [joke] :)) i'm approximatly zero in bases other than decimal, should have paid more attention to learning them before... ok enough bullshit ! i begin bin/hex/bitwise learning right now, see you Nestharus :p
 
Level 4
Joined
Jul 4, 2012
Messages
78
the point is that the understanding of "0115" is easier than numbers in another formats and bases like 0x004001, (not to mention in high number of options "01040712172124" is as hard as the hex one :pP) it is not all about performance or modularity, its a bit about simplicity for less-experienced users, btw i accepted the bitwise what is your problem man? :)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I'm saying that keeping the string thing is pointless, users won't be working in hex or numbers.

If you create 1 constant for every single condition, then users can just use those instead of w/e else. They shouldn't be working in numbers >.<, they should be working in variables.

Like

group = GroupFilter(group, UNIT_TYPE_HERO + ATTACK_TYPE_GROUND)

Not

group = GroupFilter(group, "0115")
group = GroupFilter(group, 0x004001)


Which one is easier to understand?


edit
If you're expecting users to type in arbitrary numbers, then you've got more issues than just your algorithm ;P
 
Level 4
Joined
Jul 4, 2012
Messages
78
ROFL, now that made a REAL sense, TY soooooooooooooooo much Nestharus, i owe you now :)) so i must make something like this :

JASS:
    local integer bits //users will first do these lines to make a condition list coz i suppose they can't use '  if UnitFilter(uu,us,COND_1 + COND_2 +...) then ' ,can they?
    call AddCondition(bits,COND_1)
    call AddCondition(bits,COND_2)
    ...
    ...
    if UnitFilter(uu,us,bits) then //then they can use it
    ....
    endif

correct me if i'm wrong.
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
nop

if (UnitFilter (uu, us, COND_1 + COND_2)) then
endif

and why uu and us????

Should just be

if (UnitFilter(whichUnit, COND_1 + COND_2)) then
endif


and stop using bs names like uu, us, and so on, don't use any acronyms >.<


should only be passing in 1 unit, no idea why ur taking 2

your if statements also aren't binary, your splitting 3 ways the first time. You halve it each time :\.
 
Level 4
Joined
Jul 4, 2012
Messages
78
nop

if (UnitFilter (uu, us, COND_1 + COND_2)) then
endif

and why uu and us????

Should just be

if (UnitFilter(whichUnit, COND_1 + COND_2)) then
endif


and stop using bs names like uu, us, and so on, don't use any acronyms >.<


should only be passing in 1 unit, no idea why ur taking 2

your if statements also aren't binary, your splitting 3 ways the first time. You halve it each time :\.

so u mean war's engine can add two hex ?

us for alliance and visibility checking :(

well i have 24 options which represent 3*2*2*2, what else i must do?

will change those crap names :))

oh oh. wait wait, one thing you must bright for me, those constants you told are in hex format right? for example you told UNIT_TYPE_HERO + UNIT_TYPE_GROUND ==> for example 0x002000 + 0x000040 == 0x002040 yeah? so when you say if (UnitFilter(whichUnit, COND_1 + COND_2)) then you mean war's engine can add two hex numbers?

EDIT: IT CAN! IT CAN! but can't do on binary, say any comments you have Nestharus :) i will begin my work ASAP
 
Last edited:
Level 4
Joined
Jul 4, 2012
Messages
78
ok, this is what i have done this far, Nestharus i require your comment about it :))

JASS:
    library daFilteringSystem initializer daInit /* requires Nestharus's mind */
    
        globals
    
            private integer array bit
            
            constant integer FS_UNIT_MAX_BITS = 32
            
            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_VISIBLE = 0x80
            constant integer FS_UNIT_INVISIBLE = 0x100
            constant integer FS_UNIT_IMMUNE = 0x200
            constant integer FS_UNIT_NON_IMMUNE = 0x400
            constant integer FS_UNIT_WARD = 0x800
            constant integer FS_UNIT_NON_WARD = 0x1000
            constant integer FS_UNIT_ANCIENT = 0x2000
            constant integer FS_UNIT_NON_ANCIENT = 0x4000
            constant integer FS_UNIT_HERO = 0x8000
            constant integer FS_UNIT_NON_HERO = 0x10000
            constant integer FS_UNIT_GROUND = 0x20000
            constant integer FS_UNIT_FLYING = 0x40000
            constant integer FS_UNIT_MELEE = 0x80000
            constant integer FS_UNIT_RANGED = 0x100000
            constant integer FS_UNIT_SUMMONED = 0x200000
            constant integer FS_UNIT_NON_SUMMONED = 0x400000
            constant integer FS_UNIT_UNDEAD = 0x800000
            constant integer FS_UNIT_NON_UNDEAD = 0x1000000

        endglobals
    
        private function daInit takes nothing returns nothing
            set bit[0] = 1
            set bit[1] = 0x2
            set bit[2] = 0x4
            set bit[3] = 0x8
            set bit[4] = 0x10
            set bit[5] = 0x20
            set bit[6] = 0x40
            set bit[7] = 0x80
            set bit[8] = 0x100
            set bit[9] = 0x200
            set bit[10] = 0x400
            set bit[11] = 0x800
            set bit[12] = 0x1000
            set bit[13] = 0x2000
            set bit[14] = 0x4000
            set bit[15] = 0x8000
            set bit[16] = 0x10000
            set bit[17] = 0x20000
            set bit[18] = 0x40000
            set bit[19] = 0x80000
            set bit[20] = 0x100000
            set bit[21] = 0x200000
            set bit[22] = 0x400000
            set bit[23] = 0x800000
            set bit[24] = 0x1000000
            set bit[25] = 0x2000000
            set bit[26] = 0x4000000
            set bit[27] = 0x8000000
            set bit[28] = 0x10000000
            set bit[29] = 0x20000000
            set bit[30] = 0x40000000
            set bit[31] = 0x80000000
        endfunction
        
        function UnitFilter takes unit whichUnit, unit sourceUnit, integer filter returns boolean
            local integer currentPosition = 1
            loop
                exitwhen currentPosition > FS_UNIT_MAX_BITS
                    if (filter - filter/bit[currentPosition]*bit[currentPosition])/bit[currentPosition-1]==1 then
                        if currentPosition > 16 then
                            if currentPosition > 24 then
                                if currentPosition > 28 then
                                    if currentPosition > 30 then
                                        if currentPosition == 31 then
                                            // example of course, it must be in "1" not "31" :))
                                            if not IsUnitEnemy(whichUnit,GetOwningPlayer(sourceUnit)) then
                                                return false
                                            endif
                                        else
                                        //32
                                        endif
                                    else
                                        if currentPosition == 29 then
                                        //29
                                        else
                                        //30
                                        endif
                                    endif
                                else
                                    if currentPosition > 26 then
                                        if currentPosition == 27 then
                                        //27
                                        else
                                        //28
                                        endif
                                    else
                                        if currentPosition == 25 then
                                        //25
                                        else
                                        //26
                                        endif
                                    endif
                                endif
                            else
                                if currentPosition > 20 then
                                    if currentPosition > 22 then
                                        if currentPosition == 23 then
                                        //23
                                        else
                                        //24
                                        endif
                                    else
                                        if currentPosition == 21 then
                                        //21
                                        else
                                        //22
                                        endif
                                    endif
                                else
                                    if currentPosition > 18 then
                                        if currentPosition == 19 then
                                        //19
                                        else
                                        //20
                                        endif
                                    else
                                        if currentPosition == 17 then
                                        //17
                                        else
                                        //18
                                        endif
                                    endif
                                endif
                            endif
                        else
                            if currentPosition > 8 then
                                if currentPosition > 12 then
                                    if currentPosition > 14 then
                                        if currentPosition == 15 then
                                        //15
                                        else
                                        //16
                                        endif
                                    else
                                        if currentPosition == 13 then
                                        //13
                                        else
                                        //14
                                        endif
                                    endif
                                else
                                    if currentPosition > 10 then
                                        if currentPosition == 11 then
                                        //11
                                        else
                                        //12
                                        endif
                                    else
                                        if currentPosition == 9 then
                                        //9
                                        else
                                        //10
                                        endif
                                    endif
                                endif
                            else
                                if currentPosition > 4 then
                                    if currentPosition > 6 then
                                        if currentPosition == 7 then
                                        //7
                                        else
                                        //8
                                        endif
                                    else
                                        if currentPosition == 5 then
                                        //5
                                        else
                                        //6
                                        endif
                                    endif
                                else
                                    if currentPosition > 2 then
                                        if currentPosition == 3 then
                                        //3
                                        else
                                        //4
                                        endif
                                    else
                                        if currentPosition == 1 then
                                        //1
                                        else
                                        //2
                                        endif
                                    endif
                                endif
                            endif
                        endif
                    endif
                    set currentPosition = currentPosition + 1
            endloop
            return true
        endfunction
        
    /*
        private function test takes nothing returns nothing
            local integer i = (0x004001 - 0x004001/bit[14]*bit[14])/bit[13]
            call BJDebugMsg(I2S(i))
        endfunction

        private function testinit takes nothing returns nothing
            local trigger t = CreateTrigger(  )
            call TriggerRegisterTimerEventSingle( t, 1.00 )
            call TriggerAddAction( t, function test )
        endfunction */

    endlibrary

have a good night, going to Sleep, will continue it tomorrow....ZZZZZzzzzz
 
Level 4
Joined
Jul 4, 2012
Messages
78
noooooo on your if statement stuff, split it up more

if (filter > 0x4000) then //it contains bits in the high region, etc

center in on the bits that it contains, then clear the bit and start again, do this while it's != 0

edit
set bit[31] = 0x80000000

get rid of that, that's negative

y your right, it will increase performance A LOT.

ok will make it 'while'.

didn't know that 0x80000000 is negative, will kick its a**. :)) ty again

now i'm gonna do some university stuff (registering,etc..) will continue after it.
 
Level 4
Joined
Jul 4, 2012
Messages
78
take a look at how many lines of codes did you have to add, and how the readability decremented, just to gain a little bit of speed/performance.

readability maybe but, 1) performance is increased by more than 5 times not a bit, 2) now instead of memorizing or finding codes in API which are without any rule, you only need to type in: for example FS_UNIT_HERO + FS_UNIT_GROUND + FS_UNIT MELEE + FS_UNIT_NON_WARD + FS_UNIT_NON-SUMMONED which is easier to understand ( just takes more time to type it xD than "1115171921") . however if people requested the stringed version, i'll keep it, we have no fight, have we?
 
Level 4
Joined
Jul 4, 2012
Messages
78
ok this will be the next update, only i post here to know Nestharus and other exprienced people's opinions about it:

JASS:
    library FilteringSystem initializer Init /* Special thanks to Nestharus
                                                for the algorithms and many
                                                other hints; Magtheridon96
                                                for many useful hints. */
                                                
                                                /* by TheWrecker */
                                                
        /* [url]http://www.hiveworkshop.com/forums/submissions-414/filtering-system-240887/[/url] */
    
        globals
        
            constant integer ABILITY_WARD_CLASSIFICATOR = '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_CLASSIFICATOR = '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. */
    
            private integer array bit
            
            /* this is the list of options, feel free to see them but do not modify */
            
            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_VISIBLE = 0x80
            constant integer FS_UNIT_INVISIBLE = 0x100
            constant integer FS_UNIT_IMMUNE = 0x200
            constant integer FS_UNIT_NON_IMMUNE = 0x400
            constant integer FS_UNIT_WARD = 0x800
            constant integer FS_UNIT_NON_WARD = 0x1000
            constant integer FS_UNIT_ANCIENT = 0x2000
            constant integer FS_UNIT_NON_ANCIENT = 0x4000
            constant integer FS_UNIT_HERO = 0x8000
            constant integer FS_UNIT_NON_HERO = 0x10000
            constant integer FS_UNIT_GROUND = 0x20000
            constant integer FS_UNIT_FLYING = 0x40000
            constant integer FS_UNIT_MELEE = 0x80000
            constant integer FS_UNIT_RANGED = 0x100000
            constant integer FS_UNIT_SUMMONED = 0x200000
            constant integer FS_UNIT_NON_SUMMONED = 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 //includes runes, tomes, powerups, etc
            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_LEAVED = 0x20 //also includes non-used slots
            constant integer FS_PLAYER_NEUTRAL = 0x40
            constant integer FS_PLAYER_NON_NEUTRAL = 0x80
            constant integer FS_PLAYER_VISION = 0x100 //shared vision
            constant integer FS_PLAYER_NON_VISION = 0x200
            constant integer FS_PLAYER_CONTROL = 0x400 //shared unit control
            constant integer FS_PLAYER_NON_CONTROL = 0x800

        endglobals
    
        private function Init takes nothing returns nothing
            set bit[0] = 1
            set bit[1] = 0x2
            set bit[2] = 0x4
            set bit[3] = 0x8
            set bit[4] = 0x10
            set bit[5] = 0x20
            set bit[6] = 0x40
            set bit[7] = 0x80
            set bit[8] = 0x100
            set bit[9] = 0x200
            set bit[10] = 0x400
            set bit[11] = 0x800
            set bit[12] = 0x1000
            set bit[13] = 0x2000
            set bit[14] = 0x4000
            set bit[15] = 0x8000
            set bit[16] = 0x10000
            set bit[17] = 0x20000
            set bit[18] = 0x40000
            set bit[19] = 0x80000
            set bit[20] = 0x100000
            set bit[21] = 0x200000
            set bit[22] = 0x400000
            set bit[23] = 0x800000
            set bit[24] = 0x1000000
            set bit[25] = 0x2000000
            set bit[26] = 0x4000000
            set bit[27] = 0x8000000
            set bit[28] = 0x10000000
        endfunction
        
        function UnitFilter takes unit whichUnit, unit sourceUnit, integer filter returns boolean
            local integer currentPosition = 1
            loop
                exitwhen filter == 0
                    if (filter - filter/bit[currentPosition]*bit[currentPosition])/bit[currentPosition-1]==1 then
                        set filter = filter - bit[currentPosition-1]
                        if currentPosition > 16 then
                            if currentPosition > 24 then
                                if currentPosition > 26 then
                                    if currentPosition == 27 then
                                    //27
                                    else
                                    //28
                                    endif
                                else
                                    if currentPosition == 25 then
                                        if IsUnitType(whichUnit, UNIT_TYPE_UNDEAD) then
                                            return false
                                        endif
                                    else
                                    //26
                                    endif
                                endif
                            else
                                if currentPosition > 20 then
                                    if currentPosition > 22 then
                                        if currentPosition == 23 then
                                            if IsUnitType(whichUnit, UNIT_TYPE_SUMMONED) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit, UNIT_TYPE_UNDEAD) then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 21 then
                                            if not IsUnitType(whichUnit, UNIT_TYPE_RANGED_ATTACKER) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit, UNIT_TYPE_SUMMONED) then
                                                return false
                                            endif
                                        endif
                                    endif
                                else
                                    if currentPosition > 18 then
                                        if currentPosition == 19 then
                                            if not IsUnitType(whichUnit, UNIT_TYPE_FLYING) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit, UNIT_TYPE_MELEE_ATTACKER) then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 17 then
                                            if IsUnitType(whichUnit, UNIT_TYPE_HERO) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit, UNIT_TYPE_GROUND) then
                                                return false
                                            endif
                                        endif
                                    endif
                                endif
                            endif
                        else
                            if currentPosition > 8 then
                                if currentPosition > 12 then
                                    if currentPosition > 14 then
                                        if currentPosition == 15 then
                                            if IsUnitType(whichUnit, UNIT_TYPE_ANCIENT) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit, UNIT_TYPE_HERO) then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 13 then
                                            if GetUnitAbilityLevel(whichUnit,udg_ABILITY_WARD_CLASSIFICATOR)!=0 then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit, UNIT_TYPE_ANCIENT) then
                                                return false
                                            endif
                                        endif
                                    endif
                                else
                                    if currentPosition > 10 then
                                        if currentPosition == 11 then
                                            if IsUnitType(whichUnit, UNIT_TYPE_MAGIC_IMMUNE) then
                                                return false
                                            endif
                                        else
                                            if GetUnitAbilityLevel(whichUnit,udg_ABILITY_WARD_CLASSIFICATOR)==0 then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 9 then
                                            if IsUnitVisible(whichUnit,GetOwningPlayer(sourceUnit)) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit, UNIT_TYPE_MAGIC_IMMUNE) then
                                                return false
                                            endif
                                        endif
                                    endif
                                endif
                            else
                                if currentPosition > 4 then
                                    if currentPosition > 6 then
                                        if currentPosition == 7 then
                                            if not IsUnitType(whichUnit,UNIT_TYPE_MECHANICAL) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitVisible(whichUnit,GetOwningPlayer(sourceUnit)) then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 5 then
                                            if IsUnitType(whichUnit,UNIT_TYPE_STRUCTURE) or IsUnitType(whichUnit,UNIT_TYPE_MECHANICAL) then
                                                return false
                                            endif
                                        else
                                            if not IsUnitType(whichUnit,UNIT_TYPE_STRUCTURE) then
                                                return false
                                            endif
                                        endif
                                    endif
                                else
                                    if currentPosition > 2 then
                                        if currentPosition == 3 then
                                            if GetWidgetLife(whichUnit)<=0.405 or IsUnitType(whichUnit,UNIT_TYPE_DEAD) then
                                                return false
                                            endif
                                        else
                                            if GetWidgetLife(whichUnit)>0.405 and IsUnitType(whichUnit,UNIT_TYPE_DEAD)==false then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 1 then
                                            if not IsUnitEnemy(whichUnit,GetOwningPlayer(sourceUnit)) then
                                                return false
                                            endif
                                        else
                                            if IsUnitEnemy(whichUnit,GetOwningPlayer(sourceUnit)) then
                                                return false
                                            endif
                                        endif
                                    endif
                                endif
                            endif
                        endif
                    endif
                    set currentPosition = currentPosition + 1
            endloop
            if GetUnitAbilityLevel(whichUnit,udg_ABILITY_DUMMY_CLASSIFICATOR)!=0 then
                return false
            endif
            return true
        endfunction
        
        function ItemFilter takes item whichItem, integer filter returns boolean
            local integer currentPosition = 1
            loop
                exitwhen filter == 0
                    if (filter - filter/bit[currentPosition]*bit[currentPosition])/bit[currentPosition-1]==1 then
                        set filter = filter - bit[currentPosition-1]
                        if currentPosition > 16 then
                            if currentPosition > 24 then
                                if currentPosition > 26 then
                                    if currentPosition == 27 then
                                    //27
                                    else
                                    //28
                                    endif
                                else
                                    if currentPosition == 25 then
                                    //25
                                    else
                                    //26
                                    endif
                                endif
                            else
                                if currentPosition > 20 then
                                    if currentPosition > 22 then
                                        if currentPosition == 23 then
                                            if not IsItemVisible(whichItem) then
                                                return false
                                            endif
                                        else
                                            if IsItemVisible(whichItem) then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 21 then
                                            if GetItemType(whichItem)!=ITEM_TYPE_MISCELLANEOUS then
                                                return false
                                            endif
                                        else
                                            if GetItemType(whichItem)==ITEM_TYPE_MISCELLANEOUS then
                                                return false
                                            endif
                                        endif
                                    endif
                                else
                                    if currentPosition > 18 then
                                        if currentPosition == 19 then
                                            if GetItemType(whichItem)!=ITEM_TYPE_CAMPAIGN then
                                                return false
                                            endif
                                        else
                                            if GetItemType(whichItem)==ITEM_TYPE_CAMPAIGN then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 17 then
                                            if GetItemType(whichItem)!=ITEM_TYPE_PURCHASABLE then
                                                return false
                                            endif
                                        else
                                            if GetItemType(whichItem)==ITEM_TYPE_PURCHASABLE then
                                                return false
                                            endif
                                        endif
                                    endif
                                endif
                            endif
                        else
                            if currentPosition > 8 then
                                if currentPosition > 12 then
                                    if currentPosition > 14 then
                                        if currentPosition == 15 then
                                            if GetItemType(whichItem)!=ITEM_TYPE_ARTIFACT then
                                                return false
                                            endif
                                        else
                                            if GetItemType(whichItem)==ITEM_TYPE_ARTIFACT then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 13 then
                                            if GetItemType(whichItem)!=ITEM_TYPE_POWERUP then
                                                return false
                                            endif
                                        else
                                            if GetItemType(whichItem)==ITEM_TYPE_POWERUP then
                                                return false
                                            endif
                                        endif
                                    endif
                                else
                                    if currentPosition > 10 then
                                        if currentPosition == 11 then
                                            if GetItemType(whichItem)!=ITEM_TYPE_CHARGED then
                                                return false
                                            endif
                                        else
                                            if GetItemType(whichItem)==ITEM_TYPE_CHARGED then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 9 then
                                            if GetItemType(whichItem)!=ITEM_TYPE_PERMANENT then
                                                return false
                                            endif
                                        else
                                            if GetItemType(whichItem)==ITEM_TYPE_PERMANENT then
                                                return false
                                            endif
                                        endif
                                    endif
                                endif
                            else
                                if currentPosition > 4 then
                                    if currentPosition > 6 then
                                        if currentPosition == 7 then
                                            if not IsItemPawnable(whichItem) then
                                                return false
                                            endif
                                        else
                                            if IsItemPawnable(whichItem) then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 5 then
                                            if not IsItemSellable(whichItem) then
                                                return false
                                            endif
                                        else
                                            if IsItemSellable(whichItem) then
                                                return false
                                            endif
                                        endif
                                    endif
                                else
                                    if currentPosition > 2 then
                                        if currentPosition == 3 then
                                            if not IsItemPowerup(whichItem) then
                                                return false
                                            endif
                                        else
                                            if IsItemPowerup(whichItem) then
                                                return false
                                            endif
                                        endif
                                    else
                                        if currentPosition == 1 then
                                            if not IsItemOwned(whichItem) then
                                                return false
                                            endif
                                        else
                                            if IsItemOwned(whichItem) then
                                                return false
                                            endif
                                        endif
                                    endif
                                endif
                            endif
                        endif
                    endif
                    set currentPosition = currentPosition + 1
            endloop
            return true
        endfunction
        
        function PlayerFilter takes player whichPlayer, player sourcePlayer, integer filter returns boolean
            local integer currentPosition = 1
            loop
                exitwhen filter == 0
                    if (filter - filter/bit[currentPosition]*bit[currentPosition])/bit[currentPosition-1]==1 then
                        set filter = filter - bit[currentPosition-1]
                        if currentPosition > 8 then
                            if currentPosition > 12 then
                                if currentPosition > 14 then
                                    if currentPosition == 15 then
                                    //15
                                    else
                                    //16
                                    endif
                                else
                                    if currentPosition == 13 then
                                    //13
                                    else
                                    //14
                                    endif
                                endif
                            else
                                if currentPosition > 10 then
                                    if currentPosition == 11 then
                                        if not GetPlayerAlliance(whichPlayer,sourcePlayer,ALLIANCE_SHARED_CONTROL) then
                                            return false
                                        endif
                                    else
                                        if GetPlayerAlliance(whichPlayer,sourcePlayer,ALLIANCE_SHARED_CONTROL) then
                                            return false
                                        endif
                                    endif
                                else
                                    if currentPosition == 9 then
                                        if not GetPlayerAlliance(whichPlayer,sourcePlayer,ALLIANCE_SHARED_VISION) then
                                            return false
                                        endif
                                    else
                                        if GetPlayerAlliance(whichPlayer,sourcePlayer,ALLIANCE_SHARED_VISION) then
                                            return false
                                        endif
                                    endif
                                endif
                            endif
                        else
                            if currentPosition > 4 then
                                if currentPosition > 6 then
                                    if currentPosition == 7 then
                                        if (not(whichPlayer==Player(12) or whichPlayer==Player(13) or whichPlayer==Player(14) or whichPlayer==Player(15))) then
                                            return false
                                        endif
                                    else
                                        if (whichPlayer==Player(12) or whichPlayer==Player(13) or whichPlayer==Player(14) or whichPlayer==Player(15)) then
                                            return false
                                        endif
                                    endif
                                else
                                    if currentPosition == 5 then
                                        if GetPlayerSlotState(whichPlayer)!=PLAYER_SLOT_STATE_PLAYING then
                                            return false
                                        endif
                                    else
                                        if GetPlayerSlotState(whichPlayer)!=PLAYER_SLOT_STATE_LEFT then
                                            return false
                                        endif
                                    endif
                                endif
                            else
                                if currentPosition > 2 then
                                    if currentPosition == 3 then
                                        if GetPlayerController(whichPlayer)!=MAP_CONTROL_USER then
                                            return false
                                        endif
                                    else
                                        if GetPlayerController(whichPlayer)!=MAP_CONTROL_USER then
                                            return false
                                        endif
                                    endif
                                else
                                    if currentPosition == 1 then
                                        if IsPlayerAlly(whichPlayer,sourcePlayer) then
                                            return false
                                        endif
                                    else
                                        if IsPlayerEnemy(whichPlayer,sourcePlayer) then
                                            return false
                                        endif
                                    endif
                                endif
                            endif
                        endif
                    endif
                    set currentPosition = currentPosition + 1
            endloop
            return true
        endfunction

    endlibrary
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Your loop is still terrible, try again

You don't need to iterate over every single bit, you can determine what bits are active with a binary search. I gave you the idea already.

if (filter < bit[14]) then
if (filter < bit[7]) then
if (filter < bit[3]) then

etc, same for the other way. When you center on a bit, you pop it off. If filter < bit[1], then filter is 0.
 
Level 4
Joined
Jul 4, 2012
Messages
78
you mean this?

JASS:
set currentPosition = 28    
loop
    if filter < bit[14] then
        if filter < bit[7] then
            if filter < bit[3] then
                if filter < bit[1] then
                    return true
                else
                    set currentPosition = 2
                endif
            else
                set currentPosition = 6
                ...
                ...
                ...
    set currentPosition = currentPosition - 1
 
Level 10
Joined
Sep 19, 2011
Messages
527
1) performance is increased by more than 5 times not a bit

yes, but when you see that performance in action, it doesn't really matter, does it? c:
what i'm saying, is that these optimisations are not worth it, the gain is too small.

2) now instead of memorizing or finding codes in API which are without any rule, you only need to type in: for example FS_UNIT_HERO + FS_UNIT_GROUND + FS_UNIT MELEE + FS_UNIT_NON_WARD + FS_UNIT_NON-SUMMONED which is easier to understand

well i personally prefer the "string" version, but this new version is also ok. just dont waste your time on silly optimisations (just do it, when it really needs it), my humble opinion.

however if people requested the stringed version, i'll keep it, we have no fight, have we?

Im-watching-you-meme.gif


haha, no we're ok xD
 
Level 4
Joined
Jul 4, 2012
Messages
78
not updated for a while, studying and learning new algorithms noted by Nestharus atm, as soon as i made the final version and Nestharus approved it, i'll update the main post with all 3 versions ( 1digit letter or number; 2 digit number; constants)
 
Level 4
Joined
Jul 4, 2012
Messages
78
JASS:
set currentPosition = 28    
loop
    if filter < bit[14] then
        if filter < bit[7] then
            if filter < bit[3] then
                if filter < bit[1] then
                    return true
                else
                    set currentPosition = 2
                endif
            else
                set currentPosition = 6
                ...
                ...
                ...
    set currentPosition = currentPosition - 1



so you mean its really ok, or just saying ok to stop me from asking questions from you? XD (take a joke)

edit: btw, reached 500 views :D it's now hot
 
Last edited:
Level 4
Joined
Jul 4, 2012
Messages
78
ok sry, i was busy with university stuff, Nestharus, i'm a real noob in algorithms, i was thinking about in for 2 days yet didn't find out anything useful, if you like do me a favor, create what you said and paste it here so i use it in my system ty as always xD
 
Level 4
Joined
Jul 4, 2012
Messages
78
:D thank you xD ........ then i have to put pressure on my tiny mind :)
also i did something interesting:
i created a loop without any pause to see how many of unit filters with 5 conditions can be run at a time, the result was this:

1) one digit number or letter : 226 at a time.
2) two digit number : 497 at a time.
3) constants : 384 at a time.

i think i have to make something very efficient to improve constants or all was done for nothing....
 
Level 4
Joined
Jul 4, 2012
Messages
78
sorry for being away for weeks, i was busy with university like HELL, due to huge pressure i hereby announce that i look for someone to take care of my system and continue updating it or complete the last method started until i the pressure on me drops off a bit. the primary credit will be then his/her not mine :)) thank you, pm me or post it here
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Couldn't he just filter out the bits by xor? I'm getting confused with the script, there's a lot of if blocks.
 
Top