• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Recipe System

Recipe System

Enables easy item recipe creation, including the option to dissamble recipe items again.


System code:

JASS:
//=======================================================================================================
// Recipe System
// By Fredbrik(Diablo-dk)
//
//=======================================================================================================
//globals
//integer               RN=0 // Recipe number.
//trigger               RT=CreateTrigger() // Main recipe trigger.
//boolean               RC=true
//integer array         itemid1
//integer array         itemid2
//integer array         itemid3
//integer array         itemid4
//integer array         itemid5
//integer array         itemid6
//integer array         ic //item count
//integer array         output
//endglobals
//=======================================================================================================
// User changeable constants
//=======================================================================================================
constant function Recipe_Effect takes nothing returns string
    return "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl" //An effect that comes whenever a recipe is made.
endfunction

constant function Recipe_AP takes nothing returns string
    return "origin" //Attachment point for Recipe_Effect()
endfunction
//=======================================================================================================
// This function will return the first item of entered Id in the unit's inventory.
function GetItem takes unit u, integer Id returns item
    local integer i=0
    local item it
    loop
        exitwhen i==6
        if GetItemTypeId(UnitItemInSlot(u,i)) == Id then
            return UnitItemInSlot(u,i)
        set i=5
        endif
        set i=i+1
    endloop
    return null
endfunction
//==============================
function HasItems takes unit u, integer i returns boolean
    local integer index=0
    local integer id=-1
    local integer b1=0
    local integer b2=0
    local integer b3=0
    local integer b4=0
    local integer b5=0
    local integer b6=0
    loop
        exitwhen index==6
        set id=GetItemTypeId(UnitItemInSlot(u,index))
        if id == 0 then
            set id=-1
        endif
        if id == udg_itemid1[i] and b1 == 0 then
            set b1=1
            set id=-1
        endif
        if id == udg_itemid2[i] and b2 == 0 then
            set b2=1
            set id=-1
        endif
        if id == udg_itemid3[i] and b3 == 0 then
            set b3=1
            set id=-1
        endif
        if id == udg_itemid4[i] and b4 == 0 then
            set b4=1
            set id=-1
        endif
        if id == udg_itemid5[i] and b5 == 0 then
            set b5=1
            set id=-1
        endif
        if id == udg_itemid6[i] and b6 == 0 then
            set b6=1
            set id=-1
        endif
        if b1+b2+b3+b4+b5+b6 == udg_ic[i] then
            return true
        endif
        set index=index+1
    endloop
    return false
endfunction
//=======================================================================================================
// User Functions:
// Recipe Creating:
//
//=======================================================================================================
function CreateRecipe takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6,integer output returns nothing
    set udg_RN=udg_RN+1
    set udg_itemid1[udg_RN]=i1
    set udg_itemid2[udg_RN]=i2
    set udg_ic[udg_RN]=2
    if i3 != 0 then
        set udg_itemid3[udg_RN]=i3
        set udg_ic[udg_RN]=udg_ic[udg_RN]+1
    endif
    if i4 != 0 then
        set udg_itemid4[udg_RN]=i4
        set udg_ic[udg_RN]=udg_ic[udg_RN]+1
    endif
    if i5 != 0 then
        set udg_itemid5[udg_RN]=i5
        set udg_ic[udg_RN]=udg_ic[udg_RN]+1
    endif
    if i6 != 0 then
        set udg_itemid6[udg_RN]=i6
        set udg_ic[udg_RN]=udg_ic[udg_RN]+1
    endif
    set udg_output[udg_RN]=output
endfunction
function CreateRecipe2 takes integer i1,integer i2,integer i3 returns nothing
    set udg_RN=udg_RN+1
    set udg_itemid1[udg_RN]=i1
    set udg_itemid2[udg_RN]=i2
    set udg_output[udg_RN]=i3
    set udg_ic[udg_RN]=2
endfunction

// Creates a recipe that requires 2 items to combine into a new item. i3 is the combined item.
// Example: call CreateRecipe2('I000','I001','I002')
function CreateRecipe3 takes integer i1,integer i2,integer i3,integer i4 returns nothing
    set udg_RN=udg_RN+1
    set udg_itemid1[udg_RN]=i1
    set udg_itemid2[udg_RN]=i2
    set udg_itemid3[udg_RN]=i3
    set udg_output[udg_RN]=i4
    set udg_ic[udg_RN]=3
endfunction

// The same as CreateRecipe2 except this requires 3 items to combine. i4 is the combined item.
function CreateRecipe4 takes integer i1,integer i2,integer i3,integer i4,integer i5 returns nothing
    set udg_RN=udg_RN+1
    set udg_itemid1[udg_RN]=i1
    set udg_itemid2[udg_RN]=i2
    set udg_itemid3[udg_RN]=i3
    set udg_itemid4[udg_RN]=i4
    set udg_output[udg_RN]=i5
    set udg_ic[udg_RN]=4
endfunction

