• 🏆 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!

[Trigger] Sometimes the item stacking trigger isn't working.

Status
Not open for further replies.
I have this trigger that stacks items who have more than 0 and less then 20 charges. The problem is that sometimes the items do not stack and instead the inventory gets a second item of this type. Sometimes the items do not stack at 1 stack, sometimes at 8, 16 or so. Can you help?

  • Acquire items
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • 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-type of (Item being manipulated))) Equal to True
              • (Item being manipulated) Not equal to (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated)))
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Item-type of (Item being manipulated)) Equal to Potion of Mana
                  • (Item-type of (Item being manipulated)) Equal to Potion of Healing
                  • (Item-type of (Item being manipulated)) Equal to Ankh of Reincarnation
            • Then - Actions
              • Item - Set charges remaining in (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated))) to ((Charges remaining in (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated)))) + 1)
              • Hero - Drop (Item being manipulated) from (Hero manipulating item)
              • Item - Remove (Item being manipulated)
              • Skip remaining actions
            • Else - Actions
          • For each (Integer A) from 1 to 120, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Item-type of (Item being manipulated)) Equal to Item[(Integer A)]
                • Then - Actions
                  • Trigger - Turn off Lose items <gen>
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • And - All (Conditions) are true
                        • Conditions
                          • (Charges remaining in (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated)))) Less than 20
                          • (Charges remaining in (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated)))) Greater than 0
                    • Then - Actions
                      • Item - Set charges remaining in (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated))) to ((Charges remaining in (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated)))) + 1)
                    • Else - Actions
                      • Player - Add 5 to (Triggering player) Current lumber
                  • Hero - Drop (Item being manipulated) from (Hero manipulating item)
                  • Item - Remove (Item being manipulated)
                  • Unit - Add Ability[(Integer A)] to (Triggering unit)
                  • Unit - Increase level of Ability[(Integer A)] for (Triggering unit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Item-type of (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated)))) Equal to Devour
                    • Then - Actions
                      • Unit - Add Devour Cargo (Curse / Devour Assistant) to (Triggering unit)
                      • Unit - Set level of Devour Cargo (Curse / Devour Assistant) for (Triggering unit) to (Charges remaining in (Item being manipulated))
                    • Else - Actions
                  • Trigger - Turn on Lose items <gen>
                  • Skip remaining actions
                • Else - Actions
        • Else - Actions
      • For each (Integer A) from 1 to 120, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Item-type of (Item being manipulated)) Equal to Item[(Integer A)]
            • Then - Actions
              • Unit - Add Ability[(Integer A)] to (Triggering unit)
              • Unit - Set level of Ability[(Integer A)] for (Triggering unit) to (Charges remaining in (Item being manipulated))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Item-type of (Item being manipulated)) Equal to Devour
                • Then - Actions
                  • Unit - Add Devour Cargo (Curse / Devour Assistant) to (Triggering unit)
                  • Unit - Set level of Devour Cargo (Curse / Devour Assistant) for (Triggering unit) to (Charges remaining in (Item being manipulated))
                • Else - Actions
            • Else - Actions
 
Level 12
Joined
Jan 2, 2016
Messages
973
  • ((Hero manipulating item) has an item of type (Item-type of (Item being manipulated))) Equal to True
  • (Item being manipulated) Not equal to (Item carried by (Hero manipulating item) of type (Item-type of (Item being manipulated)))
This part is a bit confusing for me... is the hero supposed to have an item of the same type, and at the same time NOT to have one? o_O
 
Level 18
Joined
Nov 21, 2012
Messages
835
I can give you my function from my campaign
modified to your needs - added stack limit
you can cut your code greatly and it works w/o problems
copy these 2 function

JASS:
function CountItemsById takes unit u, integer i returns integer
local integer x=0
local integer count=0
    loop
    exitwhen x > bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(u,x))==i then
            set count=count+1
        endif
    set x=x+1
    endloop
