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

Item Stacking - Submission

Status
Not open for further replies.
JASS:
//filter Out PowerUps
function GainItemCon takes nothing returns boolean
   return not IsItemPowerup(GetManipulatedItem ())
endfunction

function GainItem takes nothing returns nothing
   local item it = GetManipulatedItem ()
   local unit picker =  GetManipulatingUnit ()
   local item slot
   local integer loopA = 0
   local integer oldCharges
   local integer newCharges = GetItemCharges(it)
   //Has Charges
   if GetItemCharges (GetManipulatedItem ()) != 0 then
       loop
           exitwhen loopA > 5
           set slot = UnitItemInSlot (picker, loopA)
           //Same ItemType but not same Item 
           if (GetItemTypeId(it) == GetItemTypeId(slot) and slot != it) then
               set oldCharges = GetItemCharges(slot)
               if oldCharges + newCharges <= 3 then
                   call SetItemCharges(slot, newCharges +oldCharges)
                   call RemoveItem(it)
                   set it = null
                   exitwhen (true)
               endif
           endif 
           set loopA = loopA + 1
       endloop
       if it != null then
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it) + "[" + I2S(newCharges ) +"]" )
       else
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
       endif 
   else
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it)  )
   endif 
   set it = null
   set picker = null
   set slot = null
endfunction

//Works only if an Item is moved; Filters Items without Charges
function MoveItemCon takes nothing returns boolean
   return ( GetIssuedOrderId() >= 852002 and  GetIssuedOrderId() <= 852007  and GetItemCharges(GetOrderTargetItem()) != 0)
endfunction

function MoveItem takes nothing returns nothing
   local item movingItem = GetOrderTargetItem()
   local item swapedItem
   local integer oldSlot
   local integer newSlot = GetIssuedOrderId() - 852002
   local integer loopA = 0
   //Find OldItem Slot
   loop
       exitwhen loopA > 5
       if UnitItemInSlot (GetTriggerUnit(), loopA) == movingItem then
           set oldSlot = loopA 
           exitwhen (true)
       endif 
       set loopA = loopA + 1
   endloop
   set swapedItem = UnitItemInSlot (GetTriggerUnit(), newSlot)
   //Same ItemType & was Moved at all & Combined Charges below equal 3 ?
   if ( GetItemTypeId (swapedItem) == GetItemTypeId(movingItem) and newSlot != oldSlot and GetItemCharges(movingItem) + GetItemCharges(swapedItem) <= 3) then
       call SetItemCharges(movingItem, GetItemCharges(movingItem) + GetItemCharges(swapedItem))
       call RemoveItem(swapedItem)
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "[Combined into " + I2S(GetItemCharges(movingItem)) +"]" )
   endif
   set movingItem = null
   set swapedItem = null
endfunction

//===========================================================================
function InitTrig_ItemStacking takes nothing returns nothing
   //0 = Pick;
   //1 = Move/Split

   set udg_ItemSystem[0] = CreateTrigger()
   set udg_ItemSystem[1] = CreateTrigger()
 
   call TriggerAddAction( udg_ItemSystem[0], function GainItem )
   call TriggerAddCondition( udg_ItemSystem[0],  Condition (function GainItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[0], EVENT_PLAYER_UNIT_PICKUP_ITEM )
 
   call TriggerAddAction( udg_ItemSystem[1], function MoveItem )
   call TriggerAddCondition( udg_ItemSystem[1],  Condition (function MoveItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[1], EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
endfunction
Edit: Added a Condition for GainItem, Filtering out Powerups
Edit 2: Saves the Triggers in Global Triggers udg_ItemSystem[0]/udg_ItemSystem[1]

JASS:
//filter Out PowerUps
function GainItemCon takes nothing returns boolean
   return not IsItemPowerup(GetManipulatedItem ())
endfunction

function GainItem takes nothing returns nothing
   local item it = GetManipulatedItem ()
   local unit picker =  GetManipulatingUnit ()
   local item slot
   local integer loopA = 0
   local integer oldCharges
   local integer newCharges = GetItemCharges(it)
   //Has Charges
   if GetItemCharges (GetManipulatedItem ()) != 0 then
       loop
           exitwhen loopA > 5
           set slot = UnitItemInSlot (picker, loopA)
           //Same ItemType but not same Item  
           if (GetItemTypeId(it) == GetItemTypeId(slot) and slot != it) then
               set oldCharges = GetItemCharges(slot)
               if oldCharges + newCharges <= 3 then
                   call SetItemCharges(slot, newCharges +oldCharges)
                   call RemoveItem(it)
                   set it = null
                   exitwhen (true)
               endif
           endif  
           set loopA = loopA + 1
       endloop
       if it != null then
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it) + "[" + I2S(newCharges ) +"]" )
       else
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
       endif  
   else
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it)  )
   endif  
   set it = null
   set picker = null
   set slot = null
