Item Stacking System Bug

Jonnycakes

New Member
Reaction score
6
EDIT: Solved-the condition line was wrong and created an infinitely recurring trigger call.

I am working on an item stacking trigger, and got it to work fine...until a hero's inventory is full. Now I am trying to work around that, and have made dummy 'tome/powerup' items for every charged item in my map. I added a function that replaces the dummy item with a real item (with appropriate number of charges) when a dummy is picked up. Whenever I pick up a dummy item though, all that happens is that the dummy item is removed. In fact, I set up some BJDebug messages that seem to contradict themselves. Here is my trigger, with some comments about the debug messages. This is driving me insane...what is happening?

Ah, one last note...the IDs of the stackable dummy items range from 'I00E' to 'I00Z' and the IDs of the real items range from 'I02E' to 'I02Z'. The ID for a flare (the item I am using to test the trigger) is 'I00L' ('I02L').

JASS:
scope itemstack initializer init


private function conditions takes nothing returns boolean
    return GetItemCharges(GetManipulatedItem())!=0
endfunction


private function main takes unit u, item picked, real x, real y returns nothing
    local integer i=0
    local integer id=GetItemTypeId(picked)
    local item temp
    local integer level=GetItemLevel(picked)
    local integer charges=GetItemCharges(picked)
    local integer chargestemp
    local boolean boo=UnitAddItem(u, picked)
    
    loop
        exitwhen i>5
        set temp=UnitItemInSlot(u, i)
        set chargestemp=GetItemCharges(temp)
        if GetItemTypeId(temp)==id and chargestemp<level and temp!=picked then
            if chargestemp+charges>level then
                call SetItemCharges(picked, chargestemp+charges-level)
                call SetItemCharges(temp, level)
                set charges=GetItemCharges(picked)
            else
                call SetItemCharges(temp, charges+chargestemp)
                call RemoveItem(picked)
                set charges=0
            endif
        endif
        set i=i+1
    endloop
    
    if charges>0 and not boo then
        call RemoveItem(picked)
        call CreateItem(id-512, x, y)
    endif        
    
    set u=null
    set picked=null
    set temp=null
    
endfunction

private function actions takes nothing returns nothing
    local unit u=GetTriggerUnit()
    local item pick=GetManipulatedItem()
    local integer id=GetItemTypeId(pick)
    local integer charges=GetItemCharges(pick)
    local real x=GetItemX(pick)
    local real y=GetItemY(pick)
    
    if not (id>='I00E' and id<='I00Z') then//this message always shows...
        call BJDebugMsg("Error: Invalid item type for stacking.")
    endif
    
    if not ('I00L'>='I00E') then//and these ones never show...
        call BJDebugMsg("less")
    elseif not ('I00L'<='I00Z') then
        call BJDebugMsg("more")
    endif
    
    if id=='I00L' then//even though this one also shows when you pick up a flare (item id 'I00L')...what???
        call BJDebugMsg("this is a flare")
    endif
    
    call RemoveItem(pick)
    set pick=CreateItem(id+512, x, y)//I set up my item ids so that the 'real' item id is 'I02<X>' when the dummy's is 'I00<X>'
    call SetItemCharges(pick, charges)
    call main(u, pick, x, y)
    set u=null
    set pick=null    

endfunction


//===========================================================================
private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    local integer i=0
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
        set i=i+1
        exitwhen i==8
    endloop
    call TriggerAddCondition(t, Condition(function conditions))
    call TriggerAddAction(t, function actions)
endfunction

endscope
 

cleeezzz

The Undead Ranger.
Reaction score
268
JASS:
if not (id>='I00E' and id<='I00Z') then//this message always shows...

remove "not", you WANT the item to be within those ranges, why would you have "not"? that basically means, i want an item thats less than I00E and greater than I00Z

JASS:
if not ('I00L'>='I00E') then//and these ones never show...
        call BJDebugMsg("less")
    elseif not ('I00L'<='I00Z') then
        call BJDebugMsg("more")
    endif


they arent supposed to, I00L is bigger than I00E, and I00Z is bigger than I00L
(basically another "not" mistake)

(im continuing to read the trigger, ill edit if i see anything else that will actually solve your problem.)

side note,
JASS:
        call CreateItem(id, x, y)

dont you want to create the rune back? it wouldn't work the next time you try to pick it up (full inventory)
 

Jonnycakes

New Member
Reaction score
6
JASS:
if not (id>='I00E' and id<='I00Z') then//this message always shows...

remove "not", you WANT the item to be within those ranges, why would you have "not"? that basically means, i want an item thats less than I00E and greater than I00Z

This is just a message that should only pop up when the trigger is running for an item it isn't supposed to...i.e. one without any charges on it (even though they should be weeded out by the conditions function). It shows even when the item id is 'I00L' though, as checked by this:

JASS:
    if id=='I00L' then//even though this one also shows when you pick up a flare (item id 'I00L')...what???
        call BJDebugMsg("this is a flare")
    endif


