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

[JASS] [HELP] Possibly Messed-Up Item Stacking System

Status
Not open for further replies.
Level 4
Joined
May 20, 2006
Messages
43
Well, here we go:

JASS:
function Trig_Item_Charge_Actions takes nothing returns nothing
    local item i = GetManipulatedItem()
    local unit u = GetTriggerUnit()
    local integer a = 1
    local integer it = GetItemTypeId(i)
    local integer ci = GetItemCharges(i)
    local integer cr

    if GetItemTypeId(i) == 'I024' or GetItemTypeId(i) == 'I027' or GetItemTypeId(i) == 'I026' or GetItemTypeId(i) == 'I01A' or GetItemTypeId(i) == 'I00X' or GetItemTypeId(i) == 'I00K' or GetItemTypeId(i) == 'I00V' or GetItemTypeId(i) == 'I01B' or GetItemTypeId(i) == 'I00R' or GetItemTypeId(i) == 'I019' or GetItemTypeId(i) == 'I00W' or GetItemTypeId(i) == 'I00Y' or GetItemTypeId(i) == 'I00I' or GetItemTypeId(i) == 'I00A' or GetItemTypeId(i) == 'I00C' or GetItemTypeId(i) == 'I00H' or GetItemTypeId(i) == 'I016' or GetItemTypeId(i) == 'I00Z' or GetItemTypeId(i) == 'I009' or GetItemTypeId(i) == 'I00T' or GetItemTypeId(i) == 'I00B' or GetItemTypeId(i) == 'I00S' or GetItemTypeId(i) == 'I00L' or GetItemTypeId(i) == 'I00Q' or GetItemTypeId(i) == 'I004' or GetItemTypeId(i) == 'I005' or GetItemTypeId(i) == 'I01M' or GetItemTypeId(i) == 'I01N' then
        loop
            exitwhen a > 6
            if GetItemTypeId(UnitItemInSlotBJ(u,a)) == it and UnitItemInSlotBJ(u,a) != i and GetItemCharges(UnitItemInSlotBJ(u,a)) < 5 and GetItemCharges(UnitItemInSlotBJ(u,a)) > 0 then
                set cr = GetItemCharges(UnitItemInSlotBJ(u,a))
                if cr + ci > 5 then
                    call SetItemCharges(UnitItemInSlotBJ(u,a), 5)
                    call SetItemCharges(i, ci - (5 - cr))
                else
                    call RemoveItem(i)
                    call SetItemCharges( UnitItemInSlotBJ(u,a),cr + ci)
                endif
                set a = 5
            endif
            set a = a + 1
        endloop
    endif
endfunction

//===========================================================================
function InitTrig_Item_Charge takes nothing returns nothing
    set gg_trg_Item_Charge = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Item_Charge, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( gg_trg_Item_Charge, function Trig_Item_Charge_Actions )
endfunction

There seems to be an exploit to this coding that allows people to go from 1 item in the stack to 5 items, just by adding on a 2nd item. Just curious if someone could pinpoint the source of this problem. I believe it is here. Thanks!
 
Last edited by a moderator:
Level 1
Joined
Jan 19, 2008
Messages
6
It seems has't any problem.
if somebody get a itme. and if the charge of item less then 5, add item's charge. else move picked item to other slot. is that ture?

err. but there have a problem:
there:
else
call RemoveItem(i)
call SetItemCharges( UnitItemInSlotBJ(u,a),cr + ci)
endif

if charge of picked item more than 5, or item of last had been changed charge
more than 5. well, do you see ?