endfunction

//Works only if an Item is moved; Filters Items without Charges
function MoveItemCon takes nothing returns boolean
   return ( GetIssuedOrderId() >= 852002 and  GetIssuedOrderId() <= 852007  and GetItemCharges(GetOrderTargetItem()) != 0)
endfunction

function MoveItem takes nothing returns nothing
   local item movingItem = GetOrderTargetItem()
   local item swapedItem
   local integer oldSlot
   local integer newSlot = GetIssuedOrderId() - 852002
   local integer loopA = 0
   local unit hero = GetTriggerUnit()
   //Find OldItem Slot
   loop
       exitwhen loopA > 5
       if UnitItemInSlot (hero, loopA) == movingItem then
           set oldSlot = loopA  
           exitwhen (true)
       endif  
       set loopA = loopA + 1
   endloop
   set swapedItem = UnitItemInSlot (hero, newSlot)
   //Same ItemType & was Moved at all & Combined Charges below equal 3 ?
   if ( GetItemTypeId (swapedItem) == GetItemTypeId(movingItem) and newSlot != oldSlot and GetItemCharges(movingItem) + GetItemCharges(swapedItem) <= 3) then
       call SetItemCharges(movingItem, GetItemCharges(movingItem) + GetItemCharges(swapedItem))
       call RemoveItem(swapedItem)
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "[Combined into " + I2S(GetItemCharges(movingItem)) +"]" )
   else
       //Split?
       if newSlot == oldSlot and GetItemCharges(movingItem) > 1 then
       call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
       call UnitRemoveItem(hero, movingItem)
       call UnitAddItemByIdSwapped( GetItemTypeId(movingItem), hero )
       //Regain Old Item without Checking for Stacking
       call DisableTrigger(udg_ItemSystem[0])
       call UnitAddItem(hero, movingItem)
       call EnableTrigger(udg_ItemSystem[0])
       endif
   endif
   set movingItem = null
   set swapedItem = null
endfunction

//===========================================================================
function InitTrig_ItemStacking takes nothing returns nothing
   //0 = Pick;
   //1 = Move/Split

   set udg_ItemSystem[0] = CreateTrigger()
   set udg_ItemSystem[1] = CreateTrigger()
  
   call TriggerAddAction( udg_ItemSystem[0], function GainItem )
   call TriggerAddCondition( udg_ItemSystem[0],  Condition (function GainItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[0], EVENT_PLAYER_UNIT_PICKUP_ITEM )
  
   call TriggerAddAction( udg_ItemSystem[1], function MoveItem )
   call TriggerAddCondition( udg_ItemSystem[1],  Condition (function MoveItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[1], EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
endfunction
 

Attachments

  • Jass Class 6 - Item Splitting.w3x
    19.8 KB · Views: 49
  • Jass Class 5 - Item Stacking.w3x
    18.9 KB · Views: 75
Last edited:
Please always indent your code, for example:
JASS:
if true then
do something()
do something()
endif

->
if true then
    do something()
    do something()
endif

Stacking:

When items try to stack with 2 and 2 charges, then one item should result in 3 charges (targeted item), and the one which is being moved/pickedup result in 1. Max is "3", but we should try to reach it always.

Splitting:

Creating one item with default charges is not a perfect solution, as it might be also "3" or so (I guess), and we hardcoded remove always "1" from charges. And I guess if you have a full item slot, one item with 3 charges, and try to split, then you will endup in dropping 2 charges, and remaining one charge in inventory. I belive it should/could be solved without dropping the original item at all. :)
 
Update: The maps in first post are Updated, too.
JASS:
//filter Out PowerUps
function GainItemCon takes nothing returns boolean
   return not IsItemPowerup(GetManipulatedItem ())
endfunction

function GainItem takes nothing returns nothing
   local item it = GetManipulatedItem ()
   local unit picker =  GetManipulatingUnit ()
   local item slot
   local integer loopA = 0
   local integer oldCharges
   local integer newCharges = GetItemCharges(it)
   //Has Charges
   if GetItemCharges (GetManipulatedItem ()) != 0 then
       loop
           exitwhen loopA > 5
           set slot = UnitItemInSlot (picker, loopA)
           set oldCharges = GetItemCharges(slot)
           //Same ItemType / not same Item / not Full ?
           if (GetItemTypeId(it) == GetItemTypeId(slot) and slot != it and oldCharges != 3) then
               //Combined Charges in the Limit?
               if oldCharges + newCharges <= 3 then
                   call SetItemCharges(slot, newCharges +oldCharges)
                   call RemoveItem(it)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
                   set it = null
               else
                   //Not in the Limit fill Slotitem
                   set newCharges = newCharges - ( 3 - oldCharges)
                   call SetItemCharges(it, newCharges )
                   call SetItemCharges(slot, 3)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
               endif
               exitwhen (true)
           endif
           set loopA = loopA + 1
       endloop
       if it != null then
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it) + "[" + I2S(newCharges ) +"]" )
       endif
   else
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it)  )
   endif
   set it = null
   set picker = null
   set slot = null
