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

Item Drop System 1.20


JASS:
/*

    ----------------------------------------------------------------------------------

    Item Drop System 1.20
        by Adiktuz
    
    ----------------------------------------------------------------------------------
    
    Description:
    
        A system that would allow the dynamic creation of item drop lists per UnitTypeId or
        per specific unit and handle the process of item dropping from killing monsters. 
    
   ----------------------------------------------------------------------------------
    
    Features:
        
        -You can add lots of items to the drop list of a unit ( max is defined by a global)*
        
        -You can dynamically specify the number of items that a single unit can drop upon death*
        
        -You can also add drop chance bonuses to a unit (direct or multiplier)
        
        -You can dynamically add or remove items from drop list of units*
        
        *can be both based on UnitTypeId or per specific unit
    
    ----------------------------------------------------------------------------------
    
    Requirements:
        - Wc3:TFT 1.24e
        - NewGenWE 
        - JassHelper (at least 0.A.2.A)
        - Ability to follow instructions
    
    ----------------------------------------------------------------------------------
    
    How to import:
        - Create a new trigger on your map, then convert to custom sript
        - Replace anything inside that trigger with the contents of this library
    
    ----------------------------------------------------------------------------------
    
    How to use the ItemDropSystem (general , UnitTypeId based):
        
        1) Initialize UnitTypeIds to use this system
            
            - use this call function to initialize each UnitTypeId that will use this system
                
                - call ItemDrop.InitUnit(integer UnitRawCode, integer DropItemsMax)
                
                *UnitRawCode is the rawcode of the unit
                
                *DropItemsMax is the maximum number of items from the pool that a dying unit of that
                 UnitTypeId can drop
                 
        2) Add items to the drop list of a UnitTypeId
            
            - use this call function to add items
                
                - call ItemDrop.AddItem(integer UnitRawCode, integer ItemRawCode, real Chance)
                
                *UnitRawCode is the rawcode of the unit where you want to add the item
                
                *ItemRawCode is the rawcode of the item
                
                *Chance is the percent chance to drop the item (from 0.01 up to 100.00)
            
            -Note: to avoid too much stress on computers, don't add so many items to a UnitTypeId
            
        3) To remove items from the drop list of a UnitTypeId
        
            - use this call function to remove items
            
                call ItemDrop.RemoveItems(integer UnitRawCode, integer ItemRawCode)
                
                *UnitRawCode is the rawcode of the unit where you want to add the item
                
                *ItemRawCode is the rawcode of the item
        
        4) To modify the max number of items that a single unit of a certain type can drop
            
            - use this call function
                
                call ItemDrop.ChangeDropMax(intger UnitRawCode, integer Max)
                
                *UnitRawCode is the rawcode of the unit where you want to modify the drop max
                
                *integer Max is the new maximum amount of items that a single unit of that type can drop
                 upon death
        
        5) To unregister a UnitTypeId
         
                call ItemDrop.Unregister(integer rawcode)
                
                *rawcode is the rawcode/UnitTypeId of the unit you want to unregister
    ----------------------------------------------------------------------------------
    
    How to use the ItemDropSystem (specific):
        
        1) Initialize the Unit to use this system
            
            - use this call function to initialize the unit that will use this system
                
                - call ItemDrop.InitUnitSpecific(unit u, integer DropItemsMax, boolean ProcessBoth)
                
                *u is the unit
                
                *DropItemsMax is the maximum number of items from the pool that the dying unit can drop
                
                *ProcessBoth checks if the system will process both the specific and general droplist for the unit
                if false, the system will only process the specific drop list
                 
        2) Add items to the drop list of a unit
            
            - use this call function to add items
                
                - call ItemDrop.AddItemSpecific(unit u, integer ItemRawCode, real Chance)
                
                *u is the unit where you want to add the item
                
                *ItemRawCode is the rawcode of the item
                
                *Chance is the percent chance to drop the item (from 0.01 up to 100.00)
            
            -Note: to avoid too much stress on computers, don't add so many items to a UnitTypeId
            
        3) To remove items from the drop list of a unit
        
            - use this call function to remove items
            
                call ItemDrop.RemoveItemSpecific(integer UnitRawCode, integer ItemRawCode)
                
                *u is the unit where you want to add the item
                
                *ItemRawCode is the rawcode of the item
        
        4) To modify the max number of items that a unit can drop upon death
            
            - use this call function
                
                call ItemDrop.ChangeDropMaxSpecific(unit u, integer Max)
                
                *u is the unit whom you want to modify the drop max
                
                *integer Max is the new maximum amount of items that a single unit of that type can drop
                 upon death
        
        5) To unregister a unit
         
                call ItemDrop.UnregisterSpecific(unit u)
                
                *u is the unit you want to unregister
    ----------------------------------------------------------------------------------
    If you want to force a drop process outside of unit death event use this
                
        call ItemDrop.ForceProcessDrop(unit dying, boolean IsSpecific, unit killer)
    ----------------------------------------------------------------------------------
    
*/

library ItemDropSystem requires BonusChance, RegisterPlayerUnitEvent