return count
endfunction
//-------------------------------------------------------------------------
function ItemsStack takes unit u, integer itemId, integer limit returns nothing
local integer charges = 0
local integer x = 0
local integer howMany = CountItemsById(u, itemId)
if howMany >1 then
    loop
        exitwhen x > bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(u, x)) == itemId then
            set charges = charges + GetItemCharges(UnitItemInSlot(u, x))
        endif
        set x=x+1
    endloop
    if charges < limit then
        set x=0
        loop
            exitwhen x > bj_MAX_INVENTORY
            if GetItemTypeId(UnitItemInSlot(u, x)) == itemId then
                call SetItemCharges(UnitItemInSlot(u, x), charges)
                if howMany > 1 then
                    call RemoveItem(UnitItemInSlot(u, x))
                endif
                set howMany = howMany - 1
            endif
            set x=x+1
        endloop    
    endif
endif
endfunction


using in gui :
  • pickup
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • Actions
      • Set TempUnit = (Hero manipulating item)
      • Set TempItemId = (Item-type of (Item being manipulated))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • TempItemId Equal to Crown of Kings +5
              • TempItemId Equal to Ring of Protection +5
              • TempItemId Equal to Claws of Attack +15
        • Then - Actions
          • Custom script: call ItemsStack(udg_TempUnit, udg_TempItemId, 20)
        • Else - Actions
call ItemsStack(udg_TempUnit, udg_TempItemId, 20)
20 is your limit, you can use different of course

zibi
 
Level 18
Joined
Nov 21, 2012
Messages
835

JASS:
function CountItemsById takes unit u, integer i returns integer
local integer x=0
local integer count=0
    loop
    exitwhen x > bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(u,x))==i then
            set count=count+1
        endif
    set x=x+1
    endloop
return count
endfunction
//-------------------------------------------------------------------------
function ItemsStack takes unit u, integer itemId, integer limit, integer addLumber returns nothing
local integer charges = 0
local integer x = 0
local item it
local integer howMany = CountItemsById(u, itemId)
if howMany >1 then
    loop
        exitwhen x > bj_MAX_INVENTORY
        set it = UnitItemInSlot(u, x)
        if GetItemTypeId(it) == itemId then
            set charges = charges + GetItemCharges(it)
        endif
        set it=null
        set x=x+1
    endloop
    set x=0
    loop
        exitwhen x > bj_MAX_INVENTORY
        set it = UnitItemInSlot(u, x)
        if GetItemTypeId(it) == itemId then
            call SetItemCharges(it, charges)
            if howMany > 1 then
                call RemoveItem(it)
            endif
            set howMany = howMany - 1
        endif
        set it=null
        set x=x+1
    endloop    
    set x = 0  // lumber:
    loop
        exitwhen x > bj_MAX_INVENTORY
        set it = UnitItemInSlot(u, x)
        if GetItemTypeId(it) == itemId and GetItemCharges(it) > limit then
            call RemoveItem(it)
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\ResourceItems\\ResourceEffectTarget.mdl", u, "origin"))
            call AdjustPlayerStateBJ( addLumber, GetOwningPlayer(u), PLAYER_STATE_RESOURCE_LUMBER )
        endif
        set it=null
        set x=x+1
    endloop    
endif
endfunction


  • pickup
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • Actions
      • Set TempUnit = (Hero manipulating item)
      • Set TempItemId = (Item-type of (Item being manipulated))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • TempItemId Equal to Crown of Kings +5
              • TempItemId Equal to Ring of Protection +5
              • TempItemId Equal to Claws of Attack +15
        • Then - Actions
          • Custom script: call ItemsStack(udg_TempUnit, udg_TempItemId, 20, 5)
        • Else - Actions
ItemsStack(udg_TempUnit, udg_TempItemId, 20, 5)
unit can have max 20 charges, if more then 20 detectred item is removed and 5 lumber is added. I added special effect you can also add play sound on unit: 'bundle of lumber' when lumber is added ;]
zibi
 
Thank you very much. But there's one problem: The items stack only on even number - if I buy the item once and then buy it second time it becomes 2 stacks. Then when I buy it third time it becomes 2 stacks and one item with one stack. Then when I buy it fourth time it all combines to 4 stacks and so on... = only on even numbers...
It's like the screenshot I posted on your wall.
 
