Easy Item Stack 'n Split v2.7.4

This bundle is marked as approved. It works and satisfies the submission rules.
Easy Item Stack 'n Split v2.7.4
by Dangerb0y

FEATURES:
- Automatically stacks obtained items to an optional stack limit.
- Allows stacking items within a unit's inventory.
- Allows splitting item stacks within a unit's inventory.
- Allows units to seamlessly pick up items regardless of a full inventory.
- Copy-paste implementation.

STACKING ITEMS:
- Obtained items are automatically stacked with same-type items in a unit's inventory.
- Placing same-type items on top of each other will stack them together.

SPLITTING ITEMS:
- Double right-clicking or dropping an item stack on itself will split 1 off the pile. (optional)
- Consecutively split items will stack together. (optional)
- If a unit's inventory slots are full when splitting an item stack, the split item will be dropped on the ground in front of the unit. (optional)

ITEM STACKS:
- The maximum stack size is set by the item's level in the Object Editor (Shift+Double-click allows entering levels greater than 8).
- Setting an item's level to 0 will give it an unlimited stack size.
- Items must have charges in order to be stacked; non-charged items will function as Blizzard intended.

RELEASE NOTES:
- This system can be implemented into just about any map.
- This system is completely leak-free.
- This system is completely lag-free.
- This system is fully MUI and MPI.
- This system works with all inventory sizes.
- This system does NOT use hashtables or gamecache, i.e. it is much faster.
- This system is available in vJASS and GUI.

IMPLEMENTATION (vJASS):
1) Copy the trigger "EasyItemStacknSplit" to your Trigger Editor.
You must have JNGP + The Latest JassHelper to implement this version!

IMPLEMENTATION (GUI):
1) In map view, go to File > Preferences... and tick "Automatically create unknown variables while pasting trigger data" under the General tab.
2) Copy the trigger "EasyItemStacknSplitGUI" to your Trigger Editor.

UPDATING? Make sure to first delete old EasyItemStacknSplit triggers and, if you use the GUI version, all the variables with the "EasyItem" prefix.

1) Create a blank text document on your desktop and name it "blank.wav".
2) Import it with Import Manager and give it the custom path "Sound\Interface\Warning\Human\KnightInventoryFull1.wav".
Repeat this step for the following:
- "Sound\Interface\Warning\Orc\GruntInventoryFull1.wav"
- "Sound\Interface\Warning\Naga\NagaInventoryFull1.wav"
- "Sound\Interface\Warning\Undead\NecromancerInventoryFull1.wav"
- "Sound\Interface\Warning\NightElf\SentinelInventoryFull1.wav"
3) In map view, go to Advanced > Game interface... look for "Text - Message - 'Inventory is full.'" and put in a single space as its value.
4) Give yourself a firm yet gentle pat on the back. :)
v2.7.4:
--> Fixed a bug causing powerups to double up. Thank you to pks9067 for picking this up.
v2.7.3:
--> Added functionality for item stacks larger than their set stack size.
v2.7.2:
--> Fixed a split-stacking bug in GUI version. Thank you to xorkatoss for picking this up.
v2.7.1:
--> Fixed a stacking overflow bug in GUI version. Thank you to ABM for picking this up.
v2.7:
--> Consecutively split items now stack together!
--> Added parameters for split-stacking.
--> Majorly optimized GUI version.
v2.6.1:
--> Minor item cooldown incongruity fixed.
--> Minor code optimization.
v2.6:
--> Added parameter to enable/disable using item levels to determine stack limit.
--> Removed the full inventory error message. It's just not worth the ClearTextMessages.
--> Got rid of custom scripts in the GUI version where possible.
--> Reworked sounds a bit.
v2.5:
--> Modernized vJASS version a bit.
--> Condensed GUI version into a single trigger.
--> Fixed 1 or 2 potential bugs.
v2.4.2:
--> Another desync issue fixed (both versions). Looks like we're finally out of the woods.
v2.4.1:
--> System parameter added for enabling/disabling item split-dropping.
--> Desync issue fixed in GUI version. Thank you to gadina_prokleta for picking this up.
v2.4:
--> System parameter added for enabling/disabling item splitting.
--> System parameters added to GUI version.
--> Some much needed security added.
v2.3.2:
--> Timer cycle performance enhanced.
v2.3.1:
--> Minor lag issue fixed.
--> Some minor bugs fixed.
v2.3:
--> Optimized timer recycling.
--> Minor sound bugs fixed.
--> Some other important bugs fixed.
v2.2:
--> Major bug fix regarding desyncs in multiplayer maps.
--> Fixed a stacking issue in GUI version.
--> Minor code optimization.
v2.1:
--> Added the ability to have unlimited stack sizes by setting item level to 0.
v2.0.1:
--> Fixed minor sound bug in vJASS version.
--> Optimized code a bit more in vJASS version.
v2.0:
--> Completely revamped code to allow full inventory usage!
--> Removed the JASS version and added a vJASS version. Anyone coding in JASS should be doing it in vJASS anyway.
v1.7:
--> Optimized code slightly more.
--> Added GUI version for the GUIers.
v1.6:
--> Converted to JASS for better optimization and easier implementation.
--> Optimized code for slightly faster execution.
--> Added more comments.
v1.5:
--> Changed loops to use a set variable to avoid any conflict with other loops in a map. Thank you to Caedrus for picking this up.
v1.4:
--> Fixed a bug (which somehow created itself after months of working fine) causing items not to split properly. Thank you to 88WaRCraFT3 for picking this up.
v1.3:
--> Added several comments to the script to make it easier to understand.
v1.2:
--> Fixed a bug causing split-off-stack-and-auto-dropped items to be placed at position of unit instead of in front of it.
v1.1:
--> Fixed point leaks caused by creating items at points with polar offsets. This system is now 100% leak-free!
+REP for anyone who finds a bug or leak for me to fix :)