// The same as CreateRecipe2 except this requires 4 items to combine. i5 is the combined item.
function CreateRecipe5 takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6 returns nothing
    set udg_RN=udg_RN+1
    set udg_itemid1[udg_RN]=i1
    set udg_itemid2[udg_RN]=i2
    set udg_itemid3[udg_RN]=i3
    set udg_itemid4[udg_RN]=i4
    set udg_itemid5[udg_RN]=i5
    set udg_output[udg_RN]=i6
    set udg_ic[udg_RN]=5
endfunction

// The same as CreateRecipe2 except this requires 5 items to combine. i6 is the combined item.
function CreateRecipe6 takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6,integer i7 returns nothing
    set udg_RN=udg_RN+1
    set udg_itemid1[udg_RN]=i1
    set udg_itemid2[udg_RN]=i2
    set udg_itemid3[udg_RN]=i3
    set udg_itemid4[udg_RN]=i4
    set udg_itemid5[udg_RN]=i5
    set udg_itemid6[udg_RN]=i6
    set udg_output[udg_RN]=i7
    set udg_ic[udg_RN]=6
endfunction

// The same as CreateRecipe2 except this requires 6 items to combine. i7 is the combined item.
//===================================================================================================
// This function disassembles a recipe item to its original components.

function DisItem takes unit u,item it returns boolean
    local integer c=GetItemUserData(it)
    local item array newitem
    local integer i=udg_ic[c]
    if it != null then
        if i <= 6-UnitInventoryCount(u)+1 and i > 0 then
            set udg_RC=false
            if udg_itemid2[c] != null then
                set newitem[1]=CreateItem(udg_itemid1[c],GetUnitX(u),GetUnitY(u))
                set newitem[2]=CreateItem(udg_itemid2[c],GetUnitX(u),GetUnitY(u))
                endif
            if udg_itemid3[c] != null then
                set newitem[3]=CreateItem(udg_itemid3[c],GetUnitX(u),GetUnitY(u))
                call UnitAddItem(u,newitem[3])
            endif
            if udg_itemid4[c] != null then
                set newitem[4]=CreateItem(udg_itemid4[c],GetUnitX(u),GetUnitY(u))
                call UnitAddItem(u,newitem[4])
            endif
            if udg_itemid5[c] != null then
                set newitem[5]=CreateItem(udg_itemid5[c],GetUnitX(u),GetUnitY(u))
                call UnitAddItem(u,newitem[5])
            endif
            if udg_itemid6[c] != null then
                set newitem[6]=CreateItem(udg_itemid6[c],GetUnitX(u),GetUnitY(u))
                call UnitAddItem(u,newitem[6])
            endif
            call RemoveItem(it)
            call UnitAddItem(u,newitem[1])
            call UnitAddItem(u,newitem[2])

        set newitem[1]=null
        set newitem[2]=null
        set newitem[3]=null
        set newitem[4]=null
        set newitem[5]=null
        set newitem[6]=null
        set udg_RC=true
        else
            return false
        endif
    endif
    return true
endfunction
//=======================================================================================================
//
//Main Recipe Function: Do not change unless you know what you are doing
//
//=======================================================================================================
function Recipe_Main takes nothing returns nothing
    local item it
    local integer i=0
    local unit u=GetManipulatingUnit()
    loop
        exitwhen i==udg_RN
        set i=i+1
        if udg_RC == true then
            if udg_ic[i] == 6 then
                if HasItems(u,i) then
                    call RemoveItem(GetItem(u,udg_itemid1[i]))
                    call RemoveItem(GetItem(u,udg_itemid2[i]))
                    call RemoveItem(GetItem(u,udg_itemid3[i]))
                    call RemoveItem(GetItem(u,udg_itemid4[i]))
                    call RemoveItem(GetItem(u,udg_itemid5[i]))
                    call RemoveItem(GetItem(u,udg_itemid6[i]))
                    call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
                    set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
                    call SetItemUserData(it,i) //Used for disassembling.
                    call UnitAddItem(u,it)
                    set i=udg_RN
                endif
            elseif udg_ic[i] == 5 then
                if HasItems(u,i) then
                    call RemoveItem(GetItem(u,udg_itemid1[i]))
                    call RemoveItem(GetItem(u,udg_itemid2[i]))
                    call RemoveItem(GetItem(u,udg_itemid3[i]))
                    call RemoveItem(GetItem(u,udg_itemid4[i]))
                    call RemoveItem(GetItem(u,udg_itemid5[i]))
                    call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
                    set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
                    call SetItemUserData(it,i) //Used for disassembling.
                    call UnitAddItem(u,it)
                    set i=udg_RN
                endif
            elseif udg_ic[i] == 4 then
                if HasItems(u,i) then
                    call RemoveItem(GetItem(u,udg_itemid1[i]))
                    call RemoveItem(GetItem(u,udg_itemid2[i]))
                    call RemoveItem(GetItem(u,udg_itemid3[i]))
                    call RemoveItem(GetItem(u,udg_itemid4[i]))
                    call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
                    set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
                    call SetItemUserData(it,i) //Used for disassembling.
                    call UnitAddItem(u,it)
                    set i=udg_RN
                endif
            elseif udg_ic[i] == 3 then
                if HasItems(u,i) then
                    call RemoveItem(GetItem(u,udg_itemid1[i]))
                    call RemoveItem(GetItem(u,udg_itemid2[i]))
                    call RemoveItem(GetItem(u,udg_itemid3[i]))
                    call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
                    set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
                    call SetItemUserData(it,i) //Used for disassembling.
                    call UnitAddItem(u,it)
                    set i=udg_RN
                endif
            elseif udg_ic[i] == 2 then
                if HasItems(u,i) then
                    call RemoveItem(GetItem(u,udg_itemid1[i]))
                    call RemoveItem(GetItem(u,udg_itemid2[i]))
                    call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
                    set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
                    call SetItemUserData(it,i) //Used for disassembling.
                    call UnitAddItem(u,it)
                    set i=udg_RN
                endif
            endif
        endif
    endloop
    set it=null
    set u=null
