[Solved] Item Combine Setup with Upgrade Variants?

Level 5
Joined
Jun 24, 2024
Messages
59
Hi again,

now for something more difficult (for me) - i set up base items, they give basic stat increases like stats, atk, akt speed, hp, mana ect.
Those items come in variations from +1 to +10 (It's also in their name) Now i want to use these for recipes.
I have a simple trigger that does what i want - Hero has 2 correct items in their inventory + recipe = remove those 3 items and add recipe item to the hero.This works for a specific setup with items +1.

Is there a way that i create a trigger that recognizes the number in the end of the name and either chooses the lowest or a round up of them "Sum / 2" and then sets the correct item which is existing in the editor as +1 to +10 variants?

An example would be:

Recipe: Claws of Attack + Gloves of Haste = Claw Gauntlets
Items to combine: Claws of Attack +3 with Gloves of Haste +7

Result is either Claw Gauntlets +3 with Variant "Choose lowest" or Claw Gauntlets +5 with Variant "divide and round"

This way i would only need one trigger for each item combo instead of one for each item variant, which would result in 810* trigger variants since i got 9 base items times 9 possible combos times 10 different variants.. :hohum:
 
Last edited:

Remixer

Map Reviewer
Level 33
Joined
Feb 19, 2011
Messages
2,112
Well you can always detect which variant of the item type is carried, and choose for example the highest.

1. Detect the unit is carrying Claws of any time (or condition) and Gloves.
2. Detect if the unit has Claws +9, if not, check if it has +8, if not +7... Until you match a Claws of +5 for example.
3. Then we know the highest Claws the unit is carrying is Claws +5
4. Combine Claws +5 with the Gloves (which you could combine using the same logic).
5. If you want to possibly combine multiple claws, you need to check if the unit has another claws of the same level or more that are lower level.
 
Level 5
Joined
Jun 24, 2024
Messages
59
The Spreadsheet looks like this:
10 Basic items | 2 Items + 1 Recipe = 1 Unique Item
The 10 Basic items have 10 different variants (From +1 to +10 in their name)
Which would mean i need to check 90 combinations for a single recipe in a trigger.
Or create 81 triggers for 10 combinations for each "+" Variant.

Maybe i understood your suggestion wrong or am too confused to get my current idea into a trigger but the question meant:
Can i "detect" the +1 to +10 numbers in the item names and set a temp variable to the rounded or lowest number of it to then determine which item will be created. I remember something like "get a certain part of the name (String?), convert it or check it / set it to then use it further or counter check with another string. Sorry

Edit: Sadly there is no such thing as "Item Group", this would make things very easy..
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Edit: Sadly there is no such thing as "Item Group", this would make things very easy..
I'm not saying that this is the proper solution here, but you can always recreate the concept of an Item Group. But I don't think that's what you want here. What you would likely want is a database where you store data associated with Item-Type ID's rather than an individual Item.

Hashtables come to mind. The Parent Key = Group ID, Child Keys = Item-Types, or whatever data you want to store related to the Item-Types within the "group". You will need to convert an Item-Type to an Integer and vice versa but that's pretty easy.

Save data:
  • Set MyItemType = Claws of Attack +1
  • Custom script: set udg_MyInteger = udg_MyItemType
  • Hashtable - Save MyInteger as 1 of 10 in MyItemHashtable
Load data:
  • Set MyInteger = (Load 1 of 10 in MyItemHashtable)
  • Custom script: set udg_MyItemType = udg_MyInteger
  • Item - Create 1 MyItemType at (Center of (Playable map area))
The Parent Key could also represent an Item-Type ID, meaning that every Item-Type could store as much custom data as you'd like. For example: An Item-Type could know which Item-Types it upgrades/downgrades into, it could also have a custom Level value without any negative side effects, a custom Weight value used in RNG calculations, etc.

Or create 81 triggers for 10 combinations for each "+" Variant.
If you're ever creating 81 triggers for a single system then there's an extremely high chance that you're doing something wrong. The only time I've ever needed to do that was for Region Events because the Region system is very limited, and for Events that are only accessible via the Specific category like "A unit Acquires a target" - in which case it's much better to handle it through code to dynamically create triggers as needed.
 
Last edited:
Level 5
Joined
Jun 24, 2024
Messages
59
Hi again.

So, i think i got the whole Hashtable Schtick and unterstand how those work.
Now behold my Mess:
  • HashtableRecipeTest
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set VariableSet AItemTypeInt = 2
      • Hashtable - Save AItemTypeInt as 0 of 0 in (Last created hashtable).
      • -------- --------
      • Set VariableSet AItemTypeID = |cff00ff00Claw Gauntlets|r
      • Custom script: set udg_AItemTypeInt = udg_AItemTypeID
      • Hashtable - Save AItemTypeInt as 0 of 1 in (Last created hashtable).
      • -------- --------
      • Set VariableSet AItemTypeID = Claws of Attack +1
      • Custom script: set udg_AItemTypeInt = udg_AItemTypeID
      • Hashtable - Save AItemTypeInt as 0 of 2 in (Last created hashtable).
      • -------- --------
      • Set VariableSet AItemTypeID = Gloves of Haste +1
      • Custom script: set udg_AItemTypeInt = udg_AItemTypeID
      • Hashtable - Save AItemTypeInt as 0 of 3 in (Last created hashtable).
      • -------- --------
(Variable ARecipeCount is set to 1 - There is only one Recipe as for now)

The Hashtable should look like this:
[0][0] = Amount of items needed for Combination = 2
[0][1] = ID of the Recipe Item needed for Combination = Claw Gauntlets
[0][2] = ID of first item needed = Claws Of Attack
[0][3] = ID of second item needed = Gauntlets of Haste


  • RecipeUseTest
    • Events
      • Unit - A unit Uses an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Scoll of Combine: Claw Gauntlets (|cffff0000+10|r Atk, |cffff0000+10%|r AtkSpd)
    • Actions
      • For each (Integer A) from 1 to ARecipeCount, do (Actions)
        • Loop - Actions
          • For each (Integer A) from (Load (Integer A) of 0 from (Last created hashtable).) to (Integer B), do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Triggering unit) has (Load (Key (Load (Integer A) of 0 in (Last created hashtable).).) of ((Integer B) + 1) in (Last created hashtable).)) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Integer B) + 1) Equal to (Key (Load (Integer A) of 0 in (Last created hashtable).).)
                    • Then - Actions
                      • Item - Remove (Item carried by (Triggering unit) of type Claws of Attack +1)
                      • Item - Remove (Item carried by (Triggering unit) of type Gloves of Haste +1)
                      • Hero - Create |cff00ff00Claw Gauntlets|r and give it to (Triggering unit)
                    • Else - Actions
                • Else - Actions
                  • Game - Display to (Player group((Owner of (Triggering unit)))) the text: tem creation failed.
