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.
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
*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
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)
----------------------------------------------------------------------------------
/*
Does the process of determining whether a unit will drop an item or items
*/
method ProcessDrop takesunit dying,boolean IsSpecific,unit killer returnsnothing /*
necessary locals
*/ localinteger i =0 localinteger dropped =0 localinteger looped =0 localinteger 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
*/ localreal random =GetRandomReal(0.00,100.00) localreal x =GetUnitX(dying) localreal y =GetUnitY(dying) localbooleanarray 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
*/ ifnot 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 callCreateItem(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
*/
staticmethod FilterDrop takesnothingreturnsboolean localunit u =GetTriggerUnit() localthistype dat = GenDrop[GetUnitTypeId(u)] /*
this line determines if the killer has an instance with the drop chance bonus system
*/ localinteger Handle =GetHandleId(u) /*
checks if the unit has a specific drop list
*/ if SpecDrop[Handle] !=0then /*
if yes, checks if both the individual and general drop list will be processed
*/ if DropBoth[Handle]==1then /*
if yes, processes the general list first
*/ if dat !=0then /*
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 !=0then /*
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 returnfalse endmethod
//The method for drop processing outside of death events staticmethod ForceProcessDrop takesunit dying,boolean IsSpecific,unit killer returnsnothing localinteger i =0 localinteger dropped =0 localinteger looped =0 localinteger dropmax =0 localreal random =GetRandomReal(0.00,100.00) localreal x =GetUnitX(dying) localreal y =GetUnitY(dying) localbooleanarray IsLooped localthistypethis= GenDrop[GetUnitTypeId(dying)] if IsSpecific then setthis= SpecDrop[GetHandleId(dying)] set dropmax =this.DropItemsMaxS else set dropmax =this.DropItemsMax endif loop set i =GetRandomInt(0,this.ItemsMax-1) ifnot IsLooped[i]then if random <=(((this.Chance[i])*BonusGetMulti(killer))+ BonusGetDirect(killer))then set dropped = dropped +1 callCreateItem(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
*/
staticmethod InitUnit takesinteger UnitRawCode,integer DropItemsMax returnsnothing set data =.allocate() set GenDrop[UnitRawCode]= data set data.DropItemsMax= DropItemsMax endmethod
/*
The method for registering specific units into the IDS
*/
staticmethod InitUnitSpecific takesunit u,integer DropItemsMax,boolean ProcessBoth returnsnothing localinteger 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
*/
staticmethod AddItem takesinteger UnitRawCode,integer ItemRawCode,real Chance returnsnothing 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 staticif DEBUG_MODE then callBJDebugMsg(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
*/
staticmethod AddItemSpecific takesunit u,integer ItemRawCode,real Chance returnsnothing 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 staticif DEBUG_MODE then callBJDebugMsg(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
*/
staticmethod RemoveItems takesinteger UnitRawCode,integer ItemRawCode returnsnothing localinteger i =0 localboolean 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.ItemsMaxthen set end =true staticif DEBUG_MODE then callBJDebugMsg(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
*/
staticmethod RemoveItemSpecific takesunit u,integer ItemRawCode returnsnothing localinteger i =0 localboolean 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.ItemsMaxthen set end =true staticif DEBUG_MODE then callBJDebugMsg(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
*/
staticmethod ChangeDropMax takesinteger UnitRawCode,integer Max returnsnothing 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
*/
staticmethod ChangeDropMaxSpecific takesunit u,integer Max returnsnothing set data = SpecDrop[GetHandleId(u)] set data.DropItemsMaxS= Max endmethod
/*
the following methods are used to unregister unittypeids or units from the system
*/ staticmethod Unregister takesinteger rawcode returnsnothing set data = GenDrop[rawcode] call data.deallocate() endmethod
staticmethod UnregisterSpecific takesunit u returnsnothing set data = SpecDrop[GetHandleId(u)] call data.deallocate() endmethod
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
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
*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)
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)
----------------------------------------------------------------------------------
/*
this method registers the generic death event to trigger the start of the item drop processing
*/
staticmethod onInit takesnothingreturnsnothing call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,functionthistype.FilterDrop) set GenDrop = Table.create() set SpecDrop = Table.create() set DropBoth = Table.create() endmethod
endmodule
/*
Struct which handles the IDS
*/
struct ItemDropMT
staticthistype data integer DropItemsMax integer DropItemsMaxS
IPool DropT
method ProcessDrop takesunit dying,boolean IsSpecific,unit killer returnsnothing localinteger i =0 localinteger dropped =0 localinteger looped =0 localinteger dropmax =0 localreal random =GetRandomReal(0.00,100.00) localreal x =GetUnitX(dying) localreal y =GetUnitY(dying) localbooleanarray 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) ifnot IsLooped[i]then if random <=(((itemlist.Chance[i])*BonusGetMulti(killer))+ BonusGetDirect(killer))then set dropped = dropped +1 callCreateItem(itemlist.ItemList[i], x, y) endif set looped = looped +1 set IsLooped[i]=true endif exitwhen dropped >= dropmax or looped >= itemlist.itemcount endloop endmethod
staticmethod FilterDrop takesnothingreturnsboolean localunit u =GetTriggerUnit() localthistype dat = GenDrop[GetUnitTypeId(u)] localinteger Handle =GetHandleId(u) if SpecDrop[Handle] !=0then if DropBoth[Handle]==1then if dat !=0then call dat.ProcessDrop( u,false,GetKillingUnit()) endif endif set dat = SpecDrop[Handle] call dat.ProcessDrop(u,true,GetKillingUnit()) call dat.destroy() else if dat !=0then call dat.ProcessDrop( u,false,GetKillingUnit()) endif endif set u =null returnfalse endmethod
//The method for drop processing outside of death events staticmethod ForceProcessDrop takesunit dying,boolean IsSpecific,unit killer returnsnothing localinteger i =0 localinteger dropped =0 localinteger looped =0 localinteger dropmax =0 localreal random =GetRandomReal(0.00,100.00) localreal x =GetUnitX(dying) localreal y =GetUnitY(dying) localbooleanarray IsLooped localthistypethis= GenDrop[GetUnitTypeId(dying)] local DropTable itemlist =this.DropT.item if IsSpecific then setthis= SpecDrop[GetHandleId(dying)] set dropmax =this.DropItemsMaxS else set dropmax =this.DropItemsMax endif loop set i =GetRandomInt(0, itemlist.itemcount) ifnot IsLooped[i]then if random <=(((itemlist.Chance[i])*BonusGetMulti(killer))+ BonusGetDirect(killer))then set dropped = dropped +1 callCreateItem(itemlist.ItemList[i], x, y) endif set looped = looped +1 set IsLooped[i]=true endif exitwhen dropped >= dropmax or looped >= itemlist.itemcount endloop endmethod
staticmethod InitUnit takesinteger UnitRawCode,integer DropItemsMax returnsnothing set data =.allocate() set GenDrop[UnitRawCode]= data set data.DropT= IPool.create() set data.DropItemsMax= DropItemsMax endmethod
staticmethod InitUnitSpecific takesunit u,integer DropItemsMax,boolean ProcessBoth returnsnothing localinteger 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
staticmethod AddPool takesinteger UnitRawCode, DropTable dtPool,integer weight returnsnothing set data = GenDrop[UnitRawCode] call data.DropT.add(dtPool, weight) endmethod
staticmethod AddPoolSpecific takesunit u, DropTable dtPool,integer weight returnsnothing set data = SpecDrop[GetHandleId(u)] call data.DropT.add(dtPool, weight) endmethod
staticmethod RemovePool takesinteger UnitRawCode, DropTable dtPool returnsnothing set data = GenDrop[UnitRawCode] call data.DropT.remove(dtPool) endmethod
staticmethod RemovePoolSpecific takesunit u, DropTable dtPool returnsnothing set data = SpecDrop[GetHandleId(u)] call data.DropT.remove(dtPool) endmethod
staticmethod Unregister takesinteger rawcode returnsnothing set data = GenDrop[rawcode] call data.DropT.destroy() call data.deallocate() endmethod
staticmethod UnregisterSpecific takesunit u returnsnothing set data = SpecDrop[GetHandleId(u)] call data.DropT.destroy() call data.deallocate() endmethod
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.
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
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)
----------------------------------------------------------------------------------
staticmethod onInit takesnothingreturnsnothing call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,functionthistype.FilterDrop) set GenDrop = Table.create() set SpecDrop = Table.create() set DropBoth = Table.create() endmethod
endmodule
struct ItemDropPool
staticthistype data real chance
IPool droppool integer amount
staticmethod ForceProcessDrop takesunit dying,boolean IsSpecific,unit killer returnsnothing localreal x =GetUnitX(dying) localreal y =GetUnitY(dying) localthistypethis= GenDrop[GetUnitTypeId(dying)] localinteger i =1 if IsSpecific then setthis= SpecDrop[GetHandleId(dying)] endif ifGetRandomReal(0.00,100.00)<=this.chance*BonusGetMulti(killer)+ BonusGetDirect(killer)then loop exitwhen i >this.amount callCreateItem(this.droppool.item, x, y) set i = i +1 endloop endif endmethod
method ProcessDrop takesunit killer,real x,real y returnsnothing localinteger i =1 ifGetRandomReal(0.00,100.00)<=this.chance*BonusGetMulti(killer)+ BonusGetDirect(killer)then loop exitwhen i >this.amount callCreateItem(this.droppool.item, x, y) set i = i +1 endloop endif endmethod
staticmethod FilterDrop takesnothingreturnsboolean localunit u =GetTriggerUnit() localinteger i =GetHandleId(u) localinteger a =GetUnitTypeId(GetTriggerUnit()) localthistypethis= GenDrop[a] localreal x =GetUnitX(u) localreal y =GetUnitY(u) if SpecDrop[i] !=0then if DropBoth[i]==1andthis !=0then callthis.ProcessDrop(GetKillingUnit(), x, y) endif setthis= SpecDrop[i] callthis.ProcessDrop(GetKillingUnit(), x, y) ifnotIsUnitType(u,UNIT_TYPE_HERO)then callthis.droppool.destroy() endif callthis.destroy() elseifthis !=0then callthis.ProcessDrop(GetKillingUnit(), x, y) endif set u =null returnfalse endmethod
staticmethod InitUnit takesinteger UnitRawCode,real chance,integer amount returnsnothing set data =.allocate() set data.droppool= IPool.create() set data.chance= chance set data.amount= amount set GenDrop[UnitRawCode]= data endmethod
staticmethod InitUnitSpecific takesunit u,boolean ProcessBoth,real chance,integer amount returnsnothing localinteger 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
staticmethod AddItem takesinteger UnitRawCode,integer ItemRawCode,integer weight returnsnothing set data = GenDrop[UnitRawCode] call data.droppool.add(ItemRawCode, weight) endmethod
staticmethod AddItemSpecific takesunit u,integer ItemRawCode,integer weight returnsnothing set data = SpecDrop[GetHandleId(u)] call data.droppool.add(ItemRawCode, weight) endmethod
staticmethod RemoveItems takesinteger UnitRawCode,integer ItemRawCode returnsnothing set data = GenDrop[UnitRawCode] call data.droppool.remove(ItemRawCode) endmethod
staticmethod RemoveItemSpecific takesunit u,integer ItemRawCode returnsnothing set data = SpecDrop[GetHandleId(u)] call data.droppool.remove(ItemRawCode) endmethod
staticmethod Unregister takesinteger rawcode returnsnothing set data = GenDrop[rawcode] call data.droppool.destroy() call data.deallocate() endmethod
staticmethod UnregisterSpecific takesunit u returnsnothing set data = SpecDrop[GetHandleId(u)] call data.droppool.destroy() call data.deallocate() endmethod
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
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
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)
----------------------------------------------------------------------------------
staticmethod onInit takesnothingreturnsnothing call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,functionthistype.FilterDrop) set DropBoth = Table.create() set GenDrop = Table.create() set SpecDrop = Table.create() endmethod
endmodule
struct ItemDropPoolMT
staticthistype data static IPool dtable real chance
IPool DropT integer amount
staticmethod ForceProcessDrop takesunit dying,boolean IsSpecific,unit killer returnsnothing localreal x =GetUnitX(dying) localreal y =GetUnitY(dying) localthistypethis= GenDrop[GetUnitTypeId(dying)] localinteger i =1 set dtable =this.DropT.item if IsSpecific then setthis= SpecDrop[GetHandleId(dying)] set dtable =this.DropT.item endif ifGetRandomReal(0.00,100.00)<=this.chance*BonusGetMulti(killer)+ BonusGetDirect(killer)then loop exitwhen i >this.amount callCreateItem(dtable.item, x, y) set i = i +1 endloop endif endmethod
method ProcessDrop takesunit killer,real x,real y returnsnothing localinteger i =1 set dtable =this.DropT.item ifGetRandomReal(0.00,100.00)<=this.chance*BonusGetMulti(killer)+ BonusGetDirect(killer)then loop exitwhen i >this.amount callCreateItem(dtable.item, x, y) set i = i +1 endloop endif endmethod
staticmethod FilterDrop takesnothingreturnsboolean localunit u =GetTriggerUnit() localinteger i =GetHandleId(u) localinteger a =GetUnitTypeId(GetTriggerUnit()) localthistypethis= GenDrop[a] localreal x =GetUnitX(u) localreal y =GetUnitY(u) if SpecDrop[i] !=0then if DropBoth[i]==1andthis !=0then callthis.ProcessDrop(GetKillingUnit(), x, y) endif setthis= SpecDrop[i] callthis.ProcessDrop(GetKillingUnit(), x, y) ifnotIsUnitType(u,UNIT_TYPE_HERO)then callthis.DropT.destroy() endif callthis.destroy() elseifthis !=0then callthis.ProcessDrop(GetKillingUnit(), x, y) endif set u =null returnfalse endmethod
staticmethod InitUnit takesinteger UnitRawCode,real chance,integer amount returnsnothing set data =.allocate() set data.DropT= IPool.create set data.amount= amount set GenDrop[UnitRawCode]= data set data.chance= chance endmethod
staticmethod InitUnitSpecific takesunit u,boolean ProcessBoth,real chance,integer amount returnsnothing localinteger 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
staticmethod AddPool takesinteger UnitRawCode, IPool dtPool,integer weight returnsnothing set data = GenDrop[UnitRawCode] call data.DropT.add(dtPool, weight) endmethod
staticmethod AddPoolSpecific takesunit u, IPool dtPool,integer weight returnsnothing set data = SpecDrop[GetHandleId(u)] call data.DropT.add(dtPool, weight) endmethod
staticmethod RemovePool takesinteger UnitRawCode, IPool dtPool returnsnothing set data = GenDrop[UnitRawCode] call data.DropT.remove(dtPool) endmethod
staticmethod RemovePoolSpecific takesunit u, IPool dtPool returnsnothing set data = SpecDrop[GetHandleId(u)] call data.DropT.remove(dtPool) endmethod
staticmethod Unregister takesinteger rawcode returnsnothing set data = GenDrop[rawcode] call data.DropT.destroy() call data.deallocate() endmethod
staticmethod UnregisterSpecific takesunit u returnsnothing set data = SpecDrop[GetHandleId(u)] call data.DropT.destroy() call data.deallocate() endmethod
implement IDS_initsystem
endstruct
endlibrary
Jass:
scope AddItemsPMT initializer Init
privatefunction ApplyIDS takesnothingreturnsnothing //creates a new Item pool local IPool dtable = IPool.create() callDestroyTimer(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
privatefunction Init takesnothingreturnsnothing localtrigger t =CreateTrigger() callTimerStart(CreateTimer(),0.01,false,function ApplyIDS) endfunction
-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.
*/
staticmethod onInit takesnothingreturnsnothing set GenDrop = Table.create() set SpecDrop = Table.create() set DropBoth = Table.create() endmethod
endmodule
struct ItemDropPoolDest
staticthistype data real chance integer amount
IPool droppool
staticmethod ForceProcessDrop takesdestructable u,boolean IsSpecific,unit killer returnsnothing localreal x =GetDestructableX(u) localreal y =GetDestructableY(u) localthistypethis= GenDrop[GetDestructableTypeId(u)] localinteger i =1 if IsSpecific then setthis= SpecDrop[GetHandleId(u)] endif ifGetRandomReal(0.00,100.00)<=this.chance*BonusGetMulti(killer)+ BonusGetDirect(killer)then loop exitwhen i >this.amount callCreateItem(this.droppool.item, x, y) set i = i +1 endloop endif endmethod
staticmethod ClearDest takesdestructable u returnsnothing localthistypethis= SpecDrop[GetHandleId(u)] callthis.destroy() callthis.droppool.destroy() endmethod
staticmethod InitDest takesinteger DestRawCode,real chance,integer amount returnsnothing set data =.allocate() set data.droppool= IPool.create() set data.chance= chance set data.amount= amount set GenDrop[DestRawCode]= data endmethod
staticmethod InitDestSpecific takesdestructable u,boolean ProcessBoth,real chance,integer amount returnsnothing localinteger 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
staticmethod AddItem takesinteger DestRawCode,integer ItemRawCode,integer weight returnsnothing set data = GenDrop[DestRawCode] call data.droppool.add(ItemRawCode, weight) endmethod
staticmethod AddItemSpecific takesdestructable u,integer ItemRawCode,integer weight returnsnothing set data = SpecDrop[GetHandleId(u)] call data.droppool.add(ItemRawCode, weight) endmethod
staticmethod RemoveItems takesinteger DestRawCode,integer ItemRawCode returnsnothing set data = GenDrop[DestRawCode] call data.droppool.remove(ItemRawCode) endmethod
staticmethod RemoveItemSpecific takesdestructable u,integer ItemRawCode returnsnothing set data = SpecDrop[GetHandleId(u)] call data.droppool.remove(ItemRawCode) endmethod
staticmethod Unregister takesinteger rawcode returnsnothing set data = GenDrop[rawcode] call data.droppool.destroy() call data.deallocate() endmethod
staticmethod UnregisterSpecific takesdestructable u returnsnothing set data = SpecDrop[GetHandleId(u)] call data.droppool.destroy() call data.deallocate() endmethod
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.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.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
Not bad. A nice, simple, useful system. However, there is one thing to note:
Jass:
function IDSB_GetInstance takesunit u returnsinteger localinteger i =0 loop exitwhen i > BU_Total if BonusUnit[i]== u then return i else set i = i +1 endif endloop return0 endfunction
or:
Jass:
staticmethod GetInstance takesinteger u returnsthistype localthistype datum =0 localinteger i =0 loop exitwhen i ==thistype.UnitMax set datum =thistype.Stack[i] if datum.UnitRawCode== u then set i =thistype.UnitMax else set i = i +1 endif endloop return datum endmethod
For functions like these, you will probably not want to use arrays. Imagine that you have 50 unit types or whatever. That means you have to loop through 50 unit types and check them to one integer. However, with a hashtable it is set and get.
Also, using hashtables could even allow you to add item drops to specific units (assigning structs to their handle id) regardless of their unit type. (although, you should still keep that feature) An indexing system would probably work too.
Bah, if I see your keywords for your system, I know why I always get something different when I search something. This shouldn't be allowed -_-
Also, yes I tell the truth I don't know if that system is that useful. Yes it's a cool system but if I see the how to do list, it's much work, so at the end I will use the normal Item drop system.
About the triggering I can't say anything, sounds like Japanese stuff for me, but you systems/spell are always cool, so I think this can be approved, EXCEPT THE KEYWORDS!
well, it says there put as many related as possible... ^_^
what normal Item drop? the one which you double click a unit to set the items? its just about the same work... ^_^
anyway, this system is for those who want some flexibility or cannot use the method above (like, no preplaced units or unit revives) or for those who don't want to create 1 trigger per unit-type... ^_^
O man, i love vJass so much, i don't know it, but custom functions usable with custom scripts are Awesome!!!! And i love all of your system so... can't rate it perfectly but 5/5
I've written a Pool library (along with a List library and a Stack library) which I will be releasing after some more testing. It will make the process of "random drops" or "random unit" or random w/e extremely easy to work with. And with... unlimited instances. It's a wrapper for the Table library. Which also means, no handles are used except for the one hashtable in Table.
The structure is quite complex, but O(1) in complexity to retrieve a random value, making it extremely efficient to use over and over.
__________________
How to post your triggers on the Hive Workshop. JPAG - Bettering the cause of readable source code.
I have a lot of "chores" that I am currently working on, working 53 hours a week if you count travel time, preparing for my wedding, reviewing the Spells & Systems contest and tending to my own projects as a programmer.
Some notes:
Use static-ifs for constant booleans
Public/private variables are so you don't have to manually prefix things.
IDS is a bad name for a public struct (too generic)
Instead of "exitwhen end" and setting "end" to true, just use "exitwhen true" instead of the "set end = true" statement.
__________________
How to post your triggers on the Hive Workshop. JPAG - Bettering the cause of readable source code.