/*
    Version 1.20
    by Adiktuz
*/

    globals
        
        /*
            this sets the max number of items that a unit is allowed to have on its drop list
            
            the system will not allow you to add items to a drop list past this amount
            
            I suggest using a value of less than 100 since high numbers seem to cause the system
            to malfunction
        */
            
            private constant integer ITEMS_MAX = 10
            
        /*
            this is the color code of the error's text color
            
            *the default one here is red
        */
        
            private constant string ERROR_COLOR = "|cffff0000"
            private Table GenDrop
            private Table SpecDrop
            private Table DropBoth
    endglobals
    
    /*
        Do not edit below this line
    
        Start of main IDS codes
        
        Initializer module
    */
    
    private module IDS_initsystem
        
        /*
            this method registers the generic death event to trigger the start of the item drop processing
        */
        
        static method onInit takes nothing returns nothing
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.FilterDrop)
            set GenDrop = Table.create()
            set SpecDrop = Table.create()
            set DropBoth = Table.create()
        endmethod
        
    endmodule
    
    /*
        Struct which handles the IDS
    */
    
    struct ItemDrop
        
        static thistype data
        integer ItemsMax = 0
        integer DropItemsMax
        integer DropItemsMaxS
        integer array ItemList [ITEMS_MAX]
        real array Chance [ITEMS_MAX]
        
        /*
            Does the process of determining whether a unit will drop an item or items
        */
        
        method ProcessDrop takes unit dying, boolean IsSpecific, unit killer returns nothing
            /*
                necessary locals
            */
            local integer i = 0
            local integer dropped = 0
            local integer looped = 0
            local integer dropmax = 0
            /*
                I randomized the chance here rather than inside the loop because I think
                its just a useless waste of power if we randomize this for each item in the list
            */
            local real random = GetRandomReal(0.00,100.00)
            local real x = GetUnitX(dying)
            local real y = GetUnitY(dying)
            local boolean array IsLooped
            /*
                sets whether the max to be used is the specific or the general one
            */
            if IsSpecific then
                set dropmax = this.DropItemsMaxS
            else
                set dropmax = this.DropItemsMax
            endif
            /*
                the main process of the IDS
            */
            loop
                /*
                    I do this to make the run-through of the droplist randomized
                */
                set i = GetRandomInt(0, this.ItemsMax - 1)
                /*
                    This checks if the Item in the index has already been looped
                */
                if not IsLooped[i] then
                    /*
                        This checks if the item will be dropped or not
                        if the item is dropped, we increase the drop count
                    */
                    if random <= (((this.Chance[i])*BonusGetMulti(killer)) + BonusGetDirect(killer)) then
                        set dropped = dropped + 1
                        call CreateItem(this.ItemList[i], x, y)
                    endif
                    /*
                        we increase the loop count
                    */
                    set looped = looped + 1
                    /*
                        this ensures that an item that is already looped, won't be looped again
                    */
                    set IsLooped[i] = true
                endif
                /*
                    Once all the items in the drop list is looped
                    or if the unit already reach the maximum number of item drops,
                    the loop ends
                */
                exitwhen dropped >= dropmax or looped >= this.ItemsMax 
            endloop
        endmethod
        
        /*
            Checks if the dying unit is registered with the IDS
        */
        
        static method FilterDrop takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local thistype dat = GenDrop[GetUnitTypeId(u)]
            /*
                this line determines if the killer has an instance with the drop chance bonus system
            */
            local integer Handle = GetHandleId(u)
            /*
              checks if the unit has a specific drop list  
            */
            if SpecDrop[Handle] != 0 then
                /*
                    if yes, checks if both the individual and general drop list will be processed
                */
                if DropBoth[Handle] == 1 then
                    /*
                        if yes, processes the general list first
                    */
                    if dat != 0 then
                    /*
                        if the dying unit is registered with the IDS, the system now performs a run-through of the
                        droplist and determine whether the unit will drop items or not
                    */
                        call dat.ProcessDrop( u,false,GetKillingUnit())
                    endif
                endif
                set dat = SpecDrop[Handle]
                call dat.ProcessDrop(u,true,GetKillingUnit())
                /*
                    destroys the struct instance allocated for the specific drop pool of the unit
                */
                call dat.destroy()
            else
            /*
                if not, process only the general drop list
            */
                if dat != 0 then
                    /*
                        if the dying unit is registered with the IDS, the system now performs a run-through of the
                        droplist and determine whether the unit will drop items or not
                    */
                    call dat.ProcessDrop( u,false,GetKillingUnit())
                endif
            endif
            
            /*
                we clear the hashtable entry for that unit in the Hash, if the unit is not a hero
                since if its a hero, the data might still be needed
            */
            set u = null
            return false
        endmethod
        
        //The method for drop processing outside of death events
        static method ForceProcessDrop takes unit dying, boolean IsSpecific, unit killer returns nothing
            local integer i = 0
            local integer dropped = 0
            local integer looped = 0
            local integer dropmax = 0
            local real random = GetRandomReal(0.00,100.00)
            local real x = GetUnitX(dying)
            local real y = GetUnitY(dying)
            local boolean array IsLooped
            local thistype this = GenDrop[GetUnitTypeId(dying)]
            if IsSpecific then
                set this = SpecDrop[GetHandleId(dying)]
                set dropmax = this.DropItemsMaxS
            else
                set dropmax = this.DropItemsMax
            endif
            loop
                set i = GetRandomInt(0, this.ItemsMax - 1)
                if not IsLooped[i] then
                    if random <= (((this.Chance[i])*BonusGetMulti(killer)) + BonusGetDirect(killer)) then
                        set dropped = dropped + 1
                        call CreateItem(this.ItemList[i], x, y)
                    endif
                    set looped = looped + 1
                    set IsLooped[i] = true
                endif
                exitwhen dropped >= dropmax or looped >= this.ItemsMax 
            endloop
        endmethod
        
        /*
            The method for registering units into the IDS
        */
        
        static method InitUnit takes integer UnitRawCode, integer DropItemsMax returns nothing
            set data = .allocate()
            set GenDrop[UnitRawCode] = data
            set data.DropItemsMax = DropItemsMax
        endmethod
        
        /*
            The method for registering specific units into the IDS
        */
        
        static method InitUnitSpecific takes unit u, integer DropItemsMax, boolean ProcessBoth returns nothing
            local integer UnitCode = GetHandleId(u)
            set data = .allocate()
            set SpecDrop[UnitCode] = data
            if ProcessBoth then
                set DropBoth[UnitCode] = 1
            else
                set DropBoth[UnitCode] = 0
            endif
            set data.DropItemsMaxS = DropItemsMax
        endmethod
        
        /*
            The method for adding an ItemTypeId to the drop list of a UnitTypeId
        */
        
        static method AddItem takes integer UnitRawCode, integer ItemRawCode, real Chance returns nothing
            set data = GenDrop[UnitRawCode]
            /*
                The system will not allow addition of items to the drop list
                past the specified maximum to prevent malfunctions
            */
            if data.ItemsMax <= ITEMS_MAX then
                set data.ItemList[data.ItemsMax] = ItemRawCode
                set data.Chance[data.ItemsMax] = Chance
                set data.ItemsMax = data.ItemsMax + 1
            else
                static if DEBUG_MODE then
                    call BJDebugMsg(ERROR_COLOR + "Error: This unit has already reached the maximum number of items allowed in its droplist" + "|r")
                endif
            endif
        endmethod
        
        /*
            The method for adding an ItemTypeId to the drop list of a specific unit
        */
        
        static method AddItemSpecific takes unit u, integer ItemRawCode, real Chance returns nothing
            set data = SpecDrop[GetHandleId(u)]
            /*
                The system will not allow addition of items to the drop list
                past the specified maximum to prevent malfunctions
            */
            if data.ItemsMax <= ITEMS_MAX then
                set data.ItemList[data.ItemsMax] = ItemRawCode
                set data.Chance[data.ItemsMax] = Chance
                set data.ItemsMax = data.ItemsMax + 1
            else
                static if DEBUG_MODE then
                    call BJDebugMsg(ERROR_COLOR + "Error: This unit has already reached the maximum number of items allowed in its droplist" + "|r")
                endif
            endif
        endmethod
        
        /*
            The method for removing an ItemTypeId to the drop list of a UnitTypeId
        */
        
        static method RemoveItems takes integer UnitRawCode, integer ItemRawCode returns nothing
            local integer i = 0
            local boolean end = false
            set data = GenDrop[UnitRawCode]
            loop
                exitwhen end
                /*
                    if the rawcode saved on ItemList[i] is equal to the ItemRawCode,
                    the data on ItemList[i] is replaced with the data of the last saved item on the list
                    and the max number of items on the list is reduced by 1
                */
                if data.ItemList[i] == ItemRawCode then
                    set data.ItemsMax = data.ItemsMax - 1
                    set data.ItemList[i] = data.ItemList[data.ItemsMax]
                    set data.Chance[i] = data.Chance[data.ItemsMax]
                    set end = true
                else
                    set i = i + 1
                    if i >= data.ItemsMax then
                        set end = true
                        static if DEBUG_MODE then
                            call BJDebugMsg(ERROR_COLOR + "Error: The unit doesn't have the item in its drop list" + "|r")
                        endif
                    endif
                endif
            endloop
        endmethod
        
        /*
            The method for removing an ItemTypeId to the drop list of a specific unit
        */
        
        static method RemoveItemSpecific takes unit u, integer ItemRawCode returns nothing
            local integer i = 0
            local boolean end = false
            set data = SpecDrop[GetHandleId(u)]
            loop
                exitwhen end
                /*
                    if the rawcode saved on ItemList[i] is equal to the ItemRawCode,
                    the data on ItemList[i] is replaced with the data of the last saved item on the list
                    and the max number of items on the list is reduced by 1
                */
                if data.ItemList[i] == ItemRawCode then
                    set data.ItemsMax = data.ItemsMax - 1
                    set data.ItemList[i] = data.ItemList[data.ItemsMax]
                    set data.Chance[i] = data.Chance[data.ItemsMax]
                    set end = true
                else
                    set i = i + 1
                    if i >= data.ItemsMax then
                        set end = true
                        static if DEBUG_MODE then
                            call BJDebugMsg(ERROR_COLOR + "Error: The unit doesn't have the item in its drop list" + "|r")
                        endif
                    endif
                endif
            endloop
        endmethod
        
        /*
            this method is used to change the max number of items that a single unit of a UnitTypeId
            can drop upon death
        */
        
        static method ChangeDropMax takes integer UnitRawCode, integer Max returns nothing
            set data = GenDrop[UnitRawCode]
            set data.DropItemsMax = Max
        endmethod
        
        /*
            this method is used to change the max number of items that a single unit
            can drop upon death
        */
        
        static method ChangeDropMaxSpecific takes unit u, integer Max returns nothing
            set data = SpecDrop[GetHandleId(u)]
            set data.DropItemsMaxS = Max
        endmethod
        
        /*
            the following methods are used to unregister unittypeids or units from the system
        */
        static method Unregister takes integer rawcode returns nothing
            set data = GenDrop[rawcode]
            call data.deallocate()
        endmethod
        
        static method UnregisterSpecific takes unit u returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.deallocate()
        endmethod
        
        implement IDS_initsystem
        
    endstruct