endfunction

//Works only if an Item is moved; Filters Items without Charges
function MoveItemCon takes nothing returns boolean
   return ( GetIssuedOrderId() >= 852002 and  GetIssuedOrderId() <= 852007  and GetItemCharges(GetOrderTargetItem()) != 0)
endfunction

function MoveItem takes nothing returns nothing
   local item movingItem = GetOrderTargetItem()
   local item swapedItem
   local integer oldSlot
   local integer newSlot = GetIssuedOrderId() - 852002
   local integer loopA = 0
   local integer newCharges
   local unit hero = GetTriggerUnit()
   //Find OldItem Slot
   loop
       exitwhen loopA > 5
       if UnitItemInSlot (hero, loopA) == movingItem then
           set oldSlot = loopA
           exitwhen (true)
       endif
       set loopA = loopA + 1
   endloop
   set swapedItem = UnitItemInSlot (hero, newSlot)
   //Same ItemType & was Moved at all & Charges of movingItem below 3 ?
   if ( GetItemTypeId (swapedItem) == GetItemTypeId(movingItem) and newSlot != oldSlot and GetItemCharges(movingItem) < 3 and GetItemCharges(swapedItem) != 3) then
       //Will Moving Stacking Result into 1 Item?
       if GetItemCharges(movingItem) + GetItemCharges(swapedItem)  <= 3 then
           call SetItemCharges(movingItem, GetItemCharges(movingItem) + GetItemCharges(swapedItem))
           call RemoveItem(swapedItem)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"]" )
       else
           set newCharges = 3 - ( GetItemCharges(swapedItem) )
           call SetItemCharges(movingItem, 3)
           call SetItemCharges(swapedItem, newCharges)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"] & ["+I2S(newCharges)+"]" )
       endif
   endif
   set movingItem = null
   set swapedItem = null
   set hero = null
endfunction

//===========================================================================
function InitTrig_ItemStacking takes nothing returns nothing
   //0 = Pick;
   //1 = Move/Split

   set udg_ItemSystem[0] = CreateTrigger()
   set udg_ItemSystem[1] = CreateTrigger()
 
   call TriggerAddAction( udg_ItemSystem[0], function GainItem )
   call TriggerAddCondition( udg_ItemSystem[0],  Condition (function GainItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[0], EVENT_PLAYER_UNIT_PICKUP_ITEM )
 
   call TriggerAddAction( udg_ItemSystem[1], function MoveItem )
   call TriggerAddCondition( udg_ItemSystem[1],  Condition (function MoveItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[1], EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
endfunction

JASS:
//filter Out PowerUps
function GainItemCon takes nothing returns boolean
   return not IsItemPowerup(GetManipulatedItem ())
endfunction

function GainItem takes nothing returns nothing
   local item it = GetManipulatedItem ()
   local unit picker =  GetManipulatingUnit ()
   local item slot
   local integer loopA = 0
   local integer oldCharges
   local integer newCharges = GetItemCharges(it)
   //Has Charges
   if GetItemCharges (GetManipulatedItem ()) != 0 then
       loop
           exitwhen loopA > 5
           set slot = UnitItemInSlot (picker, loopA)
           set oldCharges = GetItemCharges(slot)
           //Same ItemType / not same Item   / not full ?
           if (GetItemTypeId(it) == GetItemTypeId(slot) and slot != it and oldCharges != 3) then
               //Combined Charges in the Limit?
               if oldCharges + newCharges <= 3 then
                   call SetItemCharges(slot, newCharges +oldCharges)
                   call RemoveItem(it)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
                   set it = null
               else
                   //Not in the Limit fill Slotitem
                   set newCharges = newCharges - ( 3 - oldCharges)
                   call SetItemCharges(it, newCharges )
                   call SetItemCharges(slot, 3)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
               endif
               exitwhen (true)
           endif
           set loopA = loopA + 1
       endloop
       if it != null then
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it) + "[" + I2S(newCharges ) +"]" )
       endif
   else
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it)  )
   endif
   set it = null
   set picker = null
   set slot = null