endfunction
function InitRecipe takes nothing returns nothing
    set udg_RT=CreateTrigger()
    set udg_RC=true
    call TriggerRegisterAnyUnitEventBJ( udg_RT, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction(udg_RT,function Recipe_Main)
endfunction
//call this at map init.


//forced by WE
function InitTrig_Recipe takes nothing returns nothing
endfunction
// End Recipe
Requirements:

Recipe system has no specific requirements. Get quickly started by reading the manual included within the demo map.
Furthermore I made a small sample code to demonstrate how to use the system.

Author's note:

Please give proper credits, when using Recipe System in your map.

Changelog:
version 1.22:
Fixed a bug in the implemention readme that would cause the system not to work correctly.

version 1.21:
Shortened a few functions.

version 1.2:
Fixed a bug that caused recipes with 2 or more of the same item to bug.

version 1.1:
Optimized code a bit.


Keywords:
recipe, itemrecipe
Contents

Recipe System (Map)

Reviews
19:01, 2ndth Sep 2015 This resource has been re-approved by BPower. From moderator to user: Perfect if you need a simple item recipe system. It's very fail-safe and easy to setup. Keep in mind that the system manipulates ItemUserData. In case...
Level 2
Joined
Aug 25, 2011
Messages
17
ok so is this a spell O_O i would like my game to be like DoTA so that when you buy everything in the list you'll get that item.Does this work like DoTA?
 
Level 18
Joined
Nov 21, 2012
Messages
835
Functions

Hello!
System works fine in my map, but sometimes (too often) desync appears at map initialization. Here my question. How to move all Recipie Functions from block called 'custom script code' into a trigger which can be run few sec after map init.

Im Gui user and I dont know Jass. Nothing is executed at map init only Recipie functions so I triyng to find reason for desync, thats why I want them not to run at map init.
regards Zibi
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Your system is the first on my long list of re-reviewing resources.

Edit:

TriggerConditions are better in terms of performance than TriggerActions. ( benchmark )
You could change that in your InitRecipe function.

In function Recipe_Main:
udg_RC == true could be optimized to udg_RC

In function DisItem the item array is not required and could be optimized to UnitAddItem(CreateItem(...)).
Also not every unit has an inventory size of 6. There is a native to get the proper max slot number UnitInventorySize(unit).
A bigger number does however not bug, it simply does nothing.

I'm not happy with the function name "GetItem". In my mind it is too generic and could cause a code conflict for map-makers.
In this function you have a local item handle, which is not required at all.
Furthermore setting the loop index i to 5 is not required after returning a boolean. This line can be removed.
Again a unit inventory size can be smaller than 6.

HasItems is also too generic function name in my opinion.
 
Last edited:
Level 6
Joined
Sep 19, 2007
Messages
213
Why wont this detect my Custom items Yes im using the proper 4 digit raw code, it works with regular wc3 items but i enter info for Custom Example: call CreateRecipe('I021', 'I00Z', 0,0,0,0, 'I00Y') it is just not working it wont give me the item or remove the items i have.
 
Level 7
Joined
Mar 10, 2013
Messages
366
The System is really good, looking forward to use it. Just three things I would like to say:
1. It would be easier to import if your wrapper that in a Library.
2. Use more verbose variables, if someone wants to understand what you did, if makes really hard the decrifrate. With better name defined variables, it would make it easier.
3. Please, finish the documentation.
 
Level 6
Joined
Sep 19, 2007
Messages
213
check in Object Editor if these items exists:
'I021', 'I00Z', 'I00Y'
make sure you didnt mess I with 1 like I021 - I02I

try maybe CreateRecipe2('I021', 'I00Z', 'I00Y')
Ya i have tried that way it still didnt work its weird these items are created I know it is I now L really weird driving me nuts lol

Edit: I have figured it out that you very much i was an idiot and picking up the wrong Item LMAO
 
Last edited:
Top