HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Need a JASS function for item recipes

08-16-2004, 03:20 AM#1
volatile
I have attempted to make a system in the GUI that checks a Hero's inventory to find recipes every time an item is aquired. Since the GUI isn't very flexible, I have yet to find a system that works. I have not net made the leap to JASS but am constantly finding myself trying to program 1 function in the GUI and have other triggers refer to it to get the job done.
Simply said, I need a JASS function that will check a Hero's inventory for combinations of 3 items and will allow me to remove the 3 items and place 1 item in their place. The 1 item is definately related to the recipe of the 3. Thanks.
08-17-2004, 03:38 AM#2
BDSM
You can do this in the GUI, although you can do it in JASS as well. I'll walk you through the steps you would need to do this in GUI. Probably the easiest way at first - until you get the hang of things - would be to have one trigger for each item combination you want to have. This method, however, will probably be tedious to maintain if you have quite a few number of combinations possible. But here is one trigger for one item.

Code:
Your Merged Item
    Events
        Unit - A unit Acquires an item
    Conditions
        Or - Any (Conditions) are true
            Conditions
                (Item-type of (Item being manipulated)) Equal to Item Part 1
                (Item-type of (Item being manipulated)) Equal to Item Part 2
                (Item-type of (Item being manipulated)) Equal to Item Part 3
    Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                And - All (Conditions) are true
                    Conditions
                        ((Hero manipulating item) has an item of type Item Part 1) Equal to True
                        ((Hero manipulating item) has an item of type Item Part 2) Equal to True
                        ((Hero manipulating item) has an item of type Item Part 3) Equal to True
            Then - Actions
                Item - Remove (Item carried by (Hero manipulating item) of type Item Part 1)
                Item - Remove (Item carried by (Hero manipulating item) of type Item Part 2)
                Item - Remove (Item carried by (Hero manipulating item) of type Item Part 3)
                Hero - Create Your Merged Item and give it to (Hero manipulating item)
            Else - Actions

Now, this is just a basic example. You could easily get more complex in what you setup, but this might get you started.
08-17-2004, 05:57 AM#3
volatile
That trigger works fine if you have 3 different items, but I'm actually gonna be using the same items as well. In your trigger it will check to see if the hero has one item, if he does, then it checks to see if he has all 3 items, however, if 2 of those items are the same, it will basically check the same item twice and return "true" even though it's really "false". This is what I'm having trouble with. Thx for the help, but I need a more complicated trigger.

the tricky part is in the combos

if unit has item a, item a, and item b then remove old items and give new item.
warcraft naturally will check for item a which is true, then will check again, and is true even if the hero only has 1 of item a... Are you understanding me? That's the hard part :/ I have to recognize the difference between item a and a 2nd item a in the hero's inventory.
08-17-2004, 06:54 AM#4
BDSM
No, it works like this:
- hero picks up item, item is part of the combo for item X
- checks to see if hero has all 3 items for item X
- if true, remove the 3 items, add X

In the case of a duplicate or triplicate item (2 item A), count the number of item type A's in the units inventory, assuming it has at least one.
08-17-2004, 10:01 AM#5
volatile
BDSM, I don't think you understand the complexity of this problem. You simplified it very nicely, unfortunately warcraft doesn't enable you to say "if hero has 2 of this item" you have to code that yourself. That's what all the do/for/loops are up top that the other person was getting at. Sure it's easy to say, but coding it is another thing... If you have a WORKING trigger, plz, post it. Otherwise I believe we can do without the "oversimplified" comments. If this were a simple matter, it would be solved by now... I have a grasp of programming and functions and understand how to get many things done, trust me, this is a difficult situation and I havn't found a solution yet in my search...

Please, if anyone can solve this riddle let us know, I think this would be a good thread to have an answer too.
08-17-2004, 08:12 PM#6
BDSM
I understand perfectly the complexity of the problem; I was just assuming you would be able to come up with some of these simple solutions on your own, i.e. loops, if/thens etc. It's relatively simply to see if a unit has 2 of some type of item - yes, you have to create this yourself. I was trying to help guide you, but obviously you just want something that works. I could put together a system that would work fine for you, but alas, I do not have the time - thus the 'oversimplified' guidance. Sorry you didn't find it at all helpful.
08-18-2004, 12:07 AM#7
Cubasis
A pretty cool challenge. And once again, the (well, my) answer is GameCache.