Keywords:
item, stack, split, inventory, full, items, system, simple, easy, everything, unit, jass, vjass, gui, warcraft, editor, wc3
Contents

Easy Item Stack 'n Split v2.7.4 (Map)

Reviews
11:23, 22nd Dec 2009 TriggerHappy: Review for Spell I suppose it can be useful for other GUI users. The other GUI ones IIRC aren't as advanced as this, therefor I will approve this. Status Feel free to message me here if you...

Moderator

M

Moderator

11:23, 22nd Dec 2009
TriggerHappy:

Review for Spell

I suppose it can be useful for other GUI users. The other GUI ones
IIRC aren't as advanced as this, therefor I will approve this.

Status

Feel free to message me here if you have any issues with
my review or if you have updated your resource and want it reviewed again.

Approved
 
Level 8
Joined
Oct 11, 2009
Messages
40
There are loads of systems like this, only thing difrent here is that he has good eye atraction(the collors of the letters and screenshot) :p

You're right about the eye attraction :thumbs_up:, but i'm gonna have to disagree with you that there are loads of systems like this... i may be wrong, so if you can find a system like this (as easy to implement, completely bug & leak free, MUI & MPI, and as functional) please post a link so i can tell you why my system is still better :grin:
 
You're right about the eye attraction :thumbs_up:, but i'm gonna have to disagree with you that there are loads of systems like this... i may be wrong, so if you can find a system like this (as easy to implement, completely bug & leak free, MUI & MPI, and as functional) please post a link so i can tell you why my system is still better :grin:

well if you ask me like that:grin::grin:
:fp:My Bag and Advanced Item System
It does the same as yours and many more things and you just need to implement 1 trigger without any variables...

But know serious again:
Your system is very good, too, most for GUI beginners which want to learn!!
 
Level 8
Joined
Oct 11, 2009
Messages
40
well if you ask me like that:grin::grin:
:fp:My Bag and Advanced Item System
It does the same as yours and many more things and you just need to implement 1 trigger without any variables...

Yeah I've seen your system before. It has 1 or 2 kinks mentioned in the thread, but otherwise very nice. Still quite different to mine though.

But know serious again:
Your system is very good, too, most for GUI beginners which want to learn!!

Thanks dude. That was pretty much what I was going for. Especially the GUI.
 
Level 37
Joined
Mar 6, 2006
Messages
9,242
It doesn't stack items if your inventory is full.

If you have five stacks of 3 mana potions, and one stack of one mana potion, and you try to pick up more potions, it doesn't stack them. It just says inventory full.

But I guess there's no way around it unless you base the thing around runes.
 