JASS:
if not ('I00L'>='I00E') then//and these ones never show...
        call BJDebugMsg("less")
    elseif not ('I00L'<='I00Z') then
        call BJDebugMsg("more")
    endif


they arent supposed to, I00L is bigger than I00E, and I00Z is bigger than I00L
(basically another "not" mistake)

Yeah, but one SHOULD show if this one shows:

JASS:
if not (id>='I00E' and id<='I00Z') then//this message always shows...


side note,
JASS:
        call CreateItem(id, x, y)

dont you want to create the rune back? it wouldn't work the next time you try to pick it up (full inventory)

Thank you-I didn't alter the item type ID. It should be the dummy item again (id-512). I will change this.
 

cleeezzz

The Undead Ranger.
Reaction score
268
This is just a message that should only pop up when the trigger is running for an item it isn't supposed to...i.e. one without any charges on it (even though they should be weeded out by the conditions function). It shows even when the item id is 'I00L' though, as checked by this:

yes, the range is wrong thats why its saying 'I00L' is being filtered out

JASS:
    if id=='I00L' then//even though this one also shows when you pick up a flare (item id 'I00L')...what???
        call BJDebugMsg("this is a flare")
    endif
yup, thats supposed to happen



Yeah, but one SHOULD show if this one shows:

JASS:
if not (id>='I00E' and id<='I00Z') then//this message always shows...
nope because both of them are wrong lol
okay, lets walk through this.

1. You pick up the item 'I00L'
2.
if not (id>='I00E' and id<='I00Z') then
well 'I00L' is not less than 'I00E' and its not greater than 'I00Z' therefore, it shows the message.
3.
if not ('I00L'>='I00E') then//and these ones never show...
call BJDebugMsg("less")
'I00L' is greater than 'I00E' not less than.
4.
elseif not ('I00L'<='I00Z') then
call BJDebugMsg("more")
'I00L' is less than 'I00Z' not more than

Correct way:
JASS:
scope itemstack initializer init


private function conditions takes nothing returns boolean
    return GetItemCharges(GetManipulatedItem())!=0
endfunction


private function main takes unit u, item picked, real x, real y returns nothing
    local integer i=0
    local integer id=GetItemTypeId(picked)
    local item temp
    local integer level=GetItemLevel(picked)
    local integer charges=GetItemCharges(picked)
    local integer chargestemp
    local boolean boo=UnitAddItem(u, picked)
    
    loop
        exitwhen i&gt;5
        set temp=UnitItemInSlot(u, i)
        set chargestemp=GetItemCharges(temp)
        if GetItemTypeId(temp)==id and chargestemp&lt;level and temp!=picked then
            if chargestemp+charges&gt;level then
                call SetItemCharges(picked, chargestemp+charges-level)
                call SetItemCharges(temp, level)
                set charges=GetItemCharges(picked)
            else
                call SetItemCharges(temp, charges+chargestemp)
                call RemoveItem(picked)
                set charges=0
            endif
        endif
        set i=i+1
    endloop
    
    if charges&gt;0 and not boo then
        call RemoveItem(picked)
        call CreateItem(id-512, x, y)
    endif        
    
    set u=null
    set picked=null
    set temp=null
    
endfunction

