- Joined
- Oct 16, 2008
- Messages
- 10,454
Two new versions/types [modifications of the original and the IPool version] coming in maybe a week or so, depending on how much time I could spare...
/*
----------------------------------------------------------------------------------
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
/*
----------------------------------------------------------------------------------
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
/*
----------------------------------------------------------------------------------
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
/*
----------------------------------------------------------------------------------
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
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
/*
----------------------------------------------------------------------------------
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
/*
----------------------------------------------------------------------------------
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.
*/
/*
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...
*/