Level 8
Joined
Oct 11, 2009
Messages
40
Yeah, the plan for this system was never really to solve the full-inventory-stacking problem, its purpose is just to add some much needed inventory capabilities to any map with little effort, and to be easily understandable by the average GUIer. A while ago i coded a system based on this one that gets around the full inventory problem, both with picking up and buying items, but as you mentioned, Maker, it works with runes which makes implementing it not so "easy" anymore...

The simple way around it for me would be to use my own system :)

I'm still on the lookout for easier ways of overcoming the full inv problem, so if you have a link to your system please post it so we can take a look.
 
Last edited:
Level 8
Joined
Oct 11, 2009
Messages
40
try my bag system again...
you see that you can still pick up stackable items, even if your inventory is full!!
this can be done in GUI, too...

if you are interested in that method i'll tell you, but plz PM me!

As soon as i get some free time i'll definitely be interested in GUIing your method. it would be really nice to implement this feature without mapmakers having to make duplicate items and what not. I'll PM you..

Thanks for the comments other people, glad you enjoy the system :thumbs_up:
 
Level 10
Joined
Jun 7, 2007
Messages
195
This is great! It's simple yet effective. However I converted it into JASS for better optimization and configureability. I hope it helps somebody.

Here's the code: (I know it's not perfect but it's better than plain GUI anyways, I guess.)
JASS:
//===========================================================================
//========================= ITEM STACKING ===================================
//===========================================================================
// - Manages items stacking and splitting
//     - To make an item stackable, simple add it's rawcode to the list below
//
// - Credits:
//     - Original GUI system by Dangerb0y
//     - Converted to JASS by Wezthal
//===========================================================================
scope ItemStacking initializer Init
//===========================================================================
    globals
        constant real DEGTORAD = 0.01745327
        private integer array stackable
        private integer orderId = 0
        private constant hashtable StackHash = InitHashtable()
    endglobals
//===========================================================================
function GetItemTypeIdMaxCharges takes integer nItemTypeId returns integer
    local item it = CreateItem(nItemTypeId, 0, 0)
    local integer it_charges = GetItemCharges(it)
    call RemoveItem(it)
    set it = null
    return it_charges
endfunction
//===========================================================================
    private function Setup takes nothing returns nothing
        local integer i = 0
        local integer array it_id
//===========================================================================
//========================== SETUP START ====================================
//===========================================================================
        //List stackable itemtype rawcodes here
        set it_id[0] = 'I001'
        set it_id[1] = 'I006'
        //set it_id[2] = '    '
        //set it_id[3] = '    '
        // . . .
//===========================================================================
//========================== SETUP END ======================================
//===========================================================================
        loop
            exitwhen (it_id[i] == null)
            call SaveBoolean(StackHash, StringHash("IsItemStackable"), it_id[i], true)
            call SaveInteger(StackHash, StringHash("ItemTypeIdMaxCharges"), it_id[i], GetItemTypeIdMaxCharges(it_id[i]))
            set i = i + 1
        endloop
    endfunction
//===========================================================================
    private function CountItems takes unit u returns integer
        local integer i     = 0 
        local integer items = 0
        loop
            exitwhen (i > 5)
            if (UnitItemInSlot(u, i) != null) then
                set items = items + 1
            endif
            set i = i + 1
        endloop
        return items
    endfunction
//===========================================================================
    private function ItemStacking_Conditions takes nothing returns boolean
        local item it
        local integer it_id
        local integer i = 0
        
        if (GetOrderTargetItem() != null) then
            set it = GetOrderTargetItem()
        else
            set it = GetManipulatedItem()
        endif
        set it_id = GetItemTypeId(it)
        
        if (GetItemCharges(it) > 0) then
            if (LoadBoolean(StackHash, StringHash("IsItemStackable"), it_id)) then
                set it = null
                return true
            endif
        endif
        set it = null
        return false
        
    endfunction