endfunction

//Works only if an Item is moved; Filters Items without Charges
function MoveItemCon takes nothing returns boolean
   return ( GetIssuedOrderId() >= 852002 and  GetIssuedOrderId() <= 852007  and GetItemCharges(GetOrderTargetItem()) != 0)
endfunction

function MoveItem takes nothing returns nothing
   local item movingItem = GetOrderTargetItem()
   local item swapedItem
   local item slotItem
   local unit hero = GetTriggerUnit()
   local integer oldSlot
   local integer newSlot = GetIssuedOrderId() - 852002
   local integer loopA = 0
   local integer newCharges
   //Find OldItem Slot
   loop
       exitwhen loopA > 5
       if UnitItemInSlot (hero, loopA) == movingItem then
           set oldSlot = loopA
           exitwhen (true)
       endif
       set loopA = loopA + 1
   endloop
   set swapedItem = UnitItemInSlot (hero, newSlot)
   //Same ItemType & was Moved at all & Charges of movingItem below 3 ?
   if ( GetItemTypeId (swapedItem) == GetItemTypeId(movingItem) and newSlot != oldSlot and GetItemCharges(movingItem) != 3 and GetItemCharges(swapedItem) != 3) then
       //Will Moving Stacking Result into 1 Item?
       if GetItemCharges(movingItem) + GetItemCharges(swapedItem)  <= 3 then
           call SetItemCharges(movingItem, GetItemCharges(movingItem) + GetItemCharges(swapedItem))
           call RemoveItem(swapedItem)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"]" )
       else
           set newCharges = 3 - ( GetItemCharges(swapedItem) )
           call SetItemCharges(movingItem, 3)
           call SetItemCharges(swapedItem, newCharges)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"] & ["+I2S(newCharges)+"]" )
       endif
   else
       //Split?
       if newSlot == oldSlot and GetItemCharges(movingItem) > 1 then
           set loopA = 0
           loop
               exitwhen loopA > 5
               set slotItem = UnitItemInSlot (hero, loopA)
               // Same Type / not max charges / not One ?
               if ( GetItemTypeId(slotItem) == GetItemTypeId(movingItem) and GetItemCharges(slotItem) != 3 and slotItem != movingItem ) then
                   //Move 1 Charge from Splitting item to other one
                   call SetItemCharges(slotItem, GetItemCharges(slotItem) + 1)
                   call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
                   //Clean and End
                   set movingItem = null
                   set swapedItem = null
                   set slotItem = null
                   set hero = null
                   return
               endif
               set loopA = loopA + 1
           endloop
           //If Hero has no Item which could take the charge -> Create a new with 1 Charge give it to hero and after that reduce splitting item Charges
           set swapedItem = CreateItem(GetItemTypeId(movingItem), GetUnitX(hero), GetUnitY(hero))
           call SetItemCharges(swapedItem, 1)
           call UnitAddItem(hero, swapedItem)
           call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
       endif
   endif
   set movingItem = null
   set swapedItem = null
   set slotItem = null
   set hero = null
endfunction

//===========================================================================
function InitTrig_ItemSystem takes nothing returns nothing
   //0 = Pick;
   //1 = Move/Split

   set udg_ItemSystem[0] = CreateTrigger()
   set udg_ItemSystem[1] = CreateTrigger()
 
   call TriggerAddAction( udg_ItemSystem[0], function GainItem )
   call TriggerAddCondition( udg_ItemSystem[0],  Condition (function GainItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[0], EVENT_PLAYER_UNIT_PICKUP_ITEM )
 
   call TriggerAddAction( udg_ItemSystem[1], function MoveItem )
   call TriggerAddCondition( udg_ItemSystem[1],  Condition (function MoveItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[1], EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
endfunction
 
In the stacking logics, why this:

GetItemCharges(slotItem) != 3
-- shouldn't it be
GetItemCharges(slotItem) <= 3

I believe rest looks pretty fine, I will test it today evening.

By the way, just a thought; if you make the "3" into a variable then it's very easy always to change this stack limit, but hardcoding always "3" in the code works here, too, of course.
 
Replaced GetItemCharges() != 3 with GetItemCharges() < 3
insert an variable udg_ItemSystem_MaxCharges.

!= 3 is fine as long no item with more than 3 charges exist.
JASS:
//filter Out PowerUps
function GainItemCon takes nothing returns boolean
   return not IsItemPowerup(GetManipulatedItem ())
endfunction

function GainItem takes nothing returns nothing
   local item it = GetManipulatedItem ()
   local unit picker =  GetManipulatingUnit ()
   local item slot
   local integer loopA = 0
   local integer oldCharges
   local integer newCharges = GetItemCharges(it)
   //Has Charges ?
   if GetItemCharges (GetManipulatedItem ()) != 0 then
       loop
           exitwhen loopA > 5
           set slot = UnitItemInSlot (picker, loopA)
           set oldCharges = GetItemCharges(slot)
           //Same ItemType / not same Item   / not full ?
           if (GetItemTypeId(it) == GetItemTypeId(slot) and slot != it and oldCharges < udg_ItemSystem_MaxCharges) then
               //Combined Charges in the Limit?
               if oldCharges + newCharges <= udg_ItemSystem_MaxCharges then
                   call SetItemCharges(slot, newCharges +oldCharges)
                   call RemoveItem(it)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
                   set it = null
               else
                   //Not in the Limit fill Slotitem
                   set newCharges = newCharges - ( udg_ItemSystem_MaxCharges - oldCharges)
                   call SetItemCharges(it, newCharges )
                   call SetItemCharges(slot, udg_ItemSystem_MaxCharges)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
               endif
               exitwhen (true)
           endif 
           set loopA = loopA + 1
       endloop
       if it != null then
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it) + "[" + I2S(newCharges ) +"]" )
       endif 
   else
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it)  )
   endif 
   set it = null
   set picker = null
   set slot = null