endlibrary
JASS:
/*

    ----------------------------------------------------------------------------------

    Item Drop System MultiTable 1.20
        by Adiktuz
    
    ----------------------------------------------------------------------------------
    
    Description:
    
        A system that would allow the dynamic addition/removal of item drop tables per UnitTypeId or
        per specific unit and handle the process of item dropping from killing monsters. 
        
        This system utilizes the DropTable library for the creation/modification of
        drop tables
    
   ----------------------------------------------------------------------------------
    
    Features:
        
        -You can add lots of drop tables of a unit
        
        -You can dynamically specify the number of items that a single unit can drop upon death
        
        -You can dynamically add or remove drop tables from units*
    
    ----------------------------------------------------------------------------------
    
    Requirements:
        - Wc3:TFT 1.24e
        - NewGenWE 
        - JassHelper (at least 0.A.2.A)
        - Ability to follow instructions
    
    ----------------------------------------------------------------------------------
    
    How to import:
        - Create a new trigger on your map, then convert to custom sript
        - Replace anything inside that trigger with the contents of this library
    
    ----------------------------------------------------------------------------------
    
    How to use the ItemDropSystemMT (general , UnitTypeId based):
        
        1) Initialize UnitTypeIds to use this system
            
            - use this call function to initialize each UnitTypeId that will use this system
                
                - call ItemDropMT.InitUnit(integer UnitRawCode, integer DropItemsMax)
                
                *UnitRawCode is the rawcode of the unit
                
                *DropItemsMax is the maximum number of items from the pool that a dying unit of that
                 UnitTypeId can drop
                
                 
        2) Add drop table to a UnitTypeId
            
            - use this call function to add items
                
                - call ItemDropMT.AddPool(integer UnitRawCode, DropTable dtable, integer weight)
                
                *UnitRawCode is the rawcode of the unit where you want to add the drop table
                
                *dtable is the DropTable to be added
                
                *weight is related to the chance to use this drop table (chance = weight/totalweight)
            
            -Note: to avoid too much stress on computers, don't add so many items to a UnitTypeId
            
        3) To remove drop table from a UnitTypeId
        
            - use this call function to remove drop table
            
                call ItemDropMT.RemovePool(integer UnitRawCode, DropTable dtable)
                
                *UnitRawCode is the rawcode of the unit where you want to add the drop table
                
                *dtable is the DropTable to be removed
        
        4) To modify the max number of items that a single unit of a certain type can drop
            
            - use this call function
                
                call ItemDropMT.ChangeDropMax(intger UnitRawCode, integer Max)
                
                *UnitRawCode is the rawcode of the unit where you want to modify the drop max
                
                *integer Max is the new maximum amount of items that a single unit of that type can drop
                 upon death
        
        5) To unregister a UnitTypeId
         
                call ItemDropMT.Unregister(integer rawcode)
                
                *rawcode is the rawcode/UnitTypeId of the unit you want to unregister
    ----------------------------------------------------------------------------------
    
    How to use the ItemDropSystemMT (specific):
        
        1) Initialize the Unit to use this system
            
            - use this call function to initialize the unit that will use this system
                
                - call ItemDropMT.InitUnitSpecific(unit u, integer DropItemsMax, boolean ProcessBoth)
                
                *u is the unit
                
                *DropItemsMax is the maximum number of items from the pool that the dying unit can drop
                
                *ProcessBoth checks if the system will process both the specific and general droplist for the unit
                if false, the system will only process the specific drop list
                 
        2) Add drop table to a unit
            
            - use this call function to add drop tables
                
                - call ItemDropMT.AddPoolSpecific(unit u, DropTable dtable, integer weight)
                
                *u is the unit where you want to add the drop table
                
                *dtable is the Drop Table to be added
                
                *weight is related to the chance to use this drop table (chance = weight/totalweight)
            
        3) To remove drop table from a unit
        
            - use this call function to remove items
            
                call ItemDrop.RemovePoolSpecific(integer UnitRawCode, DropTable dtable)
                
                *u is the unit where you want to add the item
                
                *dtable is the Drop Table to be removed
        
        4) To modify the max number of items that a unit can drop upon death
            
            - use this call function
                
                call ItemDrop.ChangeDropMaxSpecific(unit u, integer Max)
                
                *u is the unit whom you want to modify the drop max
                
                *integer Max is the new maximum amount of items that a single unit of that type can drop
                 upon death
        
        5) To unregister a unit
         
                call ItemDrop.UnregisterSpecific(unit u)
                
                *u is the unit you want to unregister
    ----------------------------------------------------------------------------------
    If you want to force a drop process outside of unit death event use this
                
        call ItemDrop.ForceProcessDrop(unit dying, boolean IsSpecific, unit killer)
    ----------------------------------------------------------------------------------
    
*/