As of right now it does not work, obviously i need to figure out how to correctly adres the item i want to check and compare the components.
Also the Then - Remove part is not configured properly, i would need to pick the item somehow.

Maybe i am missing something or understood it wrong? Question one would be - Is the transformed integer of the item a permanent one?
Can i even counter check that ID to an item which was created via trigger as a drop? How would this type of trigger behave, if i had 2 of each items in my inventory? Should i rather only use certain slots of an inventory for crafting or can i check within a loop from 1 to 6 and set the picked once for deletion if all conditions are met? There must be a simpler solution, i'Ve seen very similar systems in other maps but sadly those are all protected :)

Edit: Well.. thanks to a friend i got info about this lil magic:
and i will use the system :D Thanks for your help guys!
 
Last edited:
Level 5
Joined
Jun 24, 2024
Messages
59
Update and new Reply because it is a completely new problem:

i started using the Item Recipe System [GUI Friendly] and initial tests where working very well,
i then added a lot of variable Setups to the Recipes list over the past hours and now i get compile errors when trying to save/test.
Can anybody narrow down, why this happens?

I enabled and disabled all triggers to narrow down the cause but in the end this even happened, when i re-downloaded the Example Map and just opened it to save it. Then it throws 80 compiler errors. When i open it the first time and test it right away, the combine system works excellently..

Any ideas on how or why the code breaks?
 
Level 19
Joined
Oct 17, 2012
Messages
859
You need to check Enable JassHelper and Enable vJass if you are on patches 1.28+. For older patches, you will need JNGP or WEX to compile and save your map. Other options would be to use JassHelper via command line or Better Triggers.

Enable JASSHelper.gif
 
Last edited:
Level 5
Joined
Jun 24, 2024
Messages
59
Weirdly enough it was enabled.
By disabling it, saving + closing and ignoring the errors.
Restarting the Editor and enabling it again + reactivating the triggers it works now.