endfunction

//Works only if an Item is moved; Filters Items without Charges
function MoveItemCon takes nothing returns boolean
   return ( GetIssuedOrderId() >= 852002 and  GetIssuedOrderId() <= 852007  and GetItemCharges(GetOrderTargetItem()) != 0)
endfunction

function MoveItem takes nothing returns nothing
   local item movingItem = GetOrderTargetItem()
   local item swapedItem
   local item slotItem
   local unit hero = GetTriggerUnit()
   local integer oldSlot
   local integer newSlot = GetIssuedOrderId() - 852002
   local integer loopA = 0
   local integer newCharges
   //Find OldItem Slot
   loop
       exitwhen loopA > 5
       if UnitItemInSlot (hero, loopA) == movingItem then
           set oldSlot = loopA 
           exitwhen (true)
       endif 
       set loopA = loopA + 1
   endloop
   set swapedItem = UnitItemInSlot (hero, newSlot)
   //Same ItemType & was Moved at all & Charges of movingItem below udg_ItemSystem_MaxCharges ?
   if ( GetItemTypeId (swapedItem) == GetItemTypeId(movingItem) and newSlot != oldSlot and GetItemCharges(movingItem) < udg_ItemSystem_MaxCharges and GetItemCharges(swapedItem) < udg_ItemSystem_MaxCharges) then
       //Will Moving Stacking Result into 1 Item?
       if GetItemCharges(movingItem) + GetItemCharges(swapedItem)  <= udg_ItemSystem_MaxCharges then
           call SetItemCharges(movingItem, GetItemCharges(movingItem) + GetItemCharges(swapedItem))
           call RemoveItem(swapedItem)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"]" )
       else
           set newCharges = udg_ItemSystem_MaxCharges - ( GetItemCharges(swapedItem) )
           call SetItemCharges(movingItem, udg_ItemSystem_MaxCharges)
           call SetItemCharges(swapedItem, newCharges)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"] & ["+I2S(newCharges)+"]" )
       endif
   else
       //Split?
       if newSlot == oldSlot and GetItemCharges(movingItem) != 1 then
           set loopA = 0
           loop
               exitwhen loopA > 5
               set slotItem = UnitItemInSlot (hero, loopA)
               // Same Type / not max charges / not One ?
               if ( GetItemTypeId(slotItem) == GetItemTypeId(movingItem) and GetItemCharges(slotItem) < udg_ItemSystem_MaxCharges and slotItem != movingItem ) then
                   //Move 1 Charge from Splitting item to other one
                   call SetItemCharges(slotItem, GetItemCharges(slotItem) + 1)
                   call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
                   //Clean and End
                   set movingItem = null
                   set swapedItem = null
                   set slotItem = null
                   set hero = null
                   return
               endif
               set loopA = loopA + 1
           endloop 
           //If Hero has no Item which could take the charge -> Create a new with 1 Charge give it to hero and after that reduce splitting item Charges
           set swapedItem = CreateItem(GetItemTypeId(movingItem), GetUnitX(hero), GetUnitY(hero))
           call SetItemCharges(swapedItem, 1)
           call UnitAddItem(hero, swapedItem)
           call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
       endif
   endif
   set movingItem = null
   set swapedItem = null
   set slotItem = null
   set hero = null
endfunction