library ItemDropSystemMT requires BonusChance, RegisterPlayerUnitEvent, DropTable

    globals
            private constant string ERROR_COLOR = "|cffff0000"
            private Table GenDrop
            private Table SpecDrop
            private Table DropBoth
    endglobals
    
    /*
        Do not edit below this line
    
        Start of main IDS codes
        
        Initializer module
    */
    
    private module IDS_initsystem
        
        /*
            this method registers the generic death event to trigger the start of the item drop processing
        */
        
        static method onInit takes nothing returns nothing
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.FilterDrop)
            set GenDrop = Table.create()
            set SpecDrop = Table.create()
            set DropBoth = Table.create()
        endmethod
        
    endmodule
    
    /*
        Struct which handles the IDS
    */
    
    struct ItemDropMT
        
        static thistype data
        integer DropItemsMax
        integer DropItemsMaxS
        IPool DropT
        
        
        method ProcessDrop takes unit dying, boolean IsSpecific, unit killer returns nothing
            local integer i = 0
            local integer dropped = 0
            local integer looped = 0
            local integer dropmax = 0
            local real random = GetRandomReal(0.00,100.00)
            local real x = GetUnitX(dying)
            local real y = GetUnitY(dying)
            local boolean array IsLooped
            local DropTable itemlist = this.DropT.item
            if IsSpecific then
                set dropmax = this.DropItemsMaxS
            else
                set dropmax = this.DropItemsMax
            endif
            loop
                set i = GetRandomInt(0, itemlist.itemcount)
                if not IsLooped[i] then
                    if random <= (((itemlist.Chance[i])*BonusGetMulti(killer)) + BonusGetDirect(killer)) then
                        set dropped = dropped + 1
                        call CreateItem(itemlist.ItemList[i], x, y)
                    endif
                    set looped = looped + 1
                    set IsLooped[i] = true
                endif
                exitwhen dropped >= dropmax or looped >= itemlist.itemcount 
            endloop
        endmethod
        
        static method FilterDrop takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local thistype dat = GenDrop[GetUnitTypeId(u)]
            local integer Handle = GetHandleId(u)
            if SpecDrop[Handle] != 0 then
                if DropBoth[Handle] == 1 then
                    if dat != 0 then
                        call dat.ProcessDrop( u,false,GetKillingUnit())
                    endif
                endif
                set dat = SpecDrop[Handle]
                call dat.ProcessDrop(u,true,GetKillingUnit())
                call dat.destroy()
            else
                if dat != 0 then
                    call dat.ProcessDrop( u,false,GetKillingUnit())
                endif
            endif
            set u = null
            return false
        endmethod
        
        //The method for drop processing outside of death events
        static method ForceProcessDrop takes unit dying, boolean IsSpecific, unit killer returns nothing
            local integer i = 0
            local integer dropped = 0
            local integer looped = 0
            local integer dropmax = 0
            local real random = GetRandomReal(0.00,100.00)
            local real x = GetUnitX(dying)
            local real y = GetUnitY(dying)
            local boolean array IsLooped
            local thistype this = GenDrop[GetUnitTypeId(dying)]
            local DropTable itemlist = this.DropT.item
            if IsSpecific then
                set this = SpecDrop[GetHandleId(dying)]
                set dropmax = this.DropItemsMaxS
            else
                set dropmax = this.DropItemsMax
            endif
            loop
                set i = GetRandomInt(0, itemlist.itemcount)
                if not IsLooped[i] then
                    if random <= (((itemlist.Chance[i])*BonusGetMulti(killer)) + BonusGetDirect(killer)) then
                        set dropped = dropped + 1
                        call CreateItem(itemlist.ItemList[i], x, y)
                    endif
                    set looped = looped + 1
                    set IsLooped[i] = true
                endif
                exitwhen dropped >= dropmax or looped >= itemlist.itemcount 
            endloop
        endmethod
        
        static method InitUnit takes integer UnitRawCode, integer DropItemsMax returns nothing
            set data = .allocate()
            set GenDrop[UnitRawCode] = data
            set data.DropT = IPool.create()
            set data.DropItemsMax = DropItemsMax
        endmethod
        
        static method InitUnitSpecific takes unit u, integer DropItemsMax, boolean ProcessBoth returns nothing
            local integer UnitCode = GetHandleId(u)
            set data = .allocate()
            set SpecDrop[UnitCode] = data
            set data.DropT = IPool.create()
            if ProcessBoth then
                set DropBoth[UnitCode] = 1
            else
                set DropBoth[UnitCode] = 0
            endif
            set data.DropItemsMaxS = DropItemsMax
        endmethod
        
        static method AddPool takes integer UnitRawCode, DropTable dtPool, integer weight returns nothing
            set data = GenDrop[UnitRawCode]
            call data.DropT.add(dtPool, weight)
        endmethod
        
        static method AddPoolSpecific takes unit u, DropTable dtPool, integer weight returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.DropT.add(dtPool, weight)
        endmethod
        
        static method RemovePool takes integer UnitRawCode, DropTable dtPool returns nothing
            set data = GenDrop[UnitRawCode]
            call data.DropT.remove(dtPool)
        endmethod
        
        static method RemovePoolSpecific takes unit u, DropTable dtPool returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.DropT.remove(dtPool)
        endmethod
        
        static method Unregister takes integer rawcode returns nothing
            set data = GenDrop[rawcode]
            call data.DropT.destroy()
            call data.deallocate()
        endmethod
        
        static method UnregisterSpecific takes unit u returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.DropT.destroy()
            call data.deallocate()
        endmethod
        
        implement IDS_initsystem
        
    endstruct