Hmm, it might be from some trigger I have, ok. When I tested the map I noticed that your code removed the item with its 20 stacks. Sorry, if you understood me wrong, but I don't want to remove the original item, but the item that is redundant - the item you bought when you had already 20 stacks.
1 stack of every item costs 5 lumber, that's why I asked to have refund on it.

EDIT: Also, can you put these triggers and convert them into code? Since this function is fully code trigggers seem to mess with it and is better to be only code:
[hidden="triggers]
  • TRIGGERS
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Item-type of (Item carried by UNIT of type TempItemType)) Equal to Devour
        • Then - Actions
          • Unit - Add Devour Cargo (Curse / Devour Assistant) to UNIT
          • Unit - Set level of Devour Cargo (Curse / Devour Assistant) for UNIT to STACKS
        • Else - Actions
  • LOOP FOR INTEGER A (1-120) >
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • ITEM MANIPULATED Equal to Item[A]
      • Then - Actions
        • Unit - Add Ability[A] to UNIT
        • Unit - Set level of Ability[Integer A] for UNIT to STACKS
      • Else - Actions
[/hidden]
 
Last edited:
Level 18
Joined
Nov 21, 2012
Messages
835
Hmm, it might be from some trigger I have, ok. When I tested the map I noticed that your code removed the item with its 20 stacks. Sorry, if you understood me wrong, but I don't want to remove the original item, but the item that is redundant - the item you bought when you had already 20 stacks.
1 stack of every item costs 5 lumber, that's why I asked to have refund on it.
ok stan, thats not a problem when i know exactly what you need ;]

Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Item-type of (Item carried by UNIT of type TempItemType)) Equal to Devour
Then - Actions
Unit - Add Devour Cargo (Curse / Devour Assistant) to UNIT
Unit - Set level of Devour Cargo (Curse / Devour Assistant) for UNIT to STACKS
is this item 'devour' perishable?
can it be more then 1 charge (is stacking)? do you want to track ability level with charges on devour item?
the same questions to items in 120 loop
 
Devour ability and devour Cargo ability come together, otherwise devour won't work.
Look at my Ancient Hero Arena. The items are named like the abilities. When you buy item you buy also the ability. When you stack the item you upgrade the ability. DEvour is item and ability. Devour Cargo is only ability(that helps devour store unit).
Example:
Holy Light(item) x10 = Holy Light(level 10)
DEvour:
DEvour(item) x 10 = Devour(Level 10) + Devour Cargo(Level 10)

The items are not perishable. The item itself does not contain the ability in object editor because I want the ability to be on the hero not on the item. That's why I put the ability on the hero when he buys the item. The items are empty non-clickable, dropable.
 
Level 18
Joined
Nov 21, 2012
Messages
835
stan, do you want to track ability level with charges on coresponding item?
example:
hero drops Holy Light(item) x10 item on the ground
should he lose Holy Light(level 10) ability or not
if not, hero can give other unit / player this item to gain Holy light for free..
but, if it is what you want then ok, it will mean for me that gained ability level from stacking item is permanent. I need this info to add code for ability.
 
I already have trigger when losing item
  • Lose items
    • Events
      • Unit - A unit Loses an item
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 120, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Item-type of (Item being manipulated)) Equal to Item[(Integer A)]
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Item-type of (Item being manipulated)) Equal to Devour
                • Then - Actions
                  • Unit - Remove Devour Cargo (Curse / Devour Assistant) from (Triggering unit)
                • Else - Actions
              • Unit - Remove Ability[(Integer A)] from (Triggering unit)
            • Else - Actions
Hmm, about sharing item with another hero... I think buying item and sharing item is the same thing.
 
Last edited:
Level 18
Joined
Nov 21, 2012
Messages
835
JASS:
function CountItemsById takes unit u, integer i returns integer
local integer x=0
local integer count=0
    loop
    exitwhen x > bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(u,x))==i then
            set count=count+1
        endif
    set x=x+1
    endloop