//===========================================================================
function InitTrig_ItemSystem takes nothing returns nothing
   //0 = Pick;
   //1 = Move/Split
   set udg_ItemSystem_MaxCharges = 3
   set udg_ItemSystem[0] = CreateTrigger()
   set udg_ItemSystem[1] = CreateTrigger()
 
   call TriggerAddAction( udg_ItemSystem[0], function GainItem )
   call TriggerAddCondition( udg_ItemSystem[0],  Condition (function GainItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[0], EVENT_PLAYER_UNIT_PICKUP_ITEM )
 
   call TriggerAddAction( udg_ItemSystem[1], function MoveItem )
   call TriggerAddCondition( udg_ItemSystem[1],  Condition (function MoveItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[1], EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
endfunction
 

Attachments

  • Jass Class 6 - Item Splitting.w3x
    19.8 KB · Views: 57
Last edited:
Fixed another bug with spliting items here its solved:
Not full Charged Items were not splitable.​

Some Question: if a hero Picks an item with 2 charges, he has an item with 2 charges and another one with 1 one charges shall it become [3][2] or [3][1][1], currently it produces result 2?
In Numbers: Gain [2] has [2][1] -> [3][2] or [3][1][1]?​

JASS:
//filter Out PowerUps
function GainItemCon takes nothing returns boolean
   return not IsItemPowerup(GetManipulatedItem ())
endfunction

function GainItem takes nothing returns nothing
   local item it = GetManipulatedItem ()
   local unit picker =  GetManipulatingUnit ()
   local item slot
   local integer loopA = 0
   local integer oldCharges
   local integer newCharges = GetItemCharges(it)
   //Has Charges ?
   if GetItemCharges (GetManipulatedItem ()) != 0 then
       loop
           exitwhen loopA > 5
           set slot = UnitItemInSlot (picker, loopA)
           set oldCharges = GetItemCharges(slot)
           //Same ItemType / not same Item   / not full ?
           if (GetItemTypeId(it) == GetItemTypeId(slot) and slot != it and oldCharges < udg_ItemSystem_MaxCharges) then
               //Combined Charges in the Limit?
               if oldCharges + newCharges <= udg_ItemSystem_MaxCharges then
                   call SetItemCharges(slot, newCharges +oldCharges)
                   call RemoveItem(it)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
                   set it = null
               else
                   //Not in the Limit fill Slotitem
                   set newCharges = newCharges - ( udg_ItemSystem_MaxCharges - oldCharges)
                   call SetItemCharges(it, newCharges )
                   call SetItemCharges(slot, udg_ItemSystem_MaxCharges)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
               endif
               exitwhen (true)
           endif
           set loopA = loopA + 1
       endloop
       if it != null then
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it) + "[" + I2S(newCharges ) +"]" )
       endif
   else
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 30.00, GetItemName(it)  )
   endif
   set it = null
   set picker = null
   set slot = null
endfunction

//Works only if an Item is moved; Filters Items without Charges
function MoveItemCon takes nothing returns boolean
   return ( GetIssuedOrderId() >= 852002 and  GetIssuedOrderId() <= 852007  and GetItemCharges(GetOrderTargetItem()) != 0)
endfunction

function MoveItem takes nothing returns nothing
   local item movingItem = GetOrderTargetItem()
   local item swapedItem
   local item slotItem
   local unit hero = GetTriggerUnit()
   local integer oldSlot
   local integer newSlot = GetIssuedOrderId() - 852002
   local integer loopA = 0
   local integer newCharges
   //Find OldItem Slot
   loop
       exitwhen loopA > 5
       if UnitItemInSlot (hero, loopA) == movingItem then
           set oldSlot = loopA
           exitwhen (true)
       endif
       set loopA = loopA + 1
   endloop
   set swapedItem = UnitItemInSlot (hero, newSlot)
   //Same ItemType & was Moved at all & Charges of movingItem below udg_ItemSystem_MaxCharges ?
   if ( GetItemTypeId (swapedItem) == GetItemTypeId(movingItem) and newSlot != oldSlot and GetItemCharges(movingItem) < udg_ItemSystem_MaxCharges and GetItemCharges(swapedItem) < udg_ItemSystem_MaxCharges) then
       //Will Moving Stacking Result into 1 Item?
       if GetItemCharges(movingItem) + GetItemCharges(swapedItem)  <= udg_ItemSystem_MaxCharges then
           call SetItemCharges(movingItem, GetItemCharges(movingItem) + GetItemCharges(swapedItem))
           call RemoveItem(swapedItem)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"]" )
       else
           set newCharges = GetItemCharges(swapedItem) - ( udg_ItemSystem_MaxCharges - GetItemCharges(movingItem) )
           call SetItemCharges(movingItem, udg_ItemSystem_MaxCharges)
           call SetItemCharges(swapedItem, newCharges)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"] & ["+I2S(newCharges)+"]" )
       endif
   else
       //Split?
       if newSlot == oldSlot and GetItemCharges(movingItem) != 1 then
           set loopA = 0
           loop
               exitwhen loopA > 5
               set slotItem = UnitItemInSlot (hero, loopA)
               // Same Type / not max charges / not One ?
               if ( GetItemTypeId(slotItem) == GetItemTypeId(movingItem) and GetItemCharges(slotItem) < udg_ItemSystem_MaxCharges and slotItem != movingItem ) then
                   //Move 1 Charge from Splitting item to other one
                   call SetItemCharges(slotItem, GetItemCharges(slotItem) + 1)
                   call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
                   //Clean and End
                   set movingItem = null
                   set swapedItem = null
                   set slotItem = null
                   set hero = null
                   return
               endif
               set loopA = loopA + 1
           endloop
           //If Hero has no Item which could take the charge -> Create a new with 1 Charge give it to hero and after that reduce splitting item Charges
           //DisableTrigger Stacking Trigger to allow Splitting Items without full Charges
           call DisableTrigger(udg_ItemSystem[0])
           set swapedItem = CreateItem(GetItemTypeId(movingItem), GetUnitX(hero), GetUnitY(hero))
           call SetItemCharges(swapedItem, 1)
           call UnitAddItem(hero, swapedItem)
           call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
           call EnableTrigger(udg_ItemSystem[0])
       endif
   endif
   set movingItem = null
   set swapedItem = null
   set slotItem = null
   set hero = null