endlibrary



JASS:
/*

    ----------------------------------------------------------------------------------

    Item Drop System 1.20 (Pool Version)
        by Adiktuz
    
    ----------------------------------------------------------------------------------
    
    Description:
    
        A system that would allow the dynamic creation of item pools per UnitTypeId or
        per specific unit and handle the process of item dropping from killing monsters. 
        
        This version is for creating an item pool for each unit in which the drop rates 
        of each item in a pool is dependent on each other. 
        
        In this version, whether an item will be dropped or not is determined per unit 
        or unit-type, and then the item that will be dropped will depend on the weight of 
        each item in the poolversus the whole pool. The drop chance of an item is equal to 
        its weight over the total weight of the item pool.
        
        Example Scenario:
        
        -I registered crabs to have a drop chance of 15%
        -Then I registered 3 items, each having a weight of 1
        -Then I registered another item having a weight of 3
        -Now the total weight would be 6
        -Now on the case that a crab dies, a number will be randomized
         from 0.00-100, if it falls under or equal to 15, that would mean that
         an item should be dropped, else no item will be dropped.
        -Now to get which item will be dropped from the crab's item pool, it will be
         randomized based on its weight relative to the total
        -that would mean that the 3 items having a weight of 1, each has a 1/6 chance
         of dropping while the fourth item which has a weight of 3 has a chance of
         3/6 or 50% chance that it would be the item which will be dropped.
        
    
   ----------------------------------------------------------------------------------
    
    Features:
        
        -You can add lots of items to the drop list of a unit
        
        -You can also add drop chance bonuses to a unit (direct or multiplier)
        
        -You can dynamically add or remove items from drop list of units*
        
        *can be both based on UnitTypeId or per specific unit
    
    ----------------------------------------------------------------------------------
    
    Requirements:
        - Wc3:TFT 1.24e
        - NewGenWE 
        - JassHelper (at least 0.A.2.A)
        - Table and IPool by Bribe
        - Ability to follow instructions
    
    ----------------------------------------------------------------------------------
    
    How to import:
        - Create a new trigger on your map, then convert to custom sript
        - Replace anything inside that trigger with the contents of this library
    
    ----------------------------------------------------------------------------------
    
    How to use: StructName = ItemDropPool
        
        General 
        
        static method InitUnit takes integer UnitRawCode, real chance, integer amount 
        -> registers the UnitRawCode into the system and sets its chance of dropping
           an item to real chance
        -> amount is the number of items that can be dropped at a time
           
        static method AddItem takes integer UnitRawCode, integer ItemRawCode, integer weight, integer amount
        -> registers an item into the itempool of UnitRawCode
        -> chance of having this item upon a successful drop roll is equal to the
           value of weight over the total weight of all registered items for that UnitRawCode
        -> amount is the number of items that can be dropped at a time
           
        static method RemoveItems takes integer UnitRawCode, integer ItemRawCode
        -> removes the specified item from the itempool of UnitRawCode
        
        static method Unregister takes integer rawcode returns nothing
        ->unregisters the rawcode from the system
        
        Specific
        
        static method InitUnitSpecific takes unit u, boolean ProcessBoth, real chance returns nothing
        -> registers a specific unit to the system
        -> if ProcessBoth is true, the system would process the ItemPool registered to this
           unit upon death, and also the itempool registered to the rawcode of this unit,
           which if both are present, will lead to 2 item drops if this unit dies and
           the roll chance falls within this unit's range
        
        static method AddItemSpecific takes unit u, integer ItemRawCode, integer weight
        -> adds the item to the itempool of the specific unit
        
        static method RemoveItemSpecific takes unit u, integer ItemRawCode
        -> removes the item from the itempool of the specific unit
        
        static method UnregisterSpecific takes unit u returns nothing
        -> unregisters the specific unit from the pool
        
        ----------------------------------------------------------------------------------
        If you want to force a drop process outside of unit death event use this
                
            call ItemDropPool.ForceProcessDrop(unit dying, boolean IsSpecific, unit killer)
        ----------------------------------------------------------------------------------
        
*/
    
     /*
        Do not edit below this line
    */
    
