/***************************************************
*
* 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