endfunction

//===========================================================================
function InitTrig_ItemSystem takes nothing returns nothing
   //0 = Pick;
   //1 = Move/Split
   set udg_ItemSystem_MaxCharges = 3
   set udg_ItemSystem[0] = CreateTrigger()
   set udg_ItemSystem[1] = CreateTrigger()
 
   call TriggerAddAction( udg_ItemSystem[0], function GainItem )
   call TriggerAddCondition( udg_ItemSystem[0],  Condition (function GainItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[0], EVENT_PLAYER_UNIT_PICKUP_ITEM )
 
   call TriggerAddAction( udg_ItemSystem[1], function MoveItem )
   call TriggerAddCondition( udg_ItemSystem[1],  Condition (function MoveItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[1], EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
endfunction
 

Attachments

  • Jass Class 6 - Item Splitting.w3x
    19.9 KB · Views: 53
Last edited:
Pickup item with charges do now Fill all not full charge items of the same type in the inventory. was quite easy to change :).
JASS:
//filter Out PowerUps
function GainItemCon takes nothing returns boolean
   return not IsItemPowerup(GetManipulatedItem ())
endfunction

function GainItem takes nothing returns nothing
   local item it = GetManipulatedItem ()
   local unit picker =  GetManipulatingUnit ()
   local item slot
   local integer loopA = 0
   local integer oldCharges
   local integer newCharges = GetItemCharges(it)
   //Has Charges ?
   if GetItemCharges (GetManipulatedItem ()) != 0 then
       loop
           exitwhen loopA > 5
           set slot = UnitItemInSlot (picker, loopA)
           set oldCharges = GetItemCharges(slot)
           //Same ItemType / not same Item   / not full ?
           if (GetItemTypeId(it) == GetItemTypeId(slot) and slot != it and oldCharges < udg_ItemSystem_MaxCharges) then
               //Combined Charges in the Limit?
               if oldCharges + newCharges <= udg_ItemSystem_MaxCharges then
                   call SetItemCharges(slot, newCharges +oldCharges)
                   call RemoveItem(it)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
                   set it = null
                   exitwhen (true)
               else
                   //Not in the Limit fill Slotitem
                   set newCharges = newCharges - ( udg_ItemSystem_MaxCharges - oldCharges)
                   call SetItemCharges(it, newCharges )
                   call SetItemCharges(slot, udg_ItemSystem_MaxCharges)
                   call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(slot) + "["+I2S(oldCharges)+ " -> " + I2S(GetItemCharges(slot)) +"]" )
               endif   
           endif   
           set loopA = loopA + 1
       endloop
       if it != null then
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(it) + "[" + I2S(newCharges ) +"]" )
       endif   
   else
       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(it)  )
   endif   
   set it = null
   set picker = null
   set slot = null
endfunction

//Works only if an Item is moved; Filters Items without Charges
function MoveItemCon takes nothing returns boolean
   return ( GetIssuedOrderId() >= 852002 and  GetIssuedOrderId() <= 852007  and GetItemCharges(GetOrderTargetItem()) != 0)
endfunction

