Combining items in inventory to make new items | Dota 2 Workshop Tool

This tutorial will assume you have a addon_game_mode.lua file, and that is has the appropriate methods required to launch an addon.

The premise for this tutorial is the following question: "How do I make it that so having the correct items in the correct order results in the items being combined?" Note that making custom item recipes is a much easier way to go about this if recipes make sense for your mod.



The cheeky answer is lua, the better answer is lua examples:

We want some global variables that so we know the item combinations:

allowed_item_combos_two = {}
allowed_item_combos_three = {}

In our InitGameMode() function, we want to listen to various events that cause items to appear in the players inventory.

-- Listen to item events
-- syntax here is ([event to listen for], [handle of function to call], [context]) 
ListenToGameEvent("dota_item_picked_up", Dynamic_Wrap(k_GameMode, 'OnItemUpdate'), self)
-- This one is broken!
ListenToGameEvent("dota_inventory_changed", Dynamic_Wrap(k_GameMode, 'OnItemUpdate'), self)
ListenToGameEvent("dota_item_purchased", Dynamic_Wrap(k_GameMode, 'OnItemUpdate'), self)
ListenToGameEvent("dota_item_gifted", Dynamic_Wrap(k_GameMode, 'OnItemUpdate'), self)

This sets up listeners that will listen for when the items appear or move (well, move if the trigger wasn't currently broken!). We also want, inside InitGameMode(), the list of item recipes we'll be using:

allowed_item_combos_two["item_ward_observer"]  = {"item_clarity", "item_tango"}
allowed_item_combos_three["item_ward_sentry"] = {"item_mantle", "item_clarity", "item_tango"}

The format used here should be reasonably obvious. I have separate tables for items created using two and three components, simply because it made explanations of the code easier.

Finally, we want the actual function that does the combining:

function k_GameMode:OnItemUpdate(keys)

-- Lets find the hero we want to work with
player = PlayerInstanceFromIndex(keys.PlayerID+1)
hero =   player:GetAssignedHero()

-- lua uses an interesting sytax for for loops. for [start], [finish], [increment]
-- we want to run over the 6 inventory slots,, starting at index 0
for i=0,5,1 do 
    -- If there is no item here, then we cannot do anything!
    if  hero:GetItemInSlot(i) ~= nil then
        -- Lets grab the item name, since we'll need it for print statements
        local item1 = hero:GetItemInSlot(i):GetClassname()

        -- No point trying to combine three items after position 4
        if i < 4 then
            if hero:GetItemInSlot(i+1) == nil or hero:GetItemInSlot(i+2) == nil then
                -- One of the two items after our current one is nil, so we can't use it
                print("No three-part combination possible using " .. item1 .. " as the first item")
            else
                -- There are items there!
                local item2 = hero:GetItemInSlot(i+1):GetClassname()
                local item3 = hero:GetItemInSlot(i+2):GetClassname()
                print("combination of " .. item1 .. ", "  .. item2 .. " and " .. item3 .." possible")

                -- Finally, lets check to see if this pair is in our list of items that can be combined
                for result, components in pairs(allowed_item_combos_three) do
                    if components[1] == item1 and components[2] == item2 and components[3] == item3 then
                        -- It is!
                        print(result .. " can be made!")
                        -- Lets remove the old items
                        hero:GetItemInSlot(i):Kill()
                        hero:GetItemInSlot(i+1):Kill()
                        hero:GetItemInSlot(i+2):Kill()
                        -- And add the new one!
                        hero:AddItem(CreateItem(result, hero, hero))
                    end
                end
            end
        end

        if i < 5 then
            if hero:GetItemInSlot(i+1) == nil then
                print("No two-part combination possible using " .. item1 .. " as the first item")
            else

                local item2 = hero:GetItemInSlot(i+1):GetClassname()
                print("combination of " .. item1 .. " and "  .. item2 .. " possible")
                for result, components in pairs(allowed_item_combos_two) do
                    if components[1] == item1 and components[2] == item2 then
                        print(result .. " can be made!")                           
                    end
                end
            end
        end
    end
end
end

This isn't the most extendable code, so I'm going to tidy it up a bit so it works nicely with 4 / 5 items, items out of order and stuff like that. But, for now, its much easier to understand!

Hope this is helpful, Let me know if I made any mistakes or something isn't clear! I prefer to put explanations as code comments, so the code is still understandable when you copy it. If this is a pain, I can reformat.

Post a Comment

Powered by Blogger.