Here's what I quickly wrote up in notepad (as i'm not on my own comp). Notice that I have not compiled it, so it may have tons of syntax errors, and it may well have alot of logic bugs, as I didn't even re-read it. There may also well be more efficient/cooler ways to solve this problem, but this one is atleast pretty proffesional and tweakable.

But here it is.

Code:
function DebugIdInteger2IdString takes integer value returns string
   local string charMap = "..................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
   local string result = ""
   local integer remainingValue = value
   local integer charValue
   local integer byteno
   set byteno = 0
   loop
	  set charValue = ModuloInteger(remainingValue, 256)
	  set remainingValue = remainingValue / 256
	  set result = SubString(charMap, charValue, charValue + 1) + result
	  set byteno = byteno + 1
	  exitwhen byteno == 4
   endloop
   return result
endfunction
function GetOrderedString takes integer ItemA, integer ItemB, integer ItemC returns string
   local integer array Items
   local integer counter = 3
   local integer i = 0
   local integer Smallest = 0
   local string s = ""

   set Items[0] = 0
   set Items[1] = ItemA
   set Items[2] = ItemB
   set Items[3] = ItemC

   loop
	  exitwhen counter == 0
	  set i = 0
	  set Smallest = 0
	  loop
		 set i = i + 1
		 if(Items[i] > Items[Smallest]) then
			set Smallest = i
		 endif
		 exitwhen i >= counter
	  endloop
	  set s = s + DebugIdInteger2IdString(Items[Smallest])
	  set Items[Smallest] = Items[counter]
	  set counter = counter - 1
   endloop
   return s
endloop
	  
function GetComboItem takes integer ItemA, integer ItemB, integer ItemC returns integer
   return GetStoredInteger(udg_ItemComboGC, GetOrderedString(ItemA,ItemB,ItemC), "ItemType")
endfunction

function AddComboItem takes integer ItemA, integer ItemB, integer ItemC, integer Result returns nothing
   call StoreInteger(udg_ItemComboGC, GetOrderedString(ItemA,ItemB,ItemC), "ItemType", Result)
endfunction

function CheckInventory takes unit WhichHero returns nothing
   local integer i = 0
   local integer counter = 0
   local item array Items
   local integer array Types
   local integer P1 = 0
   local integer P2 = 0
   local integer P3 = 0
   local integer Combo

   loop
	  exitwhen i >= 6
	  set Items[counter] = UnitItemInSlot(WhichHero,i)
	  if(Items[counter] != null) then
		 set Types[counter] = GetItemTypeId(Items[counter])
		 set counter = counter + 1
	  endif
	  set i = i + 1
   endloop
   if(counter>=3)then
   loop
	  exitwhen P1 >= counter-2
	  set P2 = P1 + 1
	  loop
		 exitwhen P2 >= counter-1
		 set P3 = P2 + 1
		 loop
			exitwhen P3 >= counter
			set Combo = GetComboItem(Types[P1],Types[P2],Types[P3])
			if(Combo != 0) then
			   call RemoveItem(Items[P1])
			   call RemoveItem(Items[P2])
			   call RemoveItem(Items[P3])
			   call UnitAddItemById(Combo)
			   call CheckInventory(WhichHero)
			   return
			endif
			set P3 = P3 + 1
		 endloop
		 set P2 = P2 + 1
	  endloop
	  set P1 = P1 + 1
   endloop
   return
endfunction
 
//...inside a Init trigger come a whole lot of these lines:
call AddComboItem('I002','I00A','I0BC','Uber')
...
 

You then call CheckInventory whenever the inventory is edited (notice that this function may fuxxor up that trigger as it is removing items and stuff, but that's your problem)

~Cubasis
08-18-2004, 05:50 PM#8
GeneralStonewal
Here's a function I made recently.
Code:
function UnitHasNumOfItem takes unit whichUnit, integer num, integer whichType returns boolean
    local integer Index = 0
    loop
        if ( GetItemTypeId(UnitItemInSlot(whichUnit, Index)) == whichType ) then
            set num = num - 1
            if num == 0 then
                return true
            endif
        endif
        exitwhen Index == 5
        set Index = Index + 1
    endloop
    return false
endfunction