private function actions takes nothing returns nothing
    local unit u=GetTriggerUnit()
    local item pick=GetManipulatedItem()
    local integer id=GetItemTypeId(pick)
    local integer charges=GetItemCharges(pick)
    local real x=GetItemX(pick)
    local real y=GetItemY(pick)
    
    if (id&gt;=&#039;I00E&#039; and id&lt;=&#039;I00Z&#039;) then // THIS MESSAGE WILL NOT SHOW IF YOUR ITEM IS &#039;I00L&#039;
        call BJDebugMsg(&quot;Error: Invalid item type for stacking.&quot;)
    endif
    
    if (&#039;I00L&#039;&lt;=&#039;I00E&#039;) then // None will show, its not supposed to.
        call BJDebugMsg(&quot;less&quot;)
    elseif (&#039;I00L&#039;&gt;=&#039;I00Z&#039;) then
        call BJDebugMsg(&quot;more&quot;)
    endif
    
    if id==&#039;I00L&#039; then//even though this one also shows when you pick up a flare (item id &#039;I00L&#039;)...what???
        call BJDebugMsg(&quot;this is a flare&quot;)
    endif
    
    call RemoveItem(pick)
    set pick=CreateItem(id+512, x, y)//I set up my item ids so that the &#039;real&#039; item id is &#039;I02&lt;X&gt;&#039; when the dummy&#039;s is &#039;I00&lt;X&gt;&#039;
    call SetItemCharges(pick, charges)
    call main(u, pick, x, y)
    set u=null
    set pick=null    

endfunction


//===========================================================================
private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    local integer i=0
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
        set i=i+1
        exitwhen i==8
    endloop
    call TriggerAddCondition(t, Condition(function conditions))
    call TriggerAddAction(t, function actions)
endfunction

endscope


just try it, read the comments i changed

i think you're getting confused with the "not" in your "if" conditions

by the way, i suggest putting bj messages all around here

JASS:
    loop
        exitwhen i&gt;5
        set temp=UnitItemInSlot(u, i)
        set chargestemp=GetItemCharges(temp)
        if GetItemTypeId(temp)==id and chargestemp&lt;level and temp!=picked then
            if chargestemp+charges&gt;level then
                call SetItemCharges(picked, chargestemp+charges-level)
                call SetItemCharges(temp, level)
                set charges=GetItemCharges(picked)
            else
                call SetItemCharges(temp, charges+chargestemp)
                call RemoveItem(picked)
                set charges=0
            endif
        endif
        set i=i+1
    endloop
    
    if charges&gt;0 and not boo then
        call RemoveItem(picked)
        call CreateItem(id-512, x, y)
    endif

that will help you find the error
 

Jonnycakes

New Member
Reaction score
6
1. You pick up the item 'I00L'
2. well 'I00L' is not less than 'I00E' and its not greater than 'I00Z' therefore, it shows the message.

Okay.
[not (id>='I00E') and (id<='I00Z')] is equivalent to
[not (id>='I00E') or not (id>='I00E')]

(not id>='I00E') is equivalent to
(id<'I00E')

and (not id<='I00Z') is equivalent to
(id>'I00Z')

so that means that for the 'if then' condition to be satisfied...

(id<'I00E') or (id>'I00Z')

which is what I want.

Since (not 'I00L'<'I00E') and (not 'I00L'>'I00Z'), the message should not show if id='I00L'. Feel free to correct me if I'm wrong, but I feel very confident about this. Remember, with De Morgan's theorem you need to change the logical operator from an and to an or or vice versa :thup:



Also, I changed the condition of the trigger to this:

JASS:
private function conditions takes nothing returns boolean
    local integer id=GetItemTypeId(GetManipulatedItem())
    return id&gt;=&#039;I00E&#039; and id&lt;=&#039;I00Z&#039;
endfunction


and the trigger suddenly works perfectly. I have no idea why the condition would change so much about how the trigger operates (such as when picking up the EXACT SAME ITEM, the BJ messages suddenly work how they are supposed to... seriously absolutely nothing changed except the condition). I +repped you for pointing out the CreateItem bug at the end of my trigger-thank you for your help!
 

cleeezzz

The Undead Ranger.
Reaction score
268
well that condition was kinda what i was trying to say, but even though i was trying to convince you of that error, i didn't believe it would change anything because..
JASS:
  if not (id&gt;=&#039;I00E&#039; and id&lt;=&#039;I00Z&#039;) then//this message always shows...
        call BJDebugMsg(&quot;Error: Invalid item type for stacking.&quot;)
    endif
all it did was display a message, and nothing else. even though it was wrong, the trigger still should have worked.

(id<'I00E') or (id>'I00Z')

which is what I want.

your item was I00L, why would you want it to show those messages? that would be a BAD THING. if those messages showed, it would be end of the world. jk

Since (not 'I00L'<'I00E') and (not 'I00L'>'I00Z'), the message should not show if id='I00L'. Feel free to correct me if I'm wrong, but I feel very confident about this.
[not (id>='I00E') and (id<='I00Z')] is equivalent to
[not (id>='I00E') or not (id>='I00E')]

we are both correct, it was just that you missed out on that first condition line, everything else was fine.
this one ->
JASS:
if not (id&gt;=&#039;I00E&#039; and id&lt;=&#039;I00Z&#039;) then//this message always shows...


another side note, you might want to set the charges after recreating the item :d
JASS:
if charges&gt;0 and not boo then
        call RemoveItem(picked)
        call CreateItem(id-512, x, y)
    endif
 

Jonnycakes

New Member
Reaction score
6
Yes, I added a set charges function as well. Note that I didn't change the BJDebug message, I changed the conditions FUNCTION for the entire trigger. The message actually started functioning correctly (e.g. not showing), even though I was still picking up flares. I think I realize now why it wasn't working-the condition triggered whenever a unit picked up any charged item, so when the trigger came along to the UnitAddItem function, it triggered itself again.

I still don't see what you are trying to say about the BJDebug message...it is correct and functions how I want it to (now). Well, it is superfluous now with the new condition. Now on to figure out transferring items between units...
 

cleeezzz

The Undead Ranger.
Reaction score
268
I still don't see what you are trying to say about the BJDebug message...it is correct and functions how I want it to (now).

thats what i said lol, its correct except for the condition (previously, its correct now of course)

and what do you mean transfer items?
 

Jonnycakes

New Member
Reaction score
6
thats what i said lol, its correct except for the condition (previously, its correct now of course)

and what do you mean transfer items?

Well that is funny, because you made absolutely no mention of the condition function (in fact, the word "condition" doesn't show up in this thread until my post stating that I fixed the condition function) before I fixed it. Try to be clearer next time.

By transfer items, I mean transferring items directly between units. I am going to ask about it in a new thread if I can't find a way to do it by searching. This thread is done.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top