library ItemDropSystemPool requires IPool, BonusChance, RegisterPlayerUnitEvent
    
    
    globals
        private Table GenDrop
        private Table SpecDrop
        private Table DropBoth
    endglobals
    
   
    private module IDS_initsystem
        
        static method onInit takes nothing returns nothing
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.FilterDrop)
            set GenDrop = Table.create()
            set SpecDrop = Table.create()
            set DropBoth = Table.create()
        endmethod
        
    endmodule
    
    struct ItemDropPool
        
        static thistype data
        real chance
        IPool droppool
        integer amount
        
        static method ForceProcessDrop takes unit dying, boolean IsSpecific, unit killer returns nothing
            local real x = GetUnitX(dying)
            local real y = GetUnitY(dying)
            local thistype this = GenDrop[GetUnitTypeId(dying)]
            local integer i = 1
            if IsSpecific then
                set this = SpecDrop[GetHandleId(dying)]
            endif
            if GetRandomReal(0.00,100.00) <= this.chance*BonusGetMulti(killer) + BonusGetDirect(killer) then
                loop
                    exitwhen i > this.amount
                    call CreateItem(this.droppool.item, x, y)
                    set i = i + 1
                endloop
            endif
        endmethod
        
        method ProcessDrop takes unit killer, real x, real y returns nothing
            local integer i = 1
            if GetRandomReal(0.00,100.00) <= this.chance*BonusGetMulti(killer) + BonusGetDirect(killer) then
                loop
                    exitwhen i > this.amount
                    call CreateItem(this.droppool.item, x, y)
                    set i = i + 1
                endloop
            endif
        endmethod

        static method FilterDrop takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local integer i = GetHandleId(u)
            local integer a = GetUnitTypeId(GetTriggerUnit())
            local thistype this = GenDrop[a]
            local real x = GetUnitX(u)
            local real y = GetUnitY(u)
            if SpecDrop[i] != 0 then
                if DropBoth[i] == 1 and this != 0 then
                    call this.ProcessDrop(GetKillingUnit(), x, y)
                endif
                set this = SpecDrop[i]
                call this.ProcessDrop(GetKillingUnit(), x, y)
                if not IsUnitType(u, UNIT_TYPE_HERO) then
                    call this.droppool.destroy()
                endif
                call this.destroy()
            elseif this != 0 then
                call this.ProcessDrop(GetKillingUnit(), x, y)
            endif
            set u = null
            return false
        endmethod
        
        static method InitUnit takes integer UnitRawCode, real chance, integer amount returns nothing
            set data = .allocate()
            set data.droppool = IPool.create()
            set data.chance = chance
            set data.amount = amount
            set GenDrop[UnitRawCode] = data
        endmethod
        
        static method InitUnitSpecific takes unit u, boolean ProcessBoth, real chance, integer amount returns nothing
            local integer UnitCode = GetHandleId(u)
            set data = .allocate()
            set data.amount = amount
            set data.droppool = IPool.create()
            set data.chance = chance
            set SpecDrop[UnitCode] = data
            if ProcessBoth then
                set DropBoth[UnitCode] = 1
            else
                set DropBoth[UnitCode] = 0
            endif
        endmethod
        
        static method AddItem takes integer UnitRawCode, integer ItemRawCode, integer weight returns nothing
            set data = GenDrop[UnitRawCode]
            call data.droppool.add(ItemRawCode, weight)
        endmethod
        
        static method AddItemSpecific takes unit u, integer ItemRawCode, integer weight returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.droppool.add(ItemRawCode, weight)
        endmethod
        
        static method RemoveItems takes integer UnitRawCode, integer ItemRawCode returns nothing
            set data = GenDrop[UnitRawCode]
            call data.droppool.remove(ItemRawCode)
        endmethod
        
        static method RemoveItemSpecific takes unit u, integer ItemRawCode returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.droppool.remove(ItemRawCode)
        endmethod
        
        static method Unregister takes integer rawcode returns nothing
            set data = GenDrop[rawcode]
            call data.droppool.destroy()
            call data.deallocate()
        endmethod
        
        static method UnregisterSpecific takes unit u returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.droppool.destroy()
            call data.deallocate()
        endmethod
        
        implement IDS_initsystem
        
    endstruct

endlibrary


JASS:
/*
    ----------------------------------------------------------------------------------

    Item Drop System Multi Table 1.20 (Pool Version)
        by Adiktuz
    
    ----------------------------------------------------------------------------------
    
    Description:
    
        A system that would allow the dynamic addition/removal of Item pools per UnitTypeId or
        per specific unit and handle the process of item dropping from killing monsters. 
        
        Utilizes the IPool for creation/modification of item pools
        
    
   ----------------------------------------------------------------------------------
    
    Features:
        
        -You can add lots item pools to a unit
        
        -You can dynamically add or remove item pools from units
    
    ----------------------------------------------------------------------------------
    
    Requirements:
        - Wc3:TFT 1.24e
        - NewGenWE 
        - JassHelper (at least 0.A.2.A)
        - Table and IPool by Bribe
        - Ability to follow instructions
    
    ----------------------------------------------------------------------------------
    
    How to import:
        - Create a new trigger on your map, then convert to custom sript
        - Replace anything inside that trigger with the contents of this library
    
    ----------------------------------------------------------------------------------
    
    How to use: StructName = ItemDropPoolMT
        
        General 
        
        static method InitUnit takes integer UnitRawCode, real chance, integer amount 
        -> registers the UnitRawCode into the system and sets its chance of dropping
           an item to real chance
        -> amount is the number of items that can be dropped at a time
           
        static method AddPool takes integer UnitRawCode, IPool dtable, integer weight
        -> adds the item pool to the pools used by UnitRawCode
        -> chance of using this item pool upon a successful drop roll is equal to the
           value of weight over the total weight of all registered item pools for that UnitRawCode
           
        static method RemovePool takes integer UnitRawCode, IPool dtable
        -> removes the specified item pool from those used by the UnitRawCode
        
        static method Unregister takes integer rawcode returns nothing
        ->unregisters the rawcode from the system
        
        Specific
        
        static method InitUnitSpecific takes unit u, boolean ProcessBoth, real chance, integer amount returns nothing
        -> registers a specific unit to the system
        -> if ProcessBoth is true, the system would process the ItemPool registered to this
           unit upon death, and also the itempool registered to the rawcode of this unit,
           which if both are present, will lead to 2 item drops if this unit dies and
           the roll chance falls within this unit's range
        -> integer amount is the amount of items that the unit can drop upon death
        
        static method AddItemSpecific takes unit u, IPool dtable, integer weight
        -> adds the item pool to those used by the specific unit
        
        static method RemovePoolSpecific takes unit u, IPool dtable
        -> removes the item pool to those used by the specific unit
        
        static method UnregisterSpecific takes unit u returns nothing
        -> unregisters the specific unit from the pool
        
        ----------------------------------------------------------------------------------
        If you want to force a drop process outside of unit death event use this
                
            call ItemDropPool.ForceProcessDrop(unit dying, boolean IsSpecific, unit killer)
        ----------------------------------------------------------------------------------
        
*/
    
     /*
        Do not edit below this line
    */
    