return count
endfunction
//-------------------------------------------------------------------------
function ItemsStack takes unit u, integer itemId, integer limit, integer addLumber returns nothing
local integer charges = 0
local integer x = 0
local item it
local integer howMany = CountItemsById(u, itemId)
if howMany >1 then
    loop
        exitwhen x > bj_MAX_INVENTORY
        set it = UnitItemInSlot(u, x)
        if GetItemTypeId(it) == itemId then
            set charges = charges + GetItemCharges(it)
        endif
        set it=null
        set x=x+1
    endloop
    set x=0
    loop
        exitwhen x > bj_MAX_INVENTORY
        set it = UnitItemInSlot(u, x)
        if GetItemTypeId(it) == itemId then
            call SetItemCharges(it, charges)
            if howMany > 1 then
                call RemoveItem(it)
            endif
            set howMany = howMany - 1
        endif
        set it=null
        set x=x+1
    endloop       
    set x = 0  // lumber refund:
    loop
        exitwhen x > bj_MAX_INVENTORY
        set it = UnitItemInSlot(u, x)
        if GetItemTypeId(it) == itemId and GetItemCharges(it) > limit then
            call AdjustPlayerStateBJ( addLumber*(GetItemCharges(it)-limit), GetOwningPlayer(u), PLAYER_STATE_RESOURCE_LUMBER )
            call SetItemCharges(it, limit)
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\ResourceItems\\ResourceEffectTarget.mdl", u, "origin"))            
        endif
        set it=null
        set x=x+1
    endloop    
endif
endfunction
//--------------------------------------
function SetAbilityFromItem takes unit u, integer itemId returns nothing
local integer a=1
local integer x=0
local integer charges=0
    loop
        exitwhen a>120
        if itemId==udg_Item[a] then
            set x=0
            loop //set charges:
                exitwhen x > bj_MAX_INVENTORY
                if GetItemTypeId(UnitItemInSlot(u, x)) == itemId then
                    set charges = GetItemCharges(UnitItemInSlot(u, x))
                    exitwhen true
                endif
                set x=x+1
            endloop
            if GetUnitAbilityLevel(u, udg_Ability[a]) < charges then 
                call UnitAddAbility(u, udg_Ability[a])
                call SetUnitAbilityLevel(u, udg_Ability[a], charges)
                call DisplayTextToPlayer(GetOwningPlayer(u), 0.00, 0.00, "Ability " + GetObjectName(udg_Ability[a]) + " level set to: " + I2S(charges))
            endif
        endif        
        set a=a+1
    endloop            
endfunction
//-------------------------------
function SetDevourAbilityFromItem takes unit u, integer itemId returns nothing
local integer x=0
local integer charges=0
local integer itemDevour = 'afac'   //YOUR ITEM DEVOUR
local integer abilityDevour = 'ACdv' //YOUR ABILITY DEVOUR
    loop
        exitwhen x > bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(u, x)) == itemDevour then 
            set charges = GetItemCharges(UnitItemInSlot(u, x))
            exitwhen true
        endif
        set x=x+1
    endloop
    if GetUnitAbilityLevel(u, abilityDevour) < charges then 
        call UnitAddAbility(u, abilityDevour)
        call SetUnitAbilityLevel(u, abilityDevour, charges)
        call DisplayTextToPlayer(GetOwningPlayer(u), 0.00, 0.00, "Ability " + GetObjectName(abilityDevour) + " level set to: " + I2S(charges))
    endif
endfunction

  • pickup
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • Actions
      • Set TempUnit = (Hero manipulating item)
      • Set TempItemId = (Item-type of (Item being manipulated))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • TempItemId Equal to Crown of Kings +5
              • TempItemId Equal to Ring of Protection +5
              • TempItemId Equal to Claws of Attack +15
              • TempItemId Equal to Scroll of Healing
              • TempItemId Equal to Dust of Appearance
              • TempItemId Equal to Alleria's Flute of Accuracy
        • Then - Actions
          • Custom script: call ItemsStack(udg_TempUnit, udg_TempItemId, 20, 5)
          • -------- your 120 registered item-types: --------
          • Custom script: call SetAbilityFromItem(udg_TempUnit, udg_TempItemId)
          • -------- your devour ability: --------
          • -------- SetDevourAbilityFromItem function is really unnecessary if you only add --------
          • -------- your item and ability 'devour' to array, like 120 other items/abilities --------
          • Custom script: call SetDevourAbilityFromItem(udg_TempUnit, udg_TempItemId)
        • Else - Actions
zibi
 
Status
Not open for further replies.
Top