//===========================================================================
    private function ItemStacking_Actions takes nothing returns nothing
        local unit    u = GetTriggerUnit()
        local integer pl = GetPlayerId(GetOwningPlayer(u))
        local integer i
        local item    loopItem
        local integer loopItemTypeId
        local integer loopItemMaxCharges
        local integer loopItemCharges
        local item    eventItem = GetOrderTargetItem()
        local integer eventItemTypeId
        local integer eventItemMaxCharges
        local integer eventItemCharges
        local item    newItem
        local real X
        local real Y
        local real facing
        
        if (orderId != 1) then
            set orderId = GetIssuedOrderId()
            
            if (orderId >= 852002) and (orderId <= 852007) then
                if ( CountItems(u) > 0 ) and ( UnitHasItem( u, eventItem ) ) then
                    set i = 0
                    loop
                        exitwhen (i > UnitInventorySize(u) - 1)
                        
                        set eventItem = GetOrderTargetItem()
                        set eventItemTypeId = GetItemTypeId(eventItem)
                        set eventItemMaxCharges = LoadInteger(StackHash, StringHash("ItemTypeIdMaxCharges"), eventItemTypeId)
                        set eventItemCharges = GetItemCharges(eventItem)
                        set loopItem = UnitItemInSlot(u, i)
                        set loopItemTypeId = GetItemTypeId(loopItem)
                        set loopItemMaxCharges = LoadInteger(StackHash, StringHash("ItemTypeIdMaxCharges"), loopItemTypeId)
                        set loopItemCharges = GetItemCharges(loopItem)
                        
                        if ( orderId == 852002 + i ) then
                            if ( loopItemTypeId == eventItemTypeId ) then
                                if ( loopItem != eventItem ) then
                                    if ( loopItemCharges + eventItemCharges > eventItemMaxCharges ) then
                                        if ( eventItemCharges != eventItemMaxCharges ) then
                                            if ( loopItemCharges != loopItemMaxCharges ) then

                                                call SetItemCharges( loopItem, ( loopItemCharges + eventItemCharges ) - eventItemMaxCharges )
                                                call SetItemCharges( eventItem, eventItemMaxCharges )
                                            
                                            endif
                                        endif
                                    
                                    else
                                        
                                        call SetItemCharges( eventItem, eventItemCharges + loopItemCharges )
                                        call RemoveItem( loopItem )
                                    
                                    endif
                                
                                else
                                    if ( eventItemCharges > 1) then

                                        call SetItemCharges( eventItem, eventItemCharges - 1 )
                                        set facing = GetUnitFacing( u )
                                        set X  = GetUnitX( u ) + 100.0 * Cos( facing * DEGTORAD )
                                        set Y  = GetUnitY( u ) + 100.0 * Sin( facing * DEGTORAD )
                                        set newItem = CreateItem( eventItemTypeId, X, Y)
                                        call SetItemCharges( newItem, 1 )

                                        if ( CountItems( u ) < UnitInventorySize( u ) ) then

                                            set orderId = 1
                                            call UnitAddItem( u, newItem )
                                            set orderId = 0
                                        
                                        endif
                                        
                                    endif
                                
                                endif
                            endif
                        endif
                        
                        set i = i + 1
                    endloop
                endif
            else

                set i = 0
                loop
                    exitwhen (i > UnitInventorySize(u) - 1)
                    
                    set eventItem = GetManipulatedItem()
                    set eventItemTypeId = GetItemTypeId(eventItem)
                    set eventItemMaxCharges = LoadInteger(StackHash, StringHash("ItemTypeIdMaxCharges"), eventItemTypeId)
                    set eventItemCharges = GetItemCharges(eventItem)
                    set loopItem = UnitItemInSlot(u, i)
                    set loopItemTypeId = GetItemTypeId(loopItem)
                    set loopItemMaxCharges = LoadInteger(StackHash, StringHash("ItemTypeIdMaxCharges"), loopItemTypeId)
                    set loopItemCharges = GetItemCharges(loopItem)

                    if ( loopItemTypeId == eventItemTypeId ) then
                        if ( loopItemCharges < loopItemMaxCharges ) then
                            if ( loopItem != eventItem ) then
                                if ( loopItemCharges + eventItemCharges > eventItemMaxCharges ) then

                                    call SetItemCharges( eventItem, (loopItemCharges + eventItemCharges) - eventItemMaxCharges )
                                    call SetItemCharges( loopItem, eventItemMaxCharges )
                                    
                                else

                                    call SetItemCharges( loopItem, loopItemCharges + eventItemCharges )
                                    call RemoveItem( eventItem )
                                
                                endif
                            endif
                        endif
                    endif
                    
                    set i = i + 1
                endloop
            
            endif
        endif

        set u = null
        set loopItem = null
        set eventItem = null
        set newItem = null
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
    local integer i
    local trigger t = CreateTrigger()
    
    call Setup()
    
    set i = 0
    loop
        exitwhen (i > 8)
        if (GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING) then
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
        endif
        set i = i + 1
    endloop
    call TriggerAddCondition(t, Condition( function ItemStacking_Conditions ) )
    call TriggerAddAction(t, function ItemStacking_Actions )
    
    set t = null
    endfunction