function MoveItem takes nothing returns nothing
   local item movingItem = GetOrderTargetItem()
   local item swapedItem
   local item slotItem
   local unit hero = GetTriggerUnit()
   local integer oldSlot
   local integer newSlot = GetIssuedOrderId() - 852002
   local integer loopA = 0
   local integer newCharges
   //Find OldItem Slot
   loop
       exitwhen loopA > 5
       if UnitItemInSlot (hero, loopA) == movingItem then
           set oldSlot = loopA   
           exitwhen (true)
       endif   
       set loopA = loopA + 1
   endloop
   set swapedItem = UnitItemInSlot (hero, newSlot)
   //Same ItemType & was Moved at all & Charges of movingItem below udg_ItemSystem_MaxCharges ?
   if ( GetItemTypeId (swapedItem) == GetItemTypeId(movingItem) and newSlot != oldSlot and GetItemCharges(movingItem) < udg_ItemSystem_MaxCharges and GetItemCharges(swapedItem) < udg_ItemSystem_MaxCharges) then
       //Will Moving Stacking Result into 1 Item?
       if GetItemCharges(movingItem) + GetItemCharges(swapedItem)  <= udg_ItemSystem_MaxCharges then
           call SetItemCharges(movingItem, GetItemCharges(movingItem) + GetItemCharges(swapedItem))
           call RemoveItem(swapedItem)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"]" )
       else
           set newCharges = GetItemCharges(swapedItem) - ( udg_ItemSystem_MaxCharges - GetItemCharges(movingItem) )
           call SetItemCharges(movingItem, udg_ItemSystem_MaxCharges)
           call SetItemCharges(swapedItem, newCharges)
           call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 10.00, GetItemName(movingItem) + "s Combined into [" + I2S(GetItemCharges(movingItem)) +"] & ["+I2S(newCharges)+"]" )
       endif
   else
       //Split?
       if newSlot == oldSlot and GetItemCharges(movingItem) != 1 then
           set loopA = 0
           loop
               exitwhen loopA > 5
               set slotItem = UnitItemInSlot (hero, loopA)
               // Same Type / not max charges / not One ?
               if ( GetItemTypeId(slotItem) == GetItemTypeId(movingItem) and GetItemCharges(slotItem) < udg_ItemSystem_MaxCharges and slotItem != movingItem ) then
                   //Move 1 Charge from Splitting item to other one
                   call SetItemCharges(slotItem, GetItemCharges(slotItem) + 1)
                   call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
                   //Clean and End
                   set movingItem = null
                   set swapedItem = null
                   set slotItem = null
                   set hero = null
                   return
               endif
               set loopA = loopA + 1
           endloop   
           //If Hero has no Item which could take the charge -> Create a new with 1 Charge give it to hero and after that reduce splitting item Charges
           //DisableTrigger Stacking Trigger to allow Splitting Items without full Charges
           call DisableTrigger(udg_ItemSystem[0])
           set swapedItem = CreateItem(GetItemTypeId(movingItem), GetUnitX(hero), GetUnitY(hero))
           call SetItemCharges(swapedItem, 1)
           call UnitAddItem(hero, swapedItem)
           call SetItemCharges(movingItem, GetItemCharges(movingItem) - 1)
           call EnableTrigger(udg_ItemSystem[0])
       endif
   endif
   set movingItem = null
   set swapedItem = null
   set slotItem = null
   set hero = null
endfunction

//===========================================================================
function InitTrig_ItemSystem takes nothing returns nothing
   //0 = Pick;
   //1 = Move/Split
   set udg_ItemSystem_MaxCharges = 3
   set udg_ItemSystem[0] = CreateTrigger()
   set udg_ItemSystem[1] = CreateTrigger()
   
   call TriggerAddAction( udg_ItemSystem[0], function GainItem )
   call TriggerAddCondition( udg_ItemSystem[0],  Condition (function GainItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[0], EVENT_PLAYER_UNIT_PICKUP_ITEM )
   
   call TriggerAddAction( udg_ItemSystem[1], function MoveItem )
   call TriggerAddCondition( udg_ItemSystem[1],  Condition (function MoveItemCon) )
   call TriggerRegisterAnyUnitEventBJ( udg_ItemSystem[1], EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
endfunction
 

Attachments

  • Jass Class 6 - Item Splitting.w3x
    20 KB · Views: 59
Pretty good. From functionality it's higher than many other basic stacking/splitting examples out there that I saw.
Just in case you're interested, one could allow binding item type unique stack-limits, and smart split amounts if needed for a map just by using hashtable. But it's just a thought, notn needed at all here.

Gj, gogo!^^

full
 
Last edited:
Status
Not open for further replies.
Top