I use other engines/systems as well so i don't know where this bug came from...
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
I realize you found a nice solution, but here's a breakdown:

You were using A twice here, when you meant to use B in the second For Loop:
  • For each (Integer A) from
  • For each (Integer B) from
It's usually a good idea to use your own Integer variables as well, instead of relying on these.

So the idea of the system would be to have it all automated, so you wouldn't be using a Condition to check for a specific Scoll of Combine and you wouldn't be Creating/Removing specific Item-Types. Everything would be gotten from the Hashtable and managed automatically. You would also want to store your Hashtable in a variable, and reference that instead of (Last created hashtable). Never rely on the (Last created) of something unless it's like a Special Effect/Unit that you JUST created and are going to immediately interact with.

In your case it would've made sense to do something like this for saving your data:

Parent Key:
Scroll Item-Type Id (ie: Your AItemTypeID variable)

Child Keys:
-1 = How many items are used in the combination (excluding the scroll)
0 = The result of the combination (ie: Claw Gauntlets)
1 = The first item-type id (ie: Claws of Attack)
2 = The second item-type id (ie: Gloves of Haste)
// Add more as needed

  • Set Variable AItemTypeID = Scroll of Combine: Claw Gauntlets
  • Custom script: set udg_AItemTypeInt = udg_AItemTypeID
  • -------- --------
  • -------- Child #-1, how many item-types are used in the combination (exclude the scroll and the result): --------
  • Hashtable - Save 2 as -1 of AItemTypeInt in ItemHashtable.
  • -------- --------
  • -------- Child #0, the final result item-type: --------
  • Set Variable BItemTypeID = Claw Gauntlets
  • Custom script: set udg_BItemTypeInt = udg_BItemTypeID
  • Hashtable - Save BItemTypeID as 0 of AItemTypeInt in ItemHashtable.
  • -------- --------
  • -------- Child #1, first item-type used: --------
  • Set Variable BItemTypeID = Gloves of Haste +1
  • Custom script: set udg_BItemTypeInt = udg_BItemTypeID
  • Hashtable - Save BItemTypeInt as 1 of AItemTypeInt in ItemHashtable.
  • -------- --------
  • -------- Child #2, second item-type used: --------
  • Set Variable BItemTypeID = Claws of Attack +1
  • Custom script: set udg_BItemTypeInt = udg_BItemTypeID
  • Hashtable - Save BItemTypeInt as 2 of AItemTypeInt in ItemHashtable.
This can be automated further by using Arrays to hold your data temporarily and running a separate trigger to handle Saving this data into the Hashtable.

The end result for setting up an Item combination could look something like this:
  • Set Variable Combine_Scroll = Scroll of Combine: Claw Gauntlets
  • Set Variable Combine_Component_Count = 2
  • Set Variable Combine_Components[1] = Gloves of Haste +1
  • Set Variable Combine_Components[2] = Claws of Attack +1
  • Trigger - Run Add Combined Items To Hashtable (ignoring conditions)
The "Add Combined Items To Hashtable" trigger would do all of the conversion stuff and Save everything into the Hashtable. That way you can easily create Item combinations without having to worry about the confusing "under the hood" stuff going on in order to Save that data.

Then when you use a Scroll you would get it's Item-Type Id using the following trigger:
  • Events
    • Unit - A unit Uses an item
  • Conditions
  • Actions
    • Custom script: set udg_ItemTypeIntA = GetItemTypeId(GetManipulatedItem())
    • Set Variable Combine_Component_Count = (Load -1 of ItemTypeIntA from ItemHashtable)
    • If Combine_Count Equal to 0 Then (Skip remaining actions) Else (Do nothing)
    • -------- Proceed to Load the rest of the data from the Hashtable using ItemTypeIntA as the Parent key. --------
    • -------- Use For Loops to loop over the unit's entire inventory and test each inventory slot to see if it has the next needed Item-Type. --------
    • -------- From there it will vary how you confirm a success or not and the complication can vary based on your map's limitations. --------
The Custom Script in the first line gets you the Item-Type Id (integer) of your Used item. If Combine_Component_Count is equal to ZERO then we know the Item we just used isn't part of the Item combination system and we can exit the trigger early. That way we can avoid running all of this complicated logic when your Hero uses a Healing Salve, for example.
 
Last edited:
Top