//===========================================================================
endscope
//===========================================================================
 
Last edited:
Level 10
Joined
Feb 11, 2010
Messages
199
Well, I've got a bit of a problem with this system. I imported it exactly as the directions suggested (just copied the trigger and variables), and it seems to interfere rather severely with all timers and loops in my game. I can't seem to figure out exactly *why* this is, but it's definitely coming from this system, since disabling the item stack and split trigger fixes everything.

What could be causing such game-breaking interference? Any help would be greatly appreciated; I would love to be able to use this system without utterly breaking the rest of my game :)

(Link to relevant game: http://www.hiveworkshop.com/forums/maps-564/last-tower-v1-10-a-164641/index3.html)

EDIT: I seem to have found the issue... the "Integer A" loops were interfering with the "Integer A" loops already in the game. Replacing it with a unique variable loop fixed the issue. Perhaps you should consider using a unique variable for your loops (eg loop for integer variable instead of loop for integer A) so that games can't glitch from using the same variable simultaneously when newbies like me import it ;)

5/5 rating and +rep, in any case. Great resource!
 
Last edited:
Level 8
Joined
Oct 11, 2009
Messages
40
Well, I've got a bit of a problem with this system...

Just when I thought I was cruising down bug-free lane :xxd: Better to find them than not I guess... Many thanks Caedrus. That's quite the esoteric of bugs.

For anyone experiencing what Caedrus was, I've uploaded a new version of the system. Please also check out the IMPLEMENTATION steps again as I've had to add one more variable to properly iron out this bug.

P.S. I played your Last Tower map, Caedrus. Very nice.
 
Level 10
Joined
Feb 11, 2010
Messages
199
Just when I thought I was cruising down bug-free lane :xxd: Better to find them than not I guess... Many thanks Caedrus. That's quite the esoteric of bugs.
It's not really a "bug" (as there's nothing inherently wrong with using the default A/B loops on their own) so much as it's just more likely to interfere with (or be interfered with by) pre-existing systems when not using a unique variable since many people will use the default "Integer A" or "Integer B" loop triggers (and you can't run more than one of those at the same time).

Anyways, glad I could be of help in any case.

P.S. I played your Last Tower map, Caedrus. Very nice.

Glad you liked it :thumbs_up:

I'd appreciate hearing your feedback in the comments thread for TLT.
 
Last edited:
Level 4
Joined
Mar 12, 2008
Messages
83
Thank you for this system! I have only one question, i can only make item lvl 8 and no more, and in your map they stack at 10 hm?
 
Level 8
Joined
Jul 17, 2004
Messages
283
This system is excellent.

It's flawless, simple to implement, easy to use or modify, and is the most flexible GUI item stacking and splitting system I have ever seen. You can expect me to use this in a few of my projects, and will be crediting you, of course. Thank you!

5/5 + Repped
 
Last edited:
Level 8
Joined
Oct 11, 2009
Messages
40
This system is excellent.

It's flawless, simple to implement, easy to use or modify, and is the most flexible GUI item stacking and splitting system I have ever seen. You can except me to use this in a few of my projects, and will be crediting you, of course. Thank you!

5/5 + Repped

I'm glad you noticed :wink: haha. Thanks for the positive response guy, and the rep of course, much appreciated. I'm going to be working on a possible v2.0 of this system, so keep an eye out!
 
Level 8
Joined
Oct 11, 2009
Messages
40
can charged items stack even when the inventory is already full?

Sorry man, I must have missed your post. You can stack charged items that are already in your inventory when it's full, but you can't pick up items when your inventory is full. It's just one of War3's annoying limitations. There are ways to do it of course, but it gets quite complicated.
 
Level 8
Joined
Oct 11, 2009
Messages
40
lol and to think that the last version of this system that i have is 1.4 xD
very nice man this is one of the best triggers on hive workshop :thumbs_up:
keep up the good work with your awesome system ;D

All in a day's work :thumbs_up: very glad you like it.

How's going with the update?

Did any part of our convo even remotely suggest that there will be an update at all?

That being said, v2.0 is on the way... :wink:
 
Last edited:
Top