Name | Type | is_array | initial_value |
//TESH.scrollpos=201
//TESH.alwaysfold=0
library Table // made by Bribe, special thanks to Nestharus, version 3.0.0.0
/*
API
------------
struct Table
| static method create takes nothing returns Table
| create a new Table
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush all stored values inside of it
|
| method remove takes integer key returns nothing
| remove the value at index "key"
|
| method operator []= takes integer key, $TYPE$ value returns nothing
| assign "value" to index "key"
|
| method operator [] takes integer key returns $TYPE$
| load the value at index "key"
|
| method has takes integer key returns boolean
| whether or not the key was assigned
|
----------------
struct TableArray
| static method operator [] takes integer array_size returns TableArray
| create a new array of Tables of size "array_size"
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush and destroy it
|
| method operator size takes nothing returns integer
| returns the size of the TableArray
|
| method operator [] takes integer key returns Table
| returns a Table accessible exclusively to index "key"
*/
globals
private hashtable ht = InitHashtable() //The last hashtable you need
private integer more = 2 //Index generation for Tables (above 2)
private integer less = 0 //Index generation for TableArrays (below 0)
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return 1
endmethod
static method operator list takes nothing returns Table
return 2
endmethod
endstruct
private struct handles extends array
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private struct agents extends array
method operator []= takes integer key, agent value returns nothing
call SaveAgentHandle(ht, this, key, value)
endmethod
endstruct
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSaved$SUPER$(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSaved$SUPER$(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$Handle(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$Handle(ht, this, key, value)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
struct Table extends array
// Implement modules for intuitive type-syntax
implement realm
implement booleanm
implement stringm
implement playerm
implement widgetm
implement destructablem
implement itemm
implement unitm
implement abilitym
implement timerm
implement triggerm
implement triggerconditionm
implement triggeractionm
implement eventm
implement forcem
implement groupm
implement locationm
implement rectm
implement boolexprm
implement soundm
implement effectm
implement unitpoolm
implement itempoolm
implement questm
implement questitemm
implement defeatconditionm
implement timerdialogm
implement leaderboardm
implement multiboardm
implement multiboarditemm
implement trackablem
implement dialogm
implement buttonm
implement texttagm
implement lightningm
implement imagem
implement ubersplatm
implement regionm
implement fogstatem
implement fogmodifierm
implement hashtablem
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
// set this = a[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key)
endmethod
// set a[389034] = 8192
method operator []= takes integer key, Table a returns nothing
call SaveInteger(ht, this, key, a)
endmethod
// set b = a.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key)
endmethod
// call a.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key)
endmethod
// Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
// local Table a = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set more = more + 1
set this = more
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this)
endif
debug set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call a.destroy()
//
method destroy takes nothing returns nothing
debug if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
debug return
debug endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
endstruct
struct TableArray extends array
//Returns a new TableArray to do your bidding. Simply use:
//
// local TableArray ta = TableArray[array_size]
//
static method operator [] takes integer array_size returns TableArray
local Table a = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = a[0] //The last-destroyed TableArray that had this array size
debug if array_size <= 0 then
debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
debug return 0
debug endif
if this == 0 then
set less = less - array_size
set this = less
else
set a[0] = a[this] //Set the last destroyed to the last-last destroyed
call a.remove(this) //Clear hash memory
endif
set dex.size[this] = array_size //This remembers the array size
return this
endmethod
//Returns the size of the TableArray
method operator size takes nothing returns integer
return dex.size[this]
endmethod
//da[integer a].unit[integer b] = unit u
//da[integer a][integer c] = integer d
//
//Inline-friendly when not running in debug mode
//
method operator [] takes integer key returns Table
static if DEBUG_MODE then
local integer i = this.size
if i == 0 then
call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
return 0
elseif key < 0 or key >= i then
call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
return 0
endif
endif
return this + key
endmethod
//Destroys a TableArray without flushing it; assumed you'd call .flush()
//if you want it flushed too. This is public so that if you are flushing
//instances the whole time you don't waste efficiency when disposing the
//TableArray.
//
method destroy takes nothing returns nothing
local Table a = dex.size[this.size]
debug if this.size <= 0 then
debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
debug return
debug endif
if a == 0 then
//Create an array to index recycled instances with their array size
set a = Table.create()
set dex.size[this.size] = a
endif
call dex.size.remove(this) //Clear the array size from hash memory
set a[this] = a[0]
set a[0] = this
endmethod
//All you need to know about this one is that it won't hit the op limit.
private static method clean takes Table a, integer end returns nothing
local integer i = a + 5000
if i < end then
call clean.evaluate(i, end)
set end = i
endif
loop
call a.flush()
set a = a + 1
exitwhen a == end
endloop
endmethod
//Flushes the TableArray and also destroys it. Doesn't get any more
//similar to the FlushParentHashtable native than this.
//
method flush takes nothing returns nothing
local integer end = this.size + this
debug if this == end then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
call clean.evaluate(this, end)
call this.destroy()
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IPool requires Table
/*
IPool 1.0.0.0 by Bribe
About
This is a probability-pool, like a unitpool or itempool for integers.
You can insert any integer, assign it a specific weight, arbitrarily
change that weight, get the total pool weight, get the total types of
nodes that were inserted, arbitrarily remove nodes & finally destroy
the pool when its job is done.
When you want to get a random pool item, it does so with O(1) complex-
ity because internally it is a linear stack that has arbitrary access.
Disclaimer
Addition or subtraction of weight is one loop per unit of weight. So
I recommend not letting the weight of an individual item exceed a few
thousand or so because it may risk hitting the oplimit if that amount
has to be removed from the pool all at once.
If you want weight this high, please let me know and I will add built-
ins to avoid hitting the op limit. I just haven't found a need for a
feature like that so I haven't included it for efficiency's sake.
API
struct IPool extends array
static method create takes nothing returns IPool
->
Creates a new integer pool, which is based on a TableArray[5] as
it has an incredible level of complexity.
method flush takes nothing returns nothing
->
Flush all the contents of the pool, resetting everything utterly.
method destroy takes nothing returns nothing
->
Destroys the pool utterly.
method operator item takes nothing returns integer
->
Get a random integer from the pool based on the total weight of
the pool versus the weight of the item that was picked.
method add takes integer value, integer weight returns nothing
->
Add an item to the pool with a specified weight. Weight is used
as a comparison to other items in the pool. An item with weight 1
has a 50% less chance of being picked than an item with weight 2.
method remove takes integer value returns nothing
->
Removes an item from the list.
method contains takes integer value returns boolean
->
Is the item contained in the pool?
method weightOf takes integer value returns integer
->
Get the weight of an individual item.
method chanceOf takes integer value returns real
->
Get the chance (0.00 - 1.00) that the item will be picked.
method shiftWeight takes integer value, integer lbs returns nothing
->
Shift weight onto an item's weight. Shifting 1 to an item that
has a weight of 1 will result 2. Shifting -1 to an item that has
a weight of 1 will result 0. The operation is comparable to "+="
or "-=" for adding or removing weight.
method operator weight takes nothing returns integer
->
The total weight of all items in the pool.
method operator itemCount takes nothing returns integer
->
The number of unique items that have been added to the pool.
method copy takes nothing returns IPool
->
Returns a copy of the pool in the form of a newly created pool.
debug method print takes nothing returns nothing
->
Available only in debug-mode, this prints out the entire contents
of the pool, displaying both value and weight for each individual
item.
*/
globals
private Table ITEMS = 0
private Table WEIGHT = 0
endglobals
private module Init
private static method onInit takes nothing returns nothing
set ITEMS = Table.create()
set WEIGHT = Table.create()
endmethod
endmodule
struct IPool extends array
implement Init
static method create takes nothing returns thistype
return TableArray[5]
endmethod
private method operator table takes nothing returns Table
return this
endmethod
private method operator tables takes nothing returns Table
return TableArray(this)[1]
endmethod
private method operator items takes nothing returns Table
return TableArray(this)[2]
endmethod
private method operator slots takes nothing returns Table
return TableArray(this)[3]
endmethod
private method operator weights takes nothing returns Table
return TableArray(this)[4]
endmethod
private method link takes integer node, integer slot returns nothing
set this.items[slot] = node
set this.slots[node] = slot
endmethod
method operator weight takes nothing returns integer
return WEIGHT[this]
endmethod
method operator itemCount takes nothing returns integer
return ITEMS[this]
endmethod
method operator item takes nothing returns integer
return this.table[GetRandomInt(0, this.weight - 1)]
endmethod
method flush takes nothing returns nothing
local integer j = ITEMS[this]
local Table t = this.items
loop
set j = j - 1
exitwhen 0 > j
call this.tables[t[j]].destroy()
endloop
set t = this + 5
loop
set t = t - 1
call t.flush()
exitwhen t == this
endloop
call ITEMS.remove(this)
call WEIGHT.remove(this)
endmethod
method destroy takes nothing returns nothing
call this.flush()
call TableArray(this).destroy()
endmethod
method contains takes integer value returns boolean
return 0 != this.tables[value]
endmethod
method weightOf takes integer value returns integer
return this.weights[value]
endmethod
method chanceOf takes integer value returns real
return this.weightOf(value) / (this.weight + 0.)
endmethod
method shiftWeight takes integer value, integer lbs returns nothing
local integer nw = this.weightOf(value) //Node Weight
local integer pw = this.weight //Pool Weight
local Table tbls = this.tables[value] //Tables
local integer sl //Slot
local integer tv //Top value
if 0 != tbls then
if 0 != lbs then
if 0 <= lbs + nw then
set WEIGHT[this] = pw + lbs
set lbs = lbs + nw
if lbs > nw then
loop
exitwhen nw == lbs
set this.table[pw] = value //Append value to Pool table
set tbls[nw] = pw //Append slot to sub table
set pw = pw + 1
set nw = nw + 1
endloop
else
loop
exitwhen nw == lbs
set nw = nw - 1
set pw = pw - 1
set sl = tbls[nw] //Get next slot in sub table
if sl != pw then //If not top slot in Pool
set tv = this.table[pw] //Get top slot
set this.table[sl] = tv //Save it to the newly-vacant slot
set tbls[tv] = sl //Index that slot to the value
endif
call tbls.remove(nw)
call this.table.remove(pw) //Pop top slots
endloop
endif
if 0 != lbs then
set this.weights[value] = lbs //Set item weight to new weight
else
call this.weights.remove(value) //Clear hash memory, set item weight to 0
endif
debug else
debug call BJDebugMsg("IPool Error: Attempt to shift weight of item below zero: " + I2S(value))
endif
debug else
debug call BJDebugMsg("IPool Error: Attempt to shift weight of item by zero: " + I2S(value))
endif
debug else
debug call BJDebugMsg("IPool Error: Attempt to shift weight of un-added item: " + I2S(value))
endif
endmethod
method remove takes integer value returns nothing
local integer size = ITEMS[this] - 1
local integer slot = this.slots[value]
if this.contains(value) then
set ITEMS[this] = size
if slot != size then
call this.link(this.items[size], slot) // Assign top node to freed slot
endif
call this.shiftWeight(value, -this.weightOf(value)) //Shift weight to 0
call this.items.remove(size) //Remove top item from the stack
call this.tables[value].destroy()
debug else
debug call BJDebugMsg("IPool Error: Attempt to remove an un-added item: " + I2S(value))
endif
endmethod
method add takes integer value, integer weight returns nothing
if not this.contains(value) then
set this.tables[value] = Table.create()
call this.link(value, ITEMS[this])
set ITEMS[this] = ITEMS[this] + 1 //Increase item stack size
endif
call this.shiftWeight(value, weight)
endmethod
method copy takes nothing returns thistype
local thistype new = .create()
local integer i
local integer j = ITEMS[this]
local Table t = this.items
loop
set j = j - 1
exitwhen 0 > j
set i = t[j]
call new.add(i, this.weightOf(i))
endloop
return new
endmethod
static if DEBUG_MODE then
method print takes nothing returns nothing
local string s = "POOL: |cffffcc33"
local integer i
local integer j = ITEMS[this]
local Table t = this.items
loop
set j = j - 1
exitwhen 0 > j
set i = t[j]
set s = s + "[" + I2S(i) + "]<" + I2S(this.weightOf(i)) + ">"
endloop
call BJDebugMsg(s + "|r")
endmethod
endif
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BonusChance requires Table
/*
How to Add drop chance bonuses to units:
1) Register the unit into the system using this function
- call BonusRegister(unit u)
* u is the unit to be registered
2) Modify the bonuses using these functions
*Use this for adding direct amounts
*example: if a unit has a Direct Bonus of 1.00, then it will add 1.00% chance to the drop
*chance of the units it kill
- call BonusApplyDirect(unit u, real bonus, boolean add)
*Use this for applying multipliers
*example: if a unit has a multiplier bonus of 2.00, then the drop chances of all units it kills
*would be doubled
- call BonusApplyMulti(unit u, real bonus, boolean add)
* unit u is the unit to have the bonus
* real bonus is the bonus amount
* boolean add: if true -> real bonus is added to the current value of the drop chance bonus of the unit
if false -> the value of the drop chance bonus of the unit is set to real bonus
Bonus is applied this way: The percent chance is multiplied first with the BonusMultiplier
then the BonusDirect is added
You can also obtain the bonus value of a unit via these two functions:
call BonusGetDirect(unit u)
call BonusGetMulti(unit u)
*/
globals
private Table Hash
private real array BonusDirect
private real array BonusMultiplier
private integer BU_Total = 0
endglobals
function BonusRegister takes unit u returns nothing
set BU_Total = BU_Total + 1
set BonusDirect[BU_Total] = 1.00
set BonusMultiplier[BU_Total] = 1.00
set Hash[GetHandleId(u)] = BU_Total
endfunction
/*
modifies the direct bonus of a unit
*/
function BonusApplyDirect takes unit u, real bonus, boolean add returns nothing
local integer i = Hash[GetHandleId(u)]
if add then
set BonusDirect[i] = BonusDirect[i] + bonus
else
set BonusDirect[i] = bonus
endif
endfunction
/*
modifies the multiplier bonus of a unit
*/
function BonusApplyMulti takes unit u, real bonus, boolean add returns nothing
local integer i = Hash[GetHandleId(u)]
if add then
set BonusMultiplier[i] = BonusMultiplier[i] + bonus
else
set BonusMultiplier[i] = bonus
endif
endfunction
/*
these functions returns the bonuses of the unit
*/
function BonusGetDirect takes unit u returns real
return BonusDirect[Hash[GetHandleId(u)]]
endfunction
function BonusGetMulti takes unit u returns real
if BonusMultiplier[Hash[GetHandleId(u)]] == 0.0 then
return 1.0
else
return BonusMultiplier[Hash[GetHandleId(u)]]
endif
endfunction
private module mod
static method onInit takes nothing returns nothing
set Hash = Table.create()
endmethod
endmodule
struct A extends array
implement mod
endstruct
endlibrary
//TESH.scrollpos=24
//TESH.alwaysfold=0
/**************************************************************
*
* RegisterPlayerUnitEvent
* v4.1.1.0
* By Magtheridon96
*
* This library was made to replace that GTrigger
* monster by Jesus4Lyf at TheHelper. I would like
* to give a special thanks to Bribe, azlier and BBQ
* for improving this library. For modularity, it only
* supports player unit events.
*
* Functions passed to RegisterPlayerUnitEvent must
* return false. They can return nothing as well.
*
* API:
* ----
*
* function RegisterPlayerUnitEvent
* takes
* playerunitevent whichEvent : The event that will be registered.
* code whichFunction : The function that will fire when the event occurs.
* returns
* nothing
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
endlibrary
//TESH.scrollpos=17
//TESH.alwaysfold=0
library DropTable
/*
by Adiktuz
This table is used to create DropTables that works like the
original item drop method [the one at the top]
to create a new DropTable:
--> DropTable.create()
to add item to a DropTable:
--> x.add(integer ItemID, integer weight)
to remove an item from a DropTable
--> x.remove(integer ItemID)
* x is the name of the variable in which the DropTablePool is saved
See the sample trigger for examples.
*/
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
endglobals
struct DropTable
integer itemcount
integer array ItemList [ITEMS_MAX]
real array Chance [ITEMS_MAX]
static method create takes nothing returns thistype
local thistype this = .allocate()
set this.itemcount = 0
return this
endmethod
method AddItem takes integer ItemID, real chance returns nothing
if not (this.itemcount > ITEMS_MAX) then
set this.ItemList[this.itemcount] = ItemID
set this.Chance[this.itemcount] = chance
set this.itemcount = this.itemcount + 1
endif
endmethod
method RemoveItem takes integer ItemRawCode returns nothing
local integer i = 0
local boolean end = false
loop
exitwhen end
if this.ItemList[i] == ItemRawCode then
set this.itemcount = this.itemcount - 1
set this.ItemList[i] = this.ItemList[this.itemcount]
set this.Chance[i] = this.Chance[this.itemcount]
set end = true
else
set i = i + 1
if i >= this.itemcount 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
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*
----------------------------------------------------------------------------------
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
//TESH.scrollpos=17
//TESH.alwaysfold=0
scope AddItems initializer Init
private function ApplyIDS takes nothing returns nothing
local unit gnollblue = CreateUnit(Player(1), 'ngno', -831, -186,0)
call DestroyTimer(GetExpiredTimer())
/*
gnolls (general)
*/
call ItemDrop.InitUnit('ngno', 1)
//Circlet of nobility
call ItemDrop.AddItem('ngno', 'cnob', 50.00)
//Orb of darkness
call ItemDrop.AddItem('ngno', 'odef', 50.00)
/*
gnoll owned by Player2 (blue)
*/
call ItemDropPool.InitUnitSpecific(gnollblue, true, 100,1)
call ItemDropPool.AddItemSpecific(gnollblue, 'prvt', 1)
/*
murlocs
*/
call ItemDrop.InitUnit('nmrl', 3)
//Circlet of nobility
call ItemDrop.AddItem('nmrl', 'cnob', 1.00)
//Orb of darkness
call ItemDrop.AddItem('nmrl', 'odef', 1.00)
//Periapt of Vitality
call ItemDrop.AddItem('nmrl', 'prvt', 40.00)
/*
Creates the test hero and initializes it with the drop chance bonus system
*/
call BonusRegister(CreateUnit(Player(0), 'Hamg', 0, 0, 0))
endfunction
private function Init takes nothing returns nothing
call TimerStart(CreateTimer(), 0.01, false, function ApplyIDS)
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope DropChanceBonus initializer Init
/*
a simple example on how to add drop chance bonuses to units
*/
private function ApplyBonus takes nothing returns boolean
if GetSpellAbilityId() == 'A000' then
call BonusApplyMulti(GetTriggerUnit(), 1.00, true)
call BJDebugMsg("Your current chance multiplier is " + R2S(BonusGetMulti(GetTriggerUnit())))
elseif GetSpellAbilityId() == 'A001' then
call BonusApplyDirect(GetTriggerUnit(), 1.00, true)
call BJDebugMsg("You current chance bonus is " + R2S(BonusGetDirect(GetTriggerUnit())))
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddCondition(t, Condition(function ApplyBonus))
endfunction
endscope
//TESH.scrollpos=115
//TESH.alwaysfold=0
/*
----------------------------------------------------------------------------------
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
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*
----------------------------------------------------------------------------------
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
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope AddDestItems initializer Init
private function c takes nothing returns boolean
call ItemDropPoolDest.ForceProcessDrop( GetTriggerDestructable(),false,GetKillingUnit())
return false
endfunction
private function ApplyIDS takes nothing returns nothing
call ItemDropPoolDest.InitDest('LTex', 100.0,1)
call ItemDropPoolDest.AddItem('LTex', 'spsh', 5)
call ItemDropPoolDest.AddItem('LTex', 'ratc', 5)
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterDestDeathInRegionEvent(t, bj_mapInitialPlayableArea)
call TriggerAddCondition(t, Filter(function c))
call TimerStart(CreateTimer(), 0.01, false, function ApplyIDS)
endfunction
endscope
//TESH.scrollpos=155
//TESH.alwaysfold=0
/*
----------------------------------------------------------------------------------
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
//TESH.scrollpos=124
//TESH.alwaysfold=0
/*
----------------------------------------------------------------------------------
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
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*library DropTablePool requires IPool
by Adiktuz
This table is used to create DropTables that utilizes item pools
for the drop chances
to create a new DropTable:
--> DropTablePool.create()
to add item to a DropTable:
--> x.add(integer ItemID, integer weight)
to remove an item from a DropTable
--> x.remove(integer ItemID)
* x is the name of the variable in which the DropTablePool is saved
See the sample trigger for examples.
The drop chance of an item is equal to
its weight over the total weight of the item pool.
Example Scenario:
-I create a drop table pool
-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 to get which item will be dropped from the drop table, 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.
struct DropTablePool
IPool ItemList
static method create takes nothing returns thistype
local thistype this = .allocate()
set this.ItemList = IPool.create()
return this
endmethod
method AddItem takes integer ItemID, integer weight returns nothing
call this.ItemList.add(ItemID,weight)
endmethod
method RemoveItem takes integer ItemID returns nothing
call this.ItemList.remove(ItemID)
endmethod
endstruct
endlibrary*/
//TESH.scrollpos=0
//TESH.alwaysfold=0
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