so , you must check the charge of item there, and do some case.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Just a tip, you can change that long list of item types to this condition (unless you don't want this to work for every charged item of course)

function Trig_Your_Trigger_Conditions takes nothing returns boolean
return GetItemType(GetManipulatedItem()) == ITEM_TYPE_CHARGED
endfunction
 
Level 4
Joined
May 20, 2006
Messages
43
Thanks, but that's not it :S

It's an awkward bug. Hard to replicate, but it happens every now and then.

Basically, there is no way that the item should hit above 5 charges; each item modifies an ability level of unit, so it's impossible to get above 5.

But, every now and then, you can do a combo of taking items off, then putting on another charge, and it bumps it straight to 5... ignoring the +1, and getting +4 instead.

Edit: Thanks for the help though, it's much appreciated.
 
Last edited:
Level 21
Joined
Aug 21, 2005
Messages
3,699
if GetItemTypeId(i) == 'I024' or GetItemTypeId(i) == 'I027' or GetItemTypeId(i) == 'I026' or GetItemTypeId(i) == 'I01A' or GetItemTypeId(i) == 'I00X' or GetItemTypeId(i) == 'I00K' or GetItemTypeId(i) == 'I00V' or GetItemTypeId(i) == 'I01B' or GetItemTypeId(i) == 'I00R' or GetItemTypeId(i) == 'I019' or GetItemTypeId(i) == 'I00W' or GetItemTypeId(i) == 'I00Y' or GetItemTypeId(i) == 'I00I' or GetItemTypeId(i) == 'I00A' or GetItemTypeId(i) == 'I00C' or GetItemTypeId(i) == 'I00H' or GetItemTypeId(i) == 'I016' or GetItemTypeId(i) == 'I00Z' or GetItemTypeId(i) == 'I009' or GetItemTypeId(i) == 'I00T' or GetItemTypeId(i) == 'I00B' or GetItemTypeId(i) == 'I00S' or GetItemTypeId(i) == 'I00L' or GetItemTypeId(i) == 'I00Q' or GetItemTypeId(i) == 'I004' or GetItemTypeId(i) == 'I005' or GetItemTypeId(i) == 'I01M' or GetItemTypeId(i) == 'I01N' then
At the local declaration, you say it = GetItemTypeId(i). So use it instead of GetItemTypeId, since you need to call that function about 30 times in this function, while you only need to call it 1 time.

Secondly: if you can avoid BJ functions, avoid them.
When you're using UnitItemInSlotBJ, replace it with UnitItemInSlot and make sure a ranges from 0 to 5 instead of from 1 to 6.

Can't find another problem though...
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Just in case you want, i've successfuly created a stacking system yestorday (completed today).

[Notes] create a global integer variable called "maxcharges" and set it to the maximum charges you want.

My condition is "item class is charged" but you can change that to your item types of course.

JASS:
    function Trig_Untitled_Trigger_004_Conditions takes nothing returns boolean
        return GetItemType(GetManipulatedItem()) == ITEM_TYPE_CHARGED
    endfunction

    function Trig_Untitled_Trigger_004_Actions takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local item manipulated = GetManipulatedItem()
        local item inventory
        local integer manipulatedcharges = GetItemCharges(manipulated)
        local integer inventorycharges
        local integer totalcharges
        local integer a = 0
        loop
            exitwhen a==6
            if GetItemTypeId(manipulated) == GetItemTypeId(UnitItemInSlot(u, a)) then
                set inventory = UnitItemInSlot(u, a)
                set inventorycharges = GetItemCharges(inventory)
                set totalcharges = inventorycharges + manipulatedcharges
            endif
            if inventorycharges != 6 then
                if UnitItemInSlot(u,a) == manipulated then
                    set u = null
                    set manipulated = null
                    set inventory = null
                    return
                endif
                if totalcharges > udg_maxcharges then
                    call SetItemCharges(inventory,udg_maxcharges)
                    call SetItemCharges(manipulated,(totalcharges-udg_maxcharges))
                else
                    if totalcharges <= udg_maxcharges then
                        call SetItemCharges(inventory,totalcharges)
                        call RemoveItem(manipulated)
                    endif
                endif  
            endif
            set inventory = null
            set a = a+1
        endloop
    set manipulated = null
    set u = null
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_004 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_004 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_004, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddCondition( gg_trg_Untitled_Trigger_004, Condition( function Trig_Untitled_Trigger_004_Conditions ) )
    call TriggerAddAction( gg_trg_Untitled_Trigger_004, function Trig_Untitled_Trigger_004_Actions )
endfunction


(Why the hell do my JASS tags get ruined every time I edit a post with them ? >.<)
 
Last edited by a moderator:
Level 21
Joined
Aug 21, 2005
Messages
3,699
It doesn't matter a lot, no. But if your scripts are FULL of stuff like
if GetItemTypeId(i) == 'I024' or GetItemTypeId(i) == 'I027' or GetItemTypeId(i) == 'I026' or GetItemTypeId(i) == 'I01A' or GetItemTy...
or using globals (when it's unnecessary), then your scripts are ending up being bad as they perform bad...

In the end, if you can do something faster without making the script look totally chaotic, then do so... But try to comment things well so you still remember what the "5" meant after 1 week :)
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Meh, this is part of my itemsystem I created a few days ago... afaik it works correctly, so perhaps use this one...

JASS:
function StackMax takes unit whichunit, item whichitem returns boolean
// this function creates a stack of items of type CHARGED; with a max stackamount.
    local integer index = 0
    local integer itemid1 = GetItemTypeId(whichitem)
    local integer itemid2
    local integer charges1 = GetItemCharges(whichitem)
    local integer charges2
    local item item2
    local itemtype ittype = GetItemType(whichitem)
    local boolean success = false
    if (ittype == ITEM_TYPE_CHARGED) then
        loop
            exitwhen (index > 5)
            set item2 = UnitItemInSlot(whichunit, index)
            set itemid2 = GetItemTypeId(item2)
            set charges2 = GetItemCharges(item2)
            if (item2 != whichitem) and (itemid1 == itemid2) and (charges2 < 6) then
                set success = true
                set index = 6
                if charges1 + charges2 > 6 then
                    call SetItemCharges(item2, 6)
                    call SetItemCharges(whichitem, (6 - charges1 - charges2))
                else
                    call RemoveItem(whichitem)
                    call SetItemCharges(item2, (charges1 + charges2))
                endif
            endif
            set item2 = null
            set index = index + 1
        endloop
    endif
    set ittype = null
    return success
endfunction
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Its basicly exacly the same thing, you just made it with less Ifs (because I didn't know how to do And).

I wonder why mine isn't working.

Actualy, I just spotted a diffrence, I did if item 1 is in slot of item 2 then ... and you did if item 1 IS item 2.

I wonder if thats the problem ?
 
Status
Not open for further replies.
Top