Name | Type | is_array | initial_value |
//TESH.scrollpos=169
//TESH.alwaysfold=0
/***************************************************
*
* Recipe Engine
* v2.0.0.0
* By Magtheridon96
*
* - Allows the creation of item recipes with charged items as requirements.
* - Recipe limit: 1365 (682 if PLAYER_SPECIFIC_RECIPES = true)
* - If you require more recipes, contact me and I will give
* a special version of this system with a limit of 8191 recipes.
*
* Very Important:
* ---------------
*
* - If PLAYER_SPECIFIC_RECIPES == true:
* - Players will be authorized by default
* - Max Recipe Count will go down (By 50%)
*
* API:
* ----
*
* ---------------------------------------------------------------------------
* | Struct API |
* ---------------------------------------------------------------------------
*
* struct Recipe extends array
*
* - static boolean enabled
* - Used to enable or disable the system.
*
* - method requires takes integer id, integer charges returns thistype
* - Adds a requirement to a recipe given the required item Id and the required charges
* - static method create takes integer id, integer charges returns thistype
* - Creates a recipe object given the result and the desired charges
* - method enable takes nothing returns nothing
* - Enables the compiling of a recipe
* - method disable takes nothing returns nothing
* - Disables the compiling of a recipe
* - method isEnabled takes nothing returns boolean
* - Determines if a recipe is enabled or not
* - static method disassemble takes item whichItem returns integer
* - Disassembles an item regardless of whether it is carried or not
* - If DisassembleItem returns 0 -> Success
* - If DisassembleItem returns 1 -> Invalid Item
* - If DisassembleItem returns 2 -> Not enough space
*
* For Optional Player Specific Recipes:
*
* - method authorize takes integer id returns nothing
* - Allows a player to compile a recipe.
* - method unauthorize takes integer id returns nothing
* - Remove player authorization of a recipe. Players are not authorized by default.
* - method isAuthorized takes integer id returns boolean
* - Checks whether a player is authorized or not.
*
* ---------------------------------------------------------------------------
* | Jass API |
* ---------------------------------------------------------------------------
*
* - function CreateRecipe takes integer result, integer charge returns Recipe
* - Creates a recipe object given the result and the desired charges.
* - function AddRecipeRequirement takes Recipe this, integer id, integer charges returns nothing
* - Adds a requirement to a recipe given the required item Id and the required charges.
* - function EnableRecipe takes Recipe this returns nothing
* - Enables the compiling of a recipe
* - function DisableRecipe takes Recipe this returns nothing
* - Disables the compiling of a recipe
* - function IsRecipeEnabled takes Recipe this returns boolean
* - Determines if a recipe is enabled or not
* - function EnableRecipeSystem takes nothing returns nothing
* - Enables the system. The system is enabled by default.
* - function DisableRecipeSystem takes nothing returns nothing
* - Disables the system.
* - function IsRecipeSystemEnabled takes nothing returns boolean
* - Checks whether the system is enabled or not.
* - function DisassembleItem takes item it returns integer
* - Disassembles an item regardless of whether it is carried or not.
* - If DisassembleItem returns 0 -> Success
* - If DisassembleItem returns 1 -> Invalid Item
* - If DisassembleItem returns 2 -> Not enough space
*
* For Optional Player Specific Recipes:
*
* - function AuthorizePlayerRecipe takes player p, Recipe this returns nothing
* - function AuthorizePlayerRecipeById takes integer p, Recipe this returns nothing
* - Allows a player to compile a recipe.
*
* - function UnauthorizePlayerRecipe takes player p, Recipe this returns nothing
* - function UnauthorizePlayerRecipeById takes integer p, Recipe this returns nothing
* - Remove player authorization of a recipe. Players are not authorized by default.
*
* - function IsPlayerAuthorizedRecipe takes player p, Recipe this returns boolean
* - function IsPlayerAuthorizedRecipeById takes integer p, Recipe this returns boolean
* - Checks whether a player is authorized or not.
*
***************************************************/
library RecipeEngine requires Table, RegisterPlayerUnitEvent, GetItemOwner
// Configuration
globals
// The effect that appears on Recipe Compiling
private constant string EFFECT_PATH = "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl"
// The attachment point of the effect
private constant string ATTACHMENT = "origin"
// The boolean that allows you to create Player specific recipes
private constant boolean PLAYER_SPECIFIC_RECIPES = false
// Disassembling Constants
constant integer DISASSEMBLE_SUCCESS = 0
constant integer DISASSEMBLE_ERROR_INVALID = 1
constant integer DISASSEMBLE_ERROR_INVENTORY = 2
endglobals
// End of Configuration
private module Init
private static method onInit takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM, function thistype.main)
set queue = TableArray[0x2000]
set itemStack = Table.create()
set ds = Table.create()
set tb = Table.create()
endmethod
endmodule
struct Recipe extends array
private static TableArray queue
private static Table itemStack
private static Table ds = 0
private static Table tb = 0
private static integer stack = 1
private static integer array itemId
private static integer array charge
private static integer array output
private static integer array outputCharge
private static integer array count
private static boolean array recipeOff
private static constant integer NULL = -1
static boolean enabled = true
method enable takes nothing returns nothing
set recipeOff[this] = false
endmethod
method disable takes nothing returns nothing
set recipeOff[this] = true
endmethod
method isEnabled takes nothing returns boolean
return not recipeOff[this]
endmethod
static if PLAYER_SPECIFIC_RECIPES then
static boolean array au
method authorize takes integer id returns nothing
set au[this * 12 + id] = true
endmethod
method unauthorize takes integer id returns nothing
set au[this * 12 + id] = false
endmethod
method isAuthorized takes integer id returns nothing
return au[this * 12 + id]
endmethod
endif
static method disassemble takes item it returns integer
local thistype this = ds[GetHandleId(it)]
local integer i = 0
local real x = GetWidgetX(it)
local real y = GetWidgetY(it)
local unit u = GetItemOwner(it)
local integer size = UnitInventorySize(u)
local integer empty = 1
local boolean validOwner = (u != null)
local item iq
if this != 0 then
set enabled = false
if validOwner then
loop
exitwhen i == size
if UnitItemInSlot(u, i) == null then
set empty = empty + 1
endif
set i = i + 1
endloop
if count[this] > empty then
set u = null
return DISASSEMBLE_ERROR_INVENTORY
endif
set i = 0
endif
call RemoveItem(it)
loop
if itemId[6 * this + i] != NULL then
set iq = CreateItem(itemId[6 * this + i], x, y)
if validOwner then
call UnitAddItem(u, iq)
endif
if charge[6 * this + i] > 0 then
call SetItemCharges(iq, charge[6 * this + i])
endif
endif
exitwhen i == 5
set i = i + 1
endloop
set enabled = true
set iq = null
set u = null
return DISASSEMBLE_SUCCESS
endif
set u = null
return DISASSEMBLE_ERROR_INVALID
endmethod
private static method systemConditions takes integer this returns boolean
static if PLAYER_SPECIFIC_RECIPES then
return enabled and au[this * 12 + GetPlayerId(GetTriggerPlayer())] and not recipeOff[this]
else
return enabled and not recipeOff[this]
endif
endmethod
private static method main takes nothing returns nothing
local integer id = GetItemTypeId(GetManipulatedItem())
local unit u = GetManipulatingUnit()
local thistype this = queue[id][0]
local integer in = 0
local integer h
local integer i = 0
local integer int = 0
local integer index = 0
local integer slotIndex = 0
local integer itemInSlot
local integer charges
local integer arrayIndex = this * 6
local integer getIndex = 0
local item k = null
if systemConditions(this) then
loop
exitwhen this == 0
loop
exitwhen slotIndex == 6
set itemInSlot = GetItemTypeId(UnitItemInSlot(u, slotIndex))
set charges = GetItemCharges(UnitItemInSlot(u, slotIndex))
loop
if itemInSlot == itemId[arrayIndex + index] and tb[index] == 0 and charges >= charge[arrayIndex + index] then
set tb[index] = 1
set int = int + 1
exitwhen true
endif
exitwhen index == 5
set index = index + 1
endloop
set index = 0
if int == count[this] then
call tb.flush()
loop
exitwhen i == count[this]
loop
exitwhen getIndex > 5
if GetItemTypeId(UnitItemInSlot(u, getIndex)) == itemId[6 * this + i] then
set k = UnitItemInSlot(u, getIndex)
endif
set getIndex = getIndex + 1
endloop
set h = GetItemCharges(k)
if h > charge[6 * this + i] then
call SetItemCharges(k, h - charge[6 * this + i])
else
call RemoveItem(k)
endif
set i = i + 1
set getIndex = 0
endloop
call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH, u, ATTACHMENT))
set k = CreateItem(output[this], 0, 0)
if outputCharge[this] > 0 then
call SetItemCharges(k, outputCharge[this])
endif
set ds[GetHandleId(k)] = this
call UnitAddItem(u, k)
set k = null
set u = null
return
endif
set slotIndex = slotIndex + 1
endloop
call tb.flush()
set in = in + 1
set this = queue[id][in]
endloop
endif
endmethod
method requires takes integer id, integer charges returns thistype
set itemId[6 * this + count[this]] = id
set charge[6 * this + count[this]] = charges
if itemStack[id] == null then
set itemStack[id] = 0
endif
set queue[id][itemStack[id]] = this
set itemStack[id] = itemStack[id] + 1
set count[this] = count[this] + 1
return this
endmethod
static method create takes integer result, integer charges returns thistype
local thistype this = stack
local integer i = 0
set stack = stack + 1
loop
set itemId[6 * this + i] = NULL
exitwhen i == 5
set i = i + 1
endloop
set output[this] = result
set outputCharge[this] = charges
return this
endmethod
implement Init
endstruct
function CreateRecipe takes integer id, integer charge returns Recipe
return Recipe.create(id, charge)
endfunction
function AddRecipeRequirement takes Recipe this, integer id, integer charge returns nothing
call this.requires(id, charge)
endfunction
function EnableRecipe takes Recipe this returns nothing
call this.enable()
endfunction
function DisableRecipe takes Recipe this returns nothing
call this.disable()
endfunction
function IsRecipeEnabled takes Recipe this returns boolean
return this.isEnabled()
endfunction
function EnableRecipeSystem takes nothing returns nothing
set Recipe.enabled = true
endfunction
function DisableRecipeSystem takes nothing returns nothing
set Recipe.enabled = false
endfunction
function IsRecipeSystemEnabled takes nothing returns boolean
return Recipe.enabled
endfunction
function DisassembleItem takes item it returns integer
return Recipe.disassemble(it)
endfunction
static if PLAYER_SPECIFIC_RECIPES then
function AuthorizePlayerRecipeById takes integer id, Recipe this returns nothing
call this.authorize(id)
endfunction
function UnauthorizePlayerRecipeById takes integer id, Recipe this returns nothing
call this.unauthorize(id)
endfunction
function IsPlayerAuthorizedRecipeById takes integer id, Recipe this returns boolean
return this.isAuthorized(id)
endfunction
function AuthorizePlayerRecipe takes player p, Recipe this returns nothing
call this.authorize(GetPlayerId(p))
endfunction
function UnauthorizePlayerRecipe takes player p, Recipe this returns nothing
call this.unauthorize(GetPlayerId(p))
endfunction
function IsPlayerAuthorizedRecipe takes player p, Recipe this returns boolean
return this.isAuthorized(GetPlayerId(p))
endfunction
endif
endlibrary
//TESH.scrollpos=196
//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
/**************************************************************
*
* RegisterPlayerUnitEvent
* v4.2.0.0
* By Magtheridon96
*
* 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 you would like to register
* code whichFunction : The code you would like to register
* returns
* nothing
*
* - Registers code that will execute when an event fires.
*
**************************************************************/
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=10
//TESH.alwaysfold=0
library GetItemOwner /* v1.1.0.1
*************************************************************************************
*
* Retrieves the unit carrying an item.
*
*************************************************************************************
*
* */uses/*
*
* */ UnitIndexer /* hiveworkshop.com/forums/jass-functions-413/unit-indexer-172090/
* */ Table /* hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
* */ RegisterPlayerUnitEvent /* hiveworkshop.com/forums/jass-functions-413/snippet-registerplayerunitevent-203338/
*
************************************************************************************
*
* Functions
*
* function GetItemOwnerId takes item i returns integer
* - returns indexed id of owning unit
* function GetItemOwner takes item i returns unit
* - returns owning unit of item
*
************************************************************************************/
globals
private Table ot //owner table
endglobals
private module init
//when a unit picks up an item, update the owner
private static method op takes nothing returns nothing
set ot[GetHandleId(GetManipulatedItem())]=GetUnitUserData(GetTriggerUnit())
endmethod
private static method onInit takes nothing returns nothing
set ot=Table.create()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM, function thistype.op)
endmethod
endmodule
function GetItemOwnerId takes item i returns integer
//if the item is owned, the owner is in the hashtable
if (IsItemOwned(i)) then
return ot[GetHandleId(i)]
endif
return 0
endfunction
function GetItemOwner takes item i returns unit
return GetUnitById(GetItemOwnerId(i))
endfunction
private struct ItemLoc extends array
implement init
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library UnitIndexer /* v4.0.2.5
*************************************************************************************
*
* Assigns unique indexes to units via unit user data.
*
*************************************************************************************
*
* */uses/*
* */ WorldBounds /* hiveworkshop.com/forums/jass-functions-413/snippet-worldbounds-180494/
* */ Event /* hiveworkshop.com/forums/submissions-414/snippet-event-186555/
*
************************************************************************************
*
* Functions
*
* function RegisterUnitIndexEvent takes boolexpr codeToRegister, Event unitIndexEvent returns nothing
* function TriggerRegisterUnitIndexEvent takes trigger triggerToRegister, Event unitIndexEvent returns nothing
*
* function GetUnitById takes integer index returns unit
* - Returns unit given a unit index
* function GetUnitId takes unit u returns integer
* - Returns unit index given a unit
*
* function IsUnitIndexed takes unit u returns boolean
* function IsUnitDeindexing takes unit u returns boolean
*
* function GetIndexedUnitId takes nothing returns integer
* function GetIndexedUnit takes nothing returns unit
*
************************************************************************************
*
* module UnitIndexStruct
*
* - A pseudo module interface that runs a set of methods if they exist and provides
* - a few fields and operators. Runs on static ifs to minimize code.
*
* static method operator [] takes unit u returns thistype
* - Return GetUnitUserData(u)
*
* readonly unit unit
* - The indexed unit of the struct
* readonly boolean allocated
* - Is unit allocated for the struct
*
* Interface:
*
* - These methods don't have to exist. If they don't exist, the code
* - that calls them won't even be in the module.
*
* private method index takes nothing returns nothing
* - called when a unit is indexed and passes the filter.
* -
* - thistype this: Unit's index
* private method deindex takes nothing returns nothing
* - called when a unit is deindexed and is allocated for struct
* -
* - thistype this: Unit's index
* private static method filter takes unit unitToIndex returns boolean
* - Determines whether or not to allocate struct for unit
* -
* - unit unitToIndex: Unit being filtered
*
************************************************************************************
*
* struct UnitIndexer extends array
*
* - Controls the unit indexer system.
*
* static constant Event UnitIndexer.INDEX
* static constant Event UnitIndexer.DEINDEX
* - Don't register functions and triggers directly to the events. Register them via
* - RegisterUnitIndexEvent and TriggerRegisterUnitIndexEvent.
*
* static boolean enabled
* - Enables and disables unit indexing. Useful for filtering out dummy units.
*
************************************************************************************
*
* struct UnitIndex extends array
*
* - Constrols specific unit indexes.
*
* method lock takes nothing returns nothing
* - Locks an index. When an index is locked, it will not be recycled
* - when the unit is deindexed until all locks are removed. Deindex
* - events still fire at the appropriate times, the index just doesn't
* - get thrown into the recycler.
* method unlock takes nothing returns nothing
* - Unlocks an index.
*
************************************************************************************/
globals
private constant integer ABILITIES_UNIT_INDEXER = 'A!@!'
private trigger q=CreateTrigger()
private trigger l=CreateTrigger()
private unit array e
private integer r=0
private integer y=0
private integer o=0
private boolean a=false
private integer array n
private integer array p
private integer array lc
endglobals
function GetIndexedUnitId takes nothing returns integer
return o
endfunction
function GetIndexedUnit takes nothing returns unit
return e[o]
endfunction
//! runtextmacro optional UNIT_LIST_LIB()
private struct PreLoader extends array
public static method run takes nothing returns nothing
call DestroyTimer(GetExpiredTimer())
set a=true
endmethod
public static method eval takes trigger t returns nothing
local integer f=n[0]
local integer d=o
loop
exitwhen 0==f
if (IsTriggerEnabled(t)) then
set o=f
if (TriggerEvaluate(t)) then
call TriggerExecute(t)
endif
else
exitwhen true
endif
set f=n[f]
endloop
set o=d
endmethod
public static method evalb takes boolexpr c returns nothing
local trigger t=CreateTrigger()
local thistype f=n[0]
local integer d=o
call TriggerAddCondition(t,c)
loop
exitwhen 0==f
set o=f
call TriggerEvaluate(t)
set f=n[f]
endloop
call DestroyTrigger(t)
set t=null
set o=d
endmethod
endstruct
//! runtextmacro optional UNIT_EVENT_MACRO()
private module UnitIndexerInit
private static method onInit takes nothing returns nothing
local integer i=15
local boolexpr bc=Condition(function thistype.onLeave)
local boolexpr bc2=Condition(function thistype.onEnter)
local group g=CreateGroup()
local player p
set INDEX=CreateEvent()
set DEINDEX=CreateEvent()
call TriggerRegisterEnterRegion(q,WorldBounds.worldRegion,bc2)
loop
set p=Player(i)
call TriggerRegisterPlayerUnitEvent(l,p,EVENT_PLAYER_UNIT_ISSUED_ORDER,bc)
call SetPlayerAbilityAvailable(p,ABILITIES_UNIT_INDEXER,false)
call GroupEnumUnitsOfPlayer(g,p,bc2)
exitwhen 0==i
set i=i-1
endloop
call DestroyGroup(g)
set bc=null
set g=null
set bc2=null
set p=null
call TimerStart(CreateTimer(),0,false,function PreLoader.run)
endmethod
endmodule
struct UnitIndex extends array
method lock takes nothing returns nothing
debug if (null!=e[this]) then
set lc[this]=lc[this]+1
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"UNIT INDEXER ERROR: ATTEMPT TO LOCK NULL INDEX")
debug endif
endmethod
method unlock takes nothing returns nothing
debug if (0<lc[this]) then
set lc[this]=lc[this]-1
if (0==lc[this] and null==e[this]) then
set n[this]=y
set y=this
endif
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"UNIT INDEXER ERROR: ATTEMPT TO UNLOCK UNLOCKED INDEX")
debug endif
endmethod
endstruct
struct UnitIndexer extends array
readonly static Event INDEX
readonly static Event DEINDEX
static boolean enabled=true
private static method onEnter takes nothing returns boolean
local unit Q=GetFilterUnit()
local integer i
local integer d=o
if (enabled and Q!=e[GetUnitUserData(Q)]) then
if (0==y) then
set r=r+1
set i=r
else
set i=y
set y=n[y]
endif
call UnitAddAbility(Q,ABILITIES_UNIT_INDEXER)
call UnitMakeAbilityPermanent(Q,true,ABILITIES_UNIT_INDEXER)
call SetUnitUserData(Q,i)
set e[i]=Q
static if not LIBRARY_UnitList then
if (not a)then
set p[i]=p[0]
set n[p[0]]=i
set n[i]=0
set p[0]=i
endif
else
set p[i]=p[0]
set n[p[0]]=i
set n[i]=0
set p[0]=i
call GroupAddUnit(g,e[i])
endif
set o=i
call FireEvent(INDEX)
set o=d
endif
set Q=null
return false
endmethod
private static method onLeave takes nothing returns boolean
static if LIBRARY_UnitEvent then
implement optional UnitEventModule
else
local unit u=GetFilterUnit()
local integer i=GetUnitUserData(u)
local integer d=o
if (0==GetUnitAbilityLevel(u,ABILITIES_UNIT_INDEXER) and u==e[i]) then
static if not LIBRARY_UnitList then
if (not a)then
set n[p[i]]=n[i]
set p[n[i]]=p[i]
endif
else
set n[p[i]]=n[i]
set p[n[i]]=p[i]
call GroupRemoveUnit(g,e[i])
endif
set o=i
call FireEvent(DEINDEX)
set o=d
if (0==lc[i]) then
set n[i]=y
set y=i
endif
set e[i]=null
endif
set u=null
endif
return false
endmethod
implement UnitIndexerInit
endstruct
//! runtextmacro optional UNIT_EVENT_MACRO_2()
function RegisterUnitIndexEvent takes boolexpr c,integer ev returns nothing
call RegisterEvent(c, ev)
if (not a and ev==UnitIndexer.INDEX and 0!=n[0]) then
call PreLoader.evalb(c)
endif
endfunction
function TriggerRegisterUnitIndexEvent takes trigger t,integer ev returns nothing
call TriggerRegisterEvent(t,ev)
if (not a and ev == UnitIndexer.INDEX and 0!=n[0]) then
call PreLoader.eval(t)
endif
endfunction
function GetUnitById takes integer W returns unit
return e[W]
endfunction
function GetUnitId takes unit u returns integer
return GetUnitUserData(u)
endfunction
function IsUnitIndexed takes unit u returns boolean
return u==e[GetUnitUserData(u)]
endfunction
function IsUnitDeindexing takes unit u returns boolean
return IsUnitIndexed(u) and 0==GetUnitAbilityLevel(u,ABILITIES_UNIT_INDEXER)
endfunction
module UnitIndexStruct
static method operator [] takes unit u returns thistype
return GetUnitUserData(u)
endmethod
method operator unit takes nothing returns unit
return e[this]
endmethod
static if thistype.filter.exists then
static if thistype.index.exists then
static if thistype.deindex.exists then
readonly boolean allocated
else
method operator allocated takes nothing returns boolean
return filter(e[this])
endmethod
endif
else
method operator allocated takes nothing returns boolean
return filter(e[this])
endmethod
endif
elseif (thistype.index.exists) then
static if thistype.deindex.exists then
readonly boolean allocated
else
method operator allocated takes nothing returns boolean
return this==GetUnitUserData(e[this])
endmethod
endif
else
method operator allocated takes nothing returns boolean
return this==GetUnitUserData(e[this])
endmethod
endif
static if thistype.index.exists then
private static method onIndexEvent takes nothing returns boolean
static if thistype.filter.exists then
if (filter(e[o])) then
static if thistype.deindex.exists then
set thistype(o).allocated=true
endif
call thistype(o).index()
endif
else
static if thistype.deindex.exists then
set thistype(o).allocated=true
endif
call thistype(o).index()
endif
return false
endmethod
endif
static if thistype.deindex.exists then
private static method onDeindexEvent takes nothing returns boolean
static if thistype.filter.exists then
static if thistype.index.exists then
if (thistype(o).allocated) then
set thistype(o).allocated=false
call thistype(o).deindex()
endif
else
if (filter(e[o])) then
call thistype(o).deindex()
endif
endif
else
static if thistype.index.exists then
set thistype(o).allocated=false
endif
call thistype(o).deindex()
endif
return false
endmethod
endif
static if thistype.index.exists then
static if thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
else
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
endmethod
endif
elseif thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
endif
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library WorldBounds
/*
readonly static real maxX
readonly static real maxY
readonly static real minX
readonly static real minY
readonly static real centerX
readonly static real centerY
readonly static rect world
readonly static region worldRegion
*/
globals
private constant boolean USE_REGION = true
private constant boolean USE_RECT = true
private constant boolean USE_EXTREMA_COORDS = true
private constant boolean USE_CENTER_COORDS = true
endglobals
private module WorldBoundInit
private static method onInit takes nothing returns nothing
static if not USE_RECT then
local rect world=GetWorldBounds()
else
set world=GetWorldBounds()
endif
static if USE_EXTREMA_COORDS then
set maxX=GetRectMaxX(world)
set maxY=GetRectMaxY(world)
set minX=GetRectMinX(world)
set minY=GetRectMinY(world)
endif
static if USE_CENTER_COORDS then
set centerX=(maxX+minX)/2
set centerY=(minY+maxY)/2
endif
static if USE_REGION then
set worldRegion=CreateRegion()
call RegionAddRect(worldRegion,world)
endif
static if not USE_RECT then
call RemoveRect(world)
set world=null
endif
endmethod
endmodule
struct WorldBounds extends array
static if USE_EXTREMA_COORDS then
readonly static real maxX
readonly static real maxY
readonly static real minX
readonly static real minY
endif
static if USE_CENTER_COORDS then
readonly static real centerX
readonly static real centerY
endif
static if USE_RECT then
readonly static rect world
endif
static if USE_REGION then
readonly static region worldRegion
endif
implement WorldBoundInit
endstruct
endlibrary
//TESH.scrollpos=17
//TESH.alwaysfold=0
library Event
//2.0.1.1
/////////////////////////////////////////////////////////////////////////
//function CreateEvent takes nothing returns integer
//function TriggerRegisterEvent takes trigger t, integer ev returns nothing
//function RegisterEvent takes boolexpr c, integer ev returns nothing
//function FireEvent takes integer ev returns nothing
//struct Event extends array
//static method create takes nothing returns thistype
//method registerTrigger takes trigger t returns nothing
//method register takes boolexpr c returns nothing
//method fire takes nothing returns nothing
/////////////////////////////////////////////////////////////////////////
globals
private real eventv = 0
endglobals
struct Event extends array
private static integer count = 0
private static trigger array trig
private static boolexpr array bc
static method create takes nothing returns thistype
set count = count + 1
return count
endmethod
method registerTrigger takes trigger t returns nothing
call TriggerRegisterVariableEvent(t, SCOPE_PRIVATE + "eventv", EQUAL, this)
endmethod
method register takes boolexpr c returns nothing
if (null==bc[this]) then
set bc[this] = c
set trig[this] = CreateTrigger()
else
set bc[this] = Or(bc[this],c)
call TriggerClearConditions(trig[this])
endif
call TriggerAddCondition(trig[this], bc[this])
endmethod
method fire takes nothing returns nothing
set eventv = 0
set eventv = this
call TriggerEvaluate(trig[this])
endmethod
endstruct
function CreateEvent takes nothing returns Event
return Event.create()
endfunction
function TriggerRegisterEvent takes trigger t, Event ev returns nothing
call ev.registerTrigger(t)
endfunction
function RegisterEvent takes boolexpr c, Event ev returns nothing
call ev.register(c)
endfunction
function FireEvent takes Event ev returns nothing
call ev.fire()
endfunction
endlibrary
//TESH.scrollpos=282
//TESH.alwaysfold=0
/***************************************************
*
* Recipe Engine
* v2.0.0.0
* By Magtheridon96
*
* - Allows the creation of item recipes with charged items as requirements.
* - Recipe limit: 1365 (682 if PLAYER_SPECIFIC_RECIPES = true)
* - If you require more recipes, contact me and I will give
* a special version of this system with a limit of 8191 recipes.
*
* Very Important:
* ---------------
*
* - If PLAYER_SPECIFIC_RECIPES == true:
* - Players will be authorized by default
* - Max Recipe Count will go down (By 50%)
*
* - Never compile a recipe unless you arere sure the unit has the items.
* I am only allowing users to access that function because they may want
* to use it in some scenarios. (Not going to elaborate)
*
* - Only call compileEx after checking hasItemsEx for the same unit and
* the same item.
*
* API:
* ----
*
* ---------------------------------------------------------------------------
* | Struct API |
* ---------------------------------------------------------------------------
*
* struct Recipe extends array
*
* - static boolean enabled
* - Used to enable or disable the system.
*
* - method requires takes integer id, integer charges returns thistype
* - Adds a requirement to a recipe given the required item Id and the required charges
* - static method create takes integer id, integer charges returns thistype
* - Creates a recipe object given the result and the desired charges
* - method enable takes nothing returns nothing
* - Enables the Auto-compiling of a recipe
* - method disable takes nothing returns nothing
* - Disables the Auto-compiling of a recipe
* - method isEnabled takes nothing returns boolean
* - Determines if a recipe is enabled or not
* - method hasItems takes unit whichUnit returns boolean
* - Determines if a unit has the required items for a certain recipe
* - method hasItemsEx takes unit whichUnit, item included returns boolean
* - Determines if a unit has the required items for a certain recipe including one exception item
* - method compile takes unit whichUnit returns nothing
* - Compiles a recipe.
* - method compileEx takes unit whichUnit, item it returns nothing
* - Compiles a recipe including an item outside the inventory of a unit.
* - static method disassemble takes item whichItem returns integer
* - Disassembles an item regardless of whether it is carried or not
* - If DisassembleItem returns 0 -> Success
* - If DisassembleItem returns 1 -> Invalid Item
* - If DisassembleItem returns 2 -> Not enough space
* - static method iterateCompile takes unit whichUnit returns nothing
* - Iterates through all recipes and compiles them for a unit.
* - static method iterateCompileEx takes unit whichUnit, item it returns nothing
*
* For Optional Player Specific Recipes:
*
* - method authorize takes integer id returns nothing
* - Allows a player to compile a recipe.
* - method unauthorize takes integer id returns nothing
* - Remove player authorization of a recipe. Players are not authorized by default.
* - method isAuthorized takes integer id returns boolean
* - Checks whether a player is authorized or not.
*
* ---------------------------------------------------------------------------
* | Jass API |
* ---------------------------------------------------------------------------
*
* - function CreateRecipe takes integer result, integer charge returns Recipe
* - Creates a recipe object given the result and the desired charges.
* - function AddRecipeRequirement takes Recipe this, integer id, integer charges returns nothing
* - Adds a requirement to a recipe given the required item Id and the required charges.
* - function EnableRecipe takes Recipe this returns nothing
* - Enables the Auto-compiling of a recipe
* - function DisableRecipe takes Recipe this returns nothing
* - Disables the Auto-compiling of a recipe
* - function IsRecipeEnabled takes Recipe this returns boolean
* - Determines if a recipe is enabled or not
* - function EnableRecipeSystem takes nothing returns nothing
* - Enables the system. The system is enabled by default.
* - function DisableRecipeSystem takes nothing returns nothing
* - Disables the system.
* - function IsRecipeSystemEnabled takes nothing returns boolean
* - Checks whether the system is enabled or not.
* - function DisassembleItem takes item it returns integer
* - Disassembles an item regardless of whether it is carried or not.
* - If DisassembleItem returns 0 -> Success
* - If DisassembleItem returns 1 -> Invalid Item
* - If DisassembleItem returns 2 -> Not enough space
* - function HasRecipeItems takes unit whichUnit, Recipe this returns boolean
* - Determines if a unit has the required items for a certain recipe.
* - function HasRecipeItemsEx takes unit whichUnit, Recipe this, item included returns boolean
* - Determines if a unit has the required items for a certain recipe including one exception item.
* - function CompileRecipe takes unit whichUnit, Recipe this returns nothing
* - Compiles a recipe.
* - function CompileRecipeEx takes unit whichUnit, Recipe this, item it returns nothing
* - Compiles a recipe including an item outside the inventory of a unit.
*
* For Optional Player Specific Recipes:
*
* - function AuthorizePlayerRecipe takes player p, Recipe this returns nothing
* - function AuthorizePlayerRecipeById takes integer p, Recipe this returns nothing
* - Allows a player to compile a recipe.
*
* - function UnauthorizePlayerRecipe takes player p, Recipe this returns nothing
* - function UnauthorizePlayerRecipeById takes integer p, Recipe this returns nothing
* - Remove player authorization of a recipe. Players are not authorized by default.
*
* - function IsPlayerAuthorizedRecipe takes player p, Recipe this returns boolean
* - function IsPlayerAuthorizedRecipeById takes integer p, Recipe this returns boolean
* - Checks whether a player is authorized or not.
*
***************************************************/
library RecipeEngine requires Table, RegisterPlayerUnitEvent, GetItemOwner
// Configuration
globals
// The effect that appears on Recipe Compiling
private constant string EFFECT_PATH = "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl"
// The attachment point of the effect
private constant string ATTACHMENT = "origin"
// The boolean that allows you to create Player specific recipes
private constant boolean PLAYER_SPECIFIC_RECIPES = false
// Disassembling Constants
constant integer DISASSEMBLE_SUCCESS = 0
constant integer DISASSEMBLE_ERROR_INVALID = 1
constant integer DISASSEMBLE_ERROR_INVENTORY = 2
endglobals
// End of Configuration
private module Init
private static method onInit takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM, function thistype.main)
set ds = Table.create()
set tb = Table.create()
set items = Table.create()
endmethod
endmodule
struct Recipe extends array
private static Table ds = 0
private static Table tb = 0
private static integer stack = 1
private static integer array itemId
private static integer array charge
private static integer array output
private static integer array outputCharge
private static integer array count
private static boolean array recipeOff
private static constant integer NULL = -1
static boolean enabled = true
method enable takes nothing returns nothing
set recipeOff[this] = false
endmethod
method disable takes nothing returns nothing
set recipeOff[this] = true
endmethod
method isEnabled takes nothing returns boolean
return not recipeOff[this]
endmethod
private static method getItem takes unit u, integer id returns item
local integer i = 0
loop
exitwhen i > 5
if GetItemTypeId(UnitItemInSlot(u, i)) == id then
return UnitItemInSlot(u, i)
endif
set i = i + 1
endloop
return null
endmethod
method hasItems takes unit u returns boolean
local integer h = 0
local integer i = 0
local integer j = 0
local integer k
local integer l
local integer n = this * 6
loop
exitwhen j == 6
// Set Data
set k = GetItemTypeId(UnitItemInSlot(u, j))
set l = GetItemCharges(UnitItemInSlot(u, j))
loop
// Check If:
// - Itemtype is present
// - Charges are sufficient
// - Slot not counted yet
if k == itemId[n + i] and tb[i] == 0 and l >= charge[n + i] then
set tb[i] = 1
set h = h + 1
exitwhen true
endif
exitwhen i == 5
set i = i + 1
endloop
set i = 0
// Return True
if h == count[this] then
call tb.flush()
return true
endif
set j = j + 1
endloop
call tb.flush()
return false
endmethod
method hasItemsEx takes unit u, item it returns boolean
local integer h = 0
local integer i = 0
local integer j = 0
local integer k
local integer l
local integer id = GetItemTypeId(it)
local integer ic = GetItemCharges(it)
// Check if given item is
loop
if id == itemId[6 * this + i] and ic >= charge[6 * this + i] then
set tb[i] = 1
set h = h + 1
exitwhen true
endif
exitwhen i == 5
set i = i + 1
endloop
loop
exitwhen j == 6
// Set Data
set k = GetItemTypeId(UnitItemInSlot(u, j))
set l = GetItemCharges(UnitItemInSlot(u, j))
set i = 0
loop
// Check If:
// - Itemtype is present
// - Charges are sufficient
// - Recipe requirement not Satisfied
if tb[i] == 0 and k == itemId[6 * this + i] and l >= charge[6 * this + i] then
set tb[i] = 1
set h = h + 1
exitwhen true
endif
exitwhen i == 5
set i = i + 1
endloop
// Return True
if h == count[this] then
call tb.flush()
return true
endif
set j = j + 1
endloop
call tb.flush()
return false
endmethod
method compile takes unit u returns nothing
local integer h
local integer i = 0
local item k
call DisableTrigger(GetTriggeringTrigger())
loop
exitwhen i == count[this]
set k = getItem(u, itemId[6 * this + i])
set h = GetItemCharges(k)
if h > charge[6 * this + i] then
call SetItemCharges(k, h - charge[6 * this + i])
else
call RemoveItem(k)
endif
set i = i + 1
endloop
// Create Effect
call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH, u, ATTACHMENT))
// Create Item And Set Charges
set k = CreateItem(output[this], 0, 0)
if outputCharge[this] > 0 then
call SetItemCharges(k, outputCharge[this])
endif
// Disassemble Data setting
set ds[GetHandleId(k)] = this
// Give Item (Recursively Compiles All Remaining Recipes)
call UnitAddItem(u, k)
call EnableTrigger(GetTriggeringTrigger())
set k = null
endmethod
private static Table items
private method isItemRequirement takes integer id returns boolean
local integer i = count[this] - 1
loop
if id == itemId[6 * this + i] then
return true
endif
exitwhen i == 0
set i = i - 1
endloop
return false
endmethod
method compileEx takes unit u, item it returns nothing
local integer id = GetItemTypeId(it)
local integer i = 0
local integer h
local item k
local integer j = 0
local boolean b = true
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call DisableTrigger(GetTriggeringTrigger())
loop
exitwhen i == count[this]
set k = getItem(u, itemId[6 * this + i])
if k == null then
set k = it
set b = false
endif
set h = GetItemCharges(k)
if h > charge[6 * this + i] then
if this.isItemRequirement(GetItemTypeId(k)) then
call SetItemCharges(k, h - charge[6 * this + i])
endif
if b then
call UnitDropItemPoint(u, k, x, y)
else
set b = true
endif
set items.item[j] = k
set j = j + 1
else
if this.isItemRequirement(GetItemTypeId(k)) then
call RemoveItem(k)
endif
endif
set i = i + 1
endloop
// Create Effect
call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH, u, ATTACHMENT))
// Create Item And Set Charges
set k = CreateItem(output[this], 0, 0)
if outputCharge[this] > 0 then
call SetItemCharges(k, outputCharge[this])
endif
// Disassemble Data setting
set ds[GetHandleId(k)] = this
// Give Item (Recursively Compiles All Remaining Recipes)
call UnitAddItem(u, k)
loop
call UnitAddItem(u, items.item[j])
set items.item[j] = null
exitwhen j == 0
set j = j - 1
endloop
call items.flush()
call EnableTrigger(GetTriggeringTrigger())
set k = null
endmethod
static method iterateCompile takes unit u returns nothing
local thistype this = stack - 1
loop
if this.hasItems(u) then
call this.compile(u)
endif
exitwhen this == 1
set this = this - 1
endloop
endmethod
static method iterateCompileEx takes unit u, item it returns nothing
local thistype this = stack - 1
loop
if this.hasItemsEx(u, it) then
call this.compileEx(u, it)
endif
exitwhen this == 1
set this = this - 1
endloop
endmethod
static if PLAYER_SPECIFIC_RECIPES then
static boolean array au
method authorize takes integer id returns nothing
set au[this * 12 + id] = true
endmethod
method unauthorize takes integer id returns nothing
set au[this * 12 + id] = false
endmethod
method isAuthorized takes integer id returns nothing
return au[this * 12 + id]
endmethod
endif
static method disassemble takes item it returns integer
local thistype this = ds[GetHandleId(it)]
local integer i = 0
local real x = GetWidgetX(it)
local real y = GetWidgetY(it)
local unit u = GetItemOwner(it)
local integer size = UnitInventorySize(u)
local integer empty = 1
local boolean validOwner = (u != null)
local item iq
// Checking for valid recipe and inventory space
if this != 0 then
call DisableTrigger(GetTriggeringTrigger())
set enabled = false
// If the item is owned:
if validOwner then
// Get Empty Slots
loop
exitwhen i == size
if UnitItemInSlot(u, i) == null then
set empty = empty + 1
endif
set i = i + 1
endloop
// If there's not enough space, return failure
if count[this] > empty then
call EnableTrigger(GetTriggeringTrigger())
// Return Inventory Space Error
return 2
endif
set i = 0
endif
call RemoveItem(it)
// Loop through all requirements
loop
if itemId[6 * this + i] != NULL then
// Create item and set charges
set iq = CreateItem(itemId[6 * this + i], x, y)
if validOwner then
call UnitAddItem(u, iq)
endif
if charge[6 * this + i] > 0 then
call SetItemCharges(iq, charge[6 * this + i])
endif
endif
exitwhen i == 5
set i = i + 1
endloop
// Enable system
set enabled = true
// Null locals
set iq = null
set u = null
call EnableTrigger(GetTriggeringTrigger())
// Return Success
return 0
endif
// Return Invalid Item Error
return 1
endmethod
private static method systemConditions takes integer this returns boolean
static if PLAYER_SPECIFIC_RECIPES then
// If the system is enabled and the player is authorized for the recipe
return enabled and au[this * 12 + GetPlayerId(GetTriggerPlayer())] and not recipeOff[this]
else
// If the system is enabled
return enabled and not recipeOff[this]
endif
endmethod
private static method main takes nothing returns nothing
local integer id = GetItemTypeId(GetManipulatedItem())
local integer in = 1
local thistype this = Stack[id][0]
// Check for execution conditions
if systemConditions(this) then
loop
exitwhen this == 0
// If unit has items
if this.hasItems(GetManipulatingUnit()) then
// Compile recipe
call this.compile(GetManipulatingUnit())
return
endif
// Next Instance
set this = Stack[id][in]
set in = in + 1
endloop
endif
endmethod
method requires takes integer id, integer charges returns thistype
// Recipe Data
set itemId[6 * this + count[this]] = id
set charge[6 * this + count[this]] = charges
// replace this shit;
// Item Stack Add
if Stack[id] == 0 then
// If Stack Is Null, Create and Add
call Stack.create(id)
call Stack[id].add(this)
elseif not Stack[id].has(this) then
// Else, If Instance Is Not Present, Add
call Stack[id].add(this)
endif
// Increase Count
set count[this] = count[this] + 1
return this
endmethod
static method create takes integer result, integer charges returns thistype
local thistype this = stack
local integer i = 0
// Increase stack
set stack = stack + 1
// This Makes Iteration Faster (Helps Avoid A Few Checks)
loop
set itemId[6 * this + i] = NULL
exitwhen i == 5
set i = i + 1
endloop
// Recipe Data
set output[this] = result
set outputCharge[this] = charges
return this
endmethod
implement Init
endstruct
function CreateRecipe takes integer id, integer charge returns Recipe
return Recipe.create(id, charge)
endfunction
function AddRecipeRequirement takes Recipe this, integer id, integer charge returns nothing
call this.requires(id, charge)
endfunction
function EnableRecipe takes Recipe this returns nothing
call this.enable()
endfunction
function DisableRecipe takes Recipe this returns nothing
call this.disable()
endfunction
function IsRecipeEnabled takes Recipe this returns boolean
return this.isEnabled()
endfunction
function EnableRecipeSystem takes nothing returns nothing
set Recipe.enabled = true
endfunction
function DisableRecipeSystem takes nothing returns nothing
set Recipe.enabled = false
endfunction
function IsRecipeSystemEnabled takes nothing returns boolean
return Recipe.enabled
endfunction
function DisassembleItem takes item it returns integer
return Recipe.disassemble(it)
endfunction
function HasRecipeItems takes unit u, Recipe this returns boolean
return this.hasItems(u)
endfunction
function HasRecipeItemsEx takes unit u, Recipe this, item withThis returns boolean
return this.hasItemsEx(u, withThis)
endfunction
function CompileRecipe takes unit u, Recipe this returns nothing
call this.compile(u)
endfunction
function CompileRecipeEx takes unit u, Recipe this, item it returns nothing
call this.compileEx(u, it)
endfunction
//function IterateCompile
static if PLAYER_SPECIFIC_RECIPES then
function AuthorizePlayerRecipeById takes integer id, Recipe this returns nothing
call this.authorize(id)
endfunction
function UnauthorizePlayerRecipeById takes integer id, Recipe this returns nothing
call this.unauthorize(id)
endfunction
function IsPlayerAuthorizedRecipeById takes integer id, Recipe this returns boolean
return this.isAuthorized(id)
endfunction
function AuthorizePlayerRecipe takes player p, Recipe this returns nothing
call this.authorize(GetPlayerId(p))
endfunction
function UnauthorizePlayerRecipe takes player p, Recipe this returns nothing
call this.unauthorize(GetPlayerId(p))
endfunction
function IsPlayerAuthorizedRecipe takes player p, Recipe this returns boolean
return this.isAuthorized(GetPlayerId(p))
endfunction
endif
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct Demo extends array
static Recipe Orb
static Recipe SpiderRing
static Recipe Ring
static Recipe Wand
private static method onInit takes nothing returns nothing
// Beautiful API!
set Orb = CreateRecipe('rde3', 0)
set SpiderRing = CreateRecipe('sprn', 0)
set Ring = CreateRecipe('sora', 0)
set Wand = CreateRecipe('wlsd', 5)
call Orb.requires('rde1', 0).requires('rde1', 0)
call SpiderRing.requires('ram1', 0).requires('ram1', 0)
call SpiderRing.requires('ram1', 0).requires('ram2', 0)
call Ring.requires('sor5', 0).requires('sor3', 0)
call Ring.requires('sor2', 0)
call Wand.requires('will', 3).requires('I000', 1)
call BJDebugMsg("init")
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Testing requires RecipeEngine
globals
private constant string VERSION = "v2.0.0.0"
endglobals
private function dis takes nothing returns boolean
local integer i = DisassembleItem(UnitItemInSlot(gg_unit_Hamg_0009, 0))
if i == DISASSEMBLE_SUCCESS then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,5,"Succesfully Disassembled Item!")
elseif i == DISASSEMBLE_ERROR_INVALID then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,5,"Error: Invalid Item!")
else
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,5,"Error: Not enough space!")
endif
return false
endfunction
private function display takes nothing returns nothing
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Recipe Engine " + VERSION + ": By Magtheridon96\nSpecial Thanks to Diablo-dk for the original algorithms.\nTo disassemble the first item in your inventory, type \"-dis\"")
endfunction
private module Init
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TimerStart(CreateTimer(), 0, false, function display)
call TriggerRegisterPlayerChatEvent(t, Player(0), "-dis", true)
call TriggerAddCondition(t, Condition(function dis))
set t = null
endmethod
endmodule
private struct Inits extends array
implement Init
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library init initializer ini requires RecipeEngine
function ini takes nothing returns nothing
local location loc = GetRectCenter(bj_mapInitialPlayableArea)
call CreateFogModifierRadiusLocBJ(true,Player(0),FOG_OF_WAR_VISIBLE,loc,9999.00)
call RemoveLocation(loc)
set loc = null
endfunction
endlibrary