library ItemDropSystemPoolMT requires BonusChance, RegisterPlayerUnitEvent
    
    
    globals
        private Table DropBoth
        private Table GenDrop
        private Table SpecDrop
    endglobals
    
   
    private module IDS_initsystem
        
        static method onInit takes nothing returns nothing
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.FilterDrop)
            set DropBoth = Table.create()
            set GenDrop = Table.create()
            set SpecDrop = Table.create()
        endmethod
        
    endmodule
    
    struct ItemDropPoolMT
        
        static thistype data
        static IPool dtable
        real chance
        IPool DropT
        integer amount
        
        static method ForceProcessDrop takes unit dying, boolean IsSpecific, unit killer returns nothing
            local real x = GetUnitX(dying)
            local real y = GetUnitY(dying)
            local thistype this = GenDrop[GetUnitTypeId(dying)]
            local integer i = 1
            set dtable = this.DropT.item
            if IsSpecific then
                set this = SpecDrop[GetHandleId(dying)]
                set dtable = this.DropT.item
            endif
            if GetRandomReal(0.00,100.00) <= this.chance*BonusGetMulti(killer) + BonusGetDirect(killer) then
                loop
                    exitwhen i > this.amount
                    call CreateItem(dtable.item, x, y)
                    set i = i + 1
                endloop
            endif
        endmethod
        
        method ProcessDrop takes unit killer, real x, real y returns nothing
            local integer i = 1
            set dtable = this.DropT.item
            if GetRandomReal(0.00,100.00) <= this.chance*BonusGetMulti(killer) + BonusGetDirect(killer) then
                loop
                    exitwhen i > this.amount
                    call CreateItem(dtable.item, x, y)
                    set i = i + 1
                endloop
            endif
        endmethod

        static method FilterDrop takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local integer i = GetHandleId(u)
            local integer a = GetUnitTypeId(GetTriggerUnit())
            local thistype this = GenDrop[a]
            local real x = GetUnitX(u)
            local real y = GetUnitY(u)
            if SpecDrop[i] != 0 then
                if DropBoth[i] == 1 and this != 0 then
                    call this.ProcessDrop(GetKillingUnit(), x, y)
                endif
                set this = SpecDrop[i]
                call this.ProcessDrop(GetKillingUnit(), x, y)
                if not IsUnitType(u, UNIT_TYPE_HERO) then
                    call this.DropT.destroy()
                endif
                call this.destroy()
            elseif this != 0 then
                call this.ProcessDrop(GetKillingUnit(), x, y)
            endif
            set u = null
            return false
        endmethod
        
        static method InitUnit takes integer UnitRawCode, real chance, integer amount returns nothing
            set data = .allocate()
            set data.DropT = IPool.create
            set data.amount = amount
            set GenDrop[UnitRawCode] = data
            set data.chance = chance
        endmethod
        
        static method InitUnitSpecific takes unit u, boolean ProcessBoth, real chance, integer amount returns nothing
            local integer UnitCode = GetHandleId(u)
            set data = .allocate()
            set data.DropT = IPool.create
            set data.amount = amount
            set data.chance = chance
            set SpecDrop[UnitCode] = data
            if ProcessBoth then
                set DropBoth[UnitCode] = 1
            else
                set DropBoth[UnitCode] = 0
            endif
        endmethod
        
        static method AddPool takes integer UnitRawCode, IPool dtPool, integer weight returns nothing
            set data = GenDrop[UnitRawCode]
            call data.DropT.add(dtPool, weight)
        endmethod
        
        static method AddPoolSpecific takes unit u, IPool dtPool, integer weight returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.DropT.add(dtPool, weight)
        endmethod
        
        static method RemovePool takes integer UnitRawCode, IPool dtPool returns nothing
            set data = GenDrop[UnitRawCode]
            call data.DropT.remove(dtPool)
        endmethod
        
        static method RemovePoolSpecific takes unit u, IPool dtPool returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.DropT.remove(dtPool)
        endmethod
        
        static method Unregister takes integer rawcode returns nothing
            set data = GenDrop[rawcode]
            call data.DropT.destroy()
            call data.deallocate()
        endmethod
        
        static method UnregisterSpecific takes unit u returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.DropT.destroy()
            call data.deallocate()
        endmethod
        
        implement IDS_initsystem
        
    endstruct

endlibrary
JASS:
scope AddItemsPMT initializer Init
    
    private function ApplyIDS takes nothing returns nothing
        //creates a new Item pool
        local IPool dtable = IPool.create()
        call DestroyTimer(GetExpiredTimer())
        //Orb of darkness is added to the item pool
        call dtable.add('odef',1)
        //Periapt of Vitality is added to the item pool
        call dtable.add('prvt',1)
        //now since both of them have weight of 1, and total weight is 2
        //they both have 50% chance to be dropped
        //rogue unit
        call ItemDropPoolMT.InitUnit('nrog', 100.0,1)
        //add the Drop Table to the rogue unit
        call ItemDropPoolMT.AddPool('nrog',dtable,1)
        //creates a new Drop Table Pool
        set dtable = IPool.create()
        //Circlet of nobility is added to the item pool
        call dtable.add('cnob',1)
        //Legion-Doom horn is added to the item pool
        call dtable.add('lgdh',1)
        //now since both of them have weight of 1, and total weight is 2
        //they both have 50% chance to be dropped
        //add the Drop Table to the rogue unit
        call ItemDropPoolMT.AddPool('nrog',dtable,1)
        //Now since both drop tables are registered to the rogue unit with a weight of 1,
        //each of them has a 50% to be chosen as the drop table to be used
        //when a rogue unit dies and triggers a drop
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TimerStart(CreateTimer(), 0.01, false, function ApplyIDS)
    endfunction
    
endscope



JASS:
/*

    ----------------------------------------------------------------------------------

    Item Drop System 1.20 (Destructable Version)
        by Adiktuz
    
    ----------------------------------------------------------------------------------
    
    -Works almost the same as the original Pool version but for destructables.
    -Also, you need to manually set when the drop is processed
    -for most of the functions here, when it takes the unitrawcode as parameter, its just replaced with
    the destructable raw code while if it takes a unit as parameter, its just replaced with a destructable

    example:
        call ItemDropPoolDest.InitDest(integer DestRawCode, real chance)
        call ItemDropPoolDest.InitDestSpecific(destructable u, boolean ProcessBoth, real chance)
        
    To call for processing of a drop: (look at the sample trigger for better understanding)
        call ItemDropPoolDest.ForceProcessDrop(destructable u, boolean IsSpecific, unit killer)
    
    To clear the drop allocated to a destructable:
        call ItemDropPoolDest.UnregisterSpecific(destructable u)
        call ItemDropPoolDest.Unregister(integer DestRawCode)
    
    Functions list:
        call ItemDropPoolDest.InitDest(integer DestRawCode, real chance, integer amount)
        call ItemDropPoolDest.InitDestSpecific(destructable u, boolean ProcessBoth, real chance, integer amount)
        call ItemDropPoolDest.ForceProcessDrop(destructable u, boolean IsSpecific, unit killer)
        call ItemDropPoolDest.AddItem(integer DestRawCode, integer ItemRawCode, integer weight)
        call ItemDropPoolDest.AddItemSpecific(destructable u, integer ItemRawCode, integer weight)
        call ItemDropPoolDest.RemoveItems(integer DestRawCode, integer ItemRawCode)
        call ItemDropPoolDest.RemoveItemSpecific(destructable u, integer ItemRawCode)
        call ItemDropPoolDest.UnregisterSpecific(destructable u)
        call ItemDropPoolDest.Unregister(integer DestRawCode)
        
    It would also be better if you will unregister specific drops allocated to a destructable
    when it dies.
*/
    
     /*
        Do not edit below this line
    */
    
library ItemDropSystemPoolDestructable requires IPool, BonusChance
    
    
    globals
        private Table GenDrop
        private Table SpecDrop
        private Table DropBoth
    endglobals
    
   
    private module IDS_initsystem
        
        static method onInit takes nothing returns nothing
            set GenDrop = Table.create()
            set SpecDrop = Table.create()
            set DropBoth = Table.create()
        endmethod
        
    endmodule
    
    struct ItemDropPoolDest
        
        static thistype data
        real chance
        integer amount
        IPool droppool
        
        static method ForceProcessDrop takes destructable u, boolean IsSpecific, unit killer returns nothing
            local real x = GetDestructableX(u)
            local real y = GetDestructableY(u)
            local thistype this = GenDrop[GetDestructableTypeId(u)]
            local integer i = 1
            if IsSpecific then
                set this = SpecDrop[GetHandleId(u)]
            endif
            if GetRandomReal(0.00,100.00) <= this.chance*BonusGetMulti(killer) + BonusGetDirect(killer) then
                loop
                    exitwhen i > this.amount
                    call CreateItem(this.droppool.item, x, y)
                    set i = i + 1
                endloop
            endif
        endmethod
        
        static method ClearDest takes destructable u returns nothing
            local thistype this = SpecDrop[GetHandleId(u)]
            call this.destroy()
            call this.droppool.destroy()
        endmethod
        
        static method InitDest takes integer DestRawCode, real chance, integer amount returns nothing
            set data = .allocate()
            set data.droppool = IPool.create()
            set data.chance = chance
            set data.amount = amount
            set GenDrop[DestRawCode] = data
        endmethod
        
        static method InitDestSpecific takes destructable u, boolean ProcessBoth, real chance, integer amount returns nothing
            local integer UnitCode = GetHandleId(u)
            set data = .allocate()
            set data.droppool = IPool.create()
            set data.chance = chance
            set data.amount = amount
            set SpecDrop[UnitCode] = data
            if ProcessBoth then
                set DropBoth[UnitCode] = 1
            else
                set DropBoth[UnitCode] = 0
            endif
        endmethod
        
        static method AddItem takes integer DestRawCode, integer ItemRawCode, integer weight returns nothing
            set data = GenDrop[DestRawCode]
            call data.droppool.add(ItemRawCode, weight)
        endmethod
        
        static method AddItemSpecific takes destructable u, integer ItemRawCode, integer weight returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.droppool.add(ItemRawCode, weight)
        endmethod
        
        static method RemoveItems takes integer DestRawCode, integer ItemRawCode returns nothing
            set data = GenDrop[DestRawCode]
            call data.droppool.remove(ItemRawCode)
        endmethod
        
        static method RemoveItemSpecific takes destructable u, integer ItemRawCode returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.droppool.remove(ItemRawCode)
        endmethod
        
        static method Unregister takes integer rawcode returns nothing
            set data = GenDrop[rawcode]
            call data.droppool.destroy()
            call data.deallocate()
        endmethod
        
        static method UnregisterSpecific takes destructable u returns nothing
            set data = SpecDrop[GetHandleId(u)]
            call data.droppool.destroy()
            call data.deallocate()
        endmethod
        
        implement IDS_initsystem
        
    endstruct

endlibrary


I recommend using the Pool versions...



Changelog
JASS:
/*
    ----------------------------------------------------------------------------------

Version 1.10

-Saved the instance index into a hashtable

-replaced the Get intances with Hashtable function calls

-Added the functionality to use the IDS for specific units

    ----------------------------------------------------------------------------------

Version 1.11

-removed unnecessary variables

    ----------------------------------------------------------------------------------

Version 1.12

-it now destroys the struct instance for specific unit item pools when the unit dies

    ----------------------------------------------------------------------------------

Version 1.13
-changed the debug messages into static ifs
-renamed the struct to IDS_Adik
-removed the local boolean used to exit the drop loop
-fixed errors on the How To Use

    ----------------------------------------------------------------------------------

Version 1.13b
-fixed a flaw which reduces the chances of having an item drop (by making the loop run through an unused index)
Note: The code in the map might actually say 1.13 or 1.12... ignore it...


    ----------------------------------------------------------------------------------

Version 1.13c
-added Unregister methods. I'm not sure if it would be totally useful though, but added it anyway.

    ----------------------------------------------------------------------------------

Version 1.14
-optimized the code, removed unnecessary things
-separated the BonusChance functions into another library
-created another version which uses IPool (read code for details)

    ----------------------------------------------------------------------------------

Version 1.14b
-some minor optimizations as pointed out by Magtheridon96

    ----------------------------------------------------------------------------------

Version 1.14c
-changed the struct names (just use ctrl+H to change them on your codes which uses this system)
-Made it use RegisterPlayerEvent (by Magtheridon)
-Removed the hashtables and used Tables instead (3 tables per System as I realized that one of the booleans I save on the hashtable is unnecessary)

    ----------------------------------------------------------------------------------

Version 1.14d
-removed the boolean SHOW_ERROR and used DEBUG_MODE instead
-also fixed the internal version number of the ItemDropSystem
-Removed the InitHashtable call from the Pool version and updated the code on the description

    ----------------------------------------------------------------------------------

Version 1.15
-added functions for forcing the drop process outside of death events for the unit drops
-added a library for processing drops for destructable (pool version only)
-fixed a flaw on the bonuschance library which causes the drop chance to be 0.0 if the killing unit is not registered in the bonuschance library

    ----------------------------------------------------------------------------------

Version 1.20
-Added a multi-table versions
 *This update has actually been long done on my comp, just forgot to upload it.
*/

Why have I made it?
JASS:
/*
   
    well, I was thinking of a new system to make and then this idea got to my head. Then I

browsed thru the spells section looking if there is already one but the ones which showed 

up on the search were unflexible so I decided to do it... ^_^


    I think this could be really useful for maps especially RPGs and the like...

*/

Credits to Bribe for his moderation and for his two libraries (Table and IPool) and for Magtheridon96 for RegisterPlayerEvent

Keywords:
system, inventory, items, drop, death, spawn, mob, jass, vjass, codes, triggers, we, warcraft, ragnarok, rpg, role palying, games, orpg, destructables
Contents

ItemDropSystem 1.20 (Map)

Reviews
12 Nov 2011 Bribe: You should delete this line from ItemDropSystemPool: "private hashtable Hash = InitHashtable()" (since you don't use it). Other than that, this is a really great item drop system. Approved.
Top