• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Inventory is Full

Status
Not open for further replies.
Level 19
Joined
Aug 8, 2007
Messages
2,765
Any ideas on how to prevent this from happening :vw_sleep:

Basically, if this string appears, than my game de-syncs. (i know the reason, dont worry) Ive been trying to stop this function from activating but whatever i try i just cant. Any ideas?

What ive tried so far..
JASS:
        call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
        call IssueImmediateOrder(u, "stop")
        call TriggerSleepAction(0)
        call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
        call IssueImmediateOrder(u, "stop")
        call TriggerSleepAction(0.25)
        call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
        call IssueImmediateOrder(u, "stop")
I've tried moving the unit to some random spot than moving it back, same with the item, removing and re-creating the item, meh..
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
What are you trying to achieve with this code?

Items being shown for only one player :)

Without at very least the events we can't guess what's your problem.
But let's say that we need the full related script.

the loop is commented out for the time being for other reasons. (if i enable the loop it will still say inventory is full than send it to the backpack and desync)

JASS:
library CustomDrop initializer init
    globals
        private hashtable Hash_t = InitHashtable()
        private location SendToItem = Location(0,0)
    endglobals
    
    private function OnDeath takes nothing returns nothing
        local unit u = GetDyingUnit()
        local integer unitId = GetUnitTypeId(u)
        local integer count = LoadInteger(Hash_t,unitId,0) // if the unit type was not registred for drop it will be equal to 0, else it will be > 0
        local real random
        local integer i
        local item drop
        
        loop // loop on all dropable item for unitID
        exitwhen count == 0 
            
            set i = 0
            loop // player loop
            exitwhen i == 11
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                    set random = GetRandomReal(0,100)
                    if random < LoadReal(Hash_t,unitId,count) then
                        set drop = CreateItem(LoadInteger(Hash_t,unitId,count),GetUnitX(u),GetUnitY(u))
                        call SetItemVisible(drop,GetLocalPlayer()==Player(i))// the item will be visible only for Player(i)
                    endif
                endif
            set i = i+1
           endloop
     
        set count = count-1
        endloop
        set u = null
        set drop = null
    endfunction
    
    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing // chanceToDrop in percent
        local integer n = LoadInteger(Hash_t,unitId,0)
        /* integer : unitId ; 0 -> number of possible item drop for the unit type unitId
           integer : unitId ; x -> rawcode of the item to drop ; x > 0
           real : unitId ; x -> chance of the item x to drop
        */
        set n = n+1
        call SaveInteger(Hash_t,unitId,0,n)
        call SaveInteger(Hash_t,unitId,n,itemId)
        call SaveReal(Hash_t,unitId,n,chanceToDrop)
    endfunction
    private function onItemPickup takes nothing returns nothing
        local item it = GetOrderTargetItem()
        local unit u = GetTriggerUnit()
        local boolean b
        local integer i = 0
        local integer i2 = 0
        call SetItemVisible(GetOrderTargetItem(), true)
 /*       loop
            set b = UnitItemInSlot(u, i) == null
            set i = i + 1
            exitwhen i == 5 or b == true
        endloop
        if b == true then
            call UnitAddItem(u, it)
        else
            set u = udg_Backpack[GetConvertedPlayerId(GetTriggerPlayer())]
            set i = 0
            loop
                set b = UnitItemInSlot(u, i) == null
                set i = i + 1
                exitwhen i == 6 or b == true
            endloop
            if b == true then
                call UnitAddItem(u, it)
                call print("The item has been sent to your backpack")
            else
                call print("You do not have enough room for that item")
            endif
        endif*/
    endfunction

 //    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing //
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        local trigger trig2 = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerRegisterAnyUnitEventBJ(trig2, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig,function OnDeath)
        call TriggerAddAction(trig2, function onItemPickup)
        call RegisterDrop('n000','I00U',7)
        call RegisterDrop('n001','I00U',7)
        call RegisterDrop('n002','I00U',7)
        call RegisterDrop('n00H','I00U',7)
        call RegisterDrop('n00G','I00U',7)
        call RegisterDrop('n00B','I01M',10)
        call RegisterDrop('n00C','I01M',10)
        call RegisterDrop('n00D','I01M',10)
        call RegisterDrop('n003','I01M',10)
        call RegisterDrop('n005','I01N',10)
        call RegisterDrop('n009','I01N',10)
        call RegisterDrop('n007','I01O',25)
        
    endfunction
    
endlibrary

Works fine untill your inventory is full and u try to pick up an item. -_- than it desyncs. The text "Inventory is Full" is simply an indicator that this occured

e/ Troll-Brain i think you mightve written some of that code o_O

2e/ nvm you wrote all of it -_- http://www.hiveworkshop.com/forums/triggers-scripts-269/creating-localized-items-again-213673/
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
No i've not written all the code, according to this last answer

There is a logical error in your code, you forget to check the last slot 5 in your first loop while you check the slot 6 in your second one, when slot bounds is 0-5 IIRC, here is the full code edited (not checked) :

JASS:
library CustomDrop initializer init
    globals
        private hashtable Hash_t = InitHashtable()
        private location SendToItem = Location(0,0)
    endglobals
    
    private function OnDeath takes nothing returns nothing
        local unit u = GetDyingUnit()
        local integer unitId = GetUnitTypeId(u)
        local integer count = LoadInteger(Hash_t,unitId,0) // if the unit type was not registred for drop it will be equal to 0, else it will be > 0
        local real random
        local integer i
        local item drop
        
        loop // loop on all dropable item for unitID
        exitwhen count == 0 
            
            set i = 0
            loop // player loop
            exitwhen i == 11
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                    set random = GetRandomReal(0,100)
                    if random < LoadReal(Hash_t,unitId,count) then
                        set drop = CreateItem(LoadInteger(Hash_t,unitId,count),GetUnitX(u),GetUnitY(u))
                        call SetItemVisible(drop,GetLocalPlayer()==Player(i))// the item will be visible only for Player(i)
                    endif
                endif
            set i = i+1
           endloop
     
        set count = count-1
        endloop
        set u = null
        set drop = null
    endfunction
    
    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing // chanceToDrop in percent
        local integer n = LoadInteger(Hash_t,unitId,0)
        /* integer : unitId ; 0 -> number of possible item drop for the unit type unitId
           integer : unitId ; x -> rawcode of the item to drop ; x > 0
           real : unitId ; x -> chance of the item x to drop
        */
        set n = n+1
        call SaveInteger(Hash_t,unitId,0,n)
        call SaveInteger(Hash_t,unitId,n,itemId)
        call SaveReal(Hash_t,unitId,n,chanceToDrop)
    endfunction
    private function onItemPickup takes nothing returns nothing
        local item it = GetOrderTargetItem()
        local unit u = GetTriggerUnit()
        local boolean b
        local integer i = 0
        local integer i2 = 0
        call SetItemVisible(GetOrderTargetItem(), true)
        loop
            set b = UnitItemInSlot(u, i) == null
        exitwhen b or i == 5
        set i = i+1    
        endloop
        if b then
            call UnitAddItem(u, it)
        else
            set u = udg_Backpack[GetConvertedPlayerId(GetTriggerPlayer())]
            // why not just use GetPlayerId here, GUI "feature" ?
            set i = 0
            loop
                set b = UnitItemInSlot(u, i) == null
            exitwhen b or i == 5
            set i = i + 1
            endloop
            if b then
                call UnitAddItem(u, it)
                call print("The item has been sent to your backpack")
            else
                call print("You do not have enough room for that item")
            endif
        endif
    endfunction

 //    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing //
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        // you don't need two trigger variables, but yes it's kinda irrevelant
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerAddAction(trig,function OnDeath)
        set trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig, function onItemPickup)
        call RegisterDrop('n000','I00U',7)
        call RegisterDrop('n001','I00U',7)
        call RegisterDrop('n002','I00U',7)
        call RegisterDrop('n00H','I00U',7)
        call RegisterDrop('n00G','I00U',7)
        call RegisterDrop('n00B','I01M',10)
        call RegisterDrop('n00C','I01M',10)
        call RegisterDrop('n00D','I01M',10)
        call RegisterDrop('n003','I01M',10)
        call RegisterDrop('n005','I01N',10)
        call RegisterDrop('n009','I01N',10)
        call RegisterDrop('n007','I01O',25)
        set trig = null // just because i can
        
    endfunction
    
endlibrary

But if it still desync, and not if you comment the loop (and only the loop), then i have no clue because there is no local code there. Excepted maybe with your print function.
Or you have some other local code somewhere else.
 
Last edited:
Level 19
Joined
Aug 8, 2007
Messages
2,765
i dont check slot 5 because it is always occupied :p

and the part that desyncs is solely in SetItemVisible. If the inventory is full, than it desyncs instantly. If not, than onItemPickup averts it away from the desync that would happen. Currently my only two solutions are to use tomes (i swear im pretty sure that they will desync MORE than regular items) or to only allow for four slots
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
If not, than onItemPickup averts it away from the desync that would happen

I don't understand what you want mean.

But i suppose that like i thought in the other thread, hide an item in a local block is not safe.
I suppose it desycn when the item is targeted, because it can't be targeted if it's hidden.

So your best hope is to edit the item model, and then you can play with animations, it will work 100 %.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I don't understand what you want mean.

But i suppose that like i thought in the other thread, hide an item in a local block is not safe.
I suppose it desycn when the item is targeted, because it can't be targeted if it's hidden.

So your best hope is to edit the item model, and then you can play with animations, it will work 100 %.

Nonono. it works fine. it will not desync as long as i turn the item visible when the unit is ordered to pick it up. My problem is that if the units inventory is full than he will try to pick it up BEFORE the trigger is able to set it visible.

(if you make a debug in the onItemPickup, the text "Inventory is Full" will appear in yellow where it normally is than like 0.25-0.5 sec later the debug message will appear)
 
Level 12
Joined
Oct 16, 2010
Messages
680
Arhowk

I already mentiond this in a prewious post , but try triggering the order
make a quick check that if there is no free inventory slot
break the order so it won't pick up anithing
and display text "inventory is full"

so in overall you fake the default warcraft3 Inventory is Full thing..
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
That wouldn't work, coz if we believe Arhowk, the order is instant or so when the inventory of the unit is full.
If the item is not visible then the order can't be achieved (the trigger will not fire), which leads to a desync, and since the trigger won't fire you can't do anything to fix that.

The most elegant way is to use custom models, with one animation added which makes the item not visible and not selectable (with the mouse in game), but it will still be selectable by trigger, and then no desync.
And yes play an animation in a local code is perfectly safe.

And btw hiding item in a local block should be never 100 % safe, you know the pathing, collision of the item.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
That wouldn't work, coz if we believe Arhowk, the order is instant or so when the inventory of the unit is full.
If the item is not visible then the order can't be achieved (the trigger will not fire), which leads to a desync, and since the trigger won't fire you can't do anything to fix that.

The most elegant way is to use custom models, with one animation added which makes the item not visible and not selectable (with the mouse in game), but it will still be selectable by trigger, and then no desync.
And yes play an animation in a local code is perfectly safe.

And btw hiding item in a local block should be never 100 % safe, you know the pathing, collision of the item.

At first i didnt understand you but... thats not too bad of an idea... ill post it in the requests section (im not a modeller)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
That would be better to learn by yourself.
You only have to learn how to add an animation, and for making the item not selectable with the mouse when the animation is played, just convert the model to .mdl and define the BoundRadius to 0.
http://www.hiveworkshop.com/forums/...diting-add-animations-tag-222674/#post2217248
Now i don't know how to make an animation which makes the item not visible, but that wouldn't be so hard.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
That would be better to learn by yourself.
You only have to learn how to add an animation, and for making the item not selectable with the mouse when the animation is played, just convert the model to .mdl and define the BoundRadius to 0.
http://www.hiveworkshop.com/forums/...diting-add-animations-tag-222674/#post2217248
Now i don't know how to make an animation which makes the item not visible, but that wouldn't be so hard.

How would you set an item's animation? :) a JASSHelper search for "Item" and "Anim" proves nothing
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I have an other one but that could desync.

Try this code :

JASS:
library Test initializer init

    globals
        private integer Item_id = 'I000' // it is the "unselectable" model
    endglobals

    private function init nothing returns nothing
        call TriggerSleepAction(5)
        if GetLocalPlayer() == Player(0) then
            set Item_id = 'I001' // it is the "normal" model
        endif
        call CreateItem(Item_Id,0,0)
    endfunction

endlibrary

The only difference between I000 and I001 is the model.
Try to use the item, if it still doesn't desync then you have your solution, delete all animations and make a birth loop one which makes the model not visible and not selectable.
Or eventually just make all animations not selectable.

Ofc you have to care if you use the item id in some trigger.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Nah, that wont work for various reasons and it will also decrease the efficiency of my map by loads.

On another subject, your script might work with a few adjustments after Nestharus updates his ISS
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
1) Im 1/10 done with my map and already got closer to 50 items (note : 1/10 does NOT count late game with extensive dungeons plus there will be 25 characters with class based mainhands and offhands)

2) Id have to make another ability for every item (due to my item system)

3) Saving would really mess things up (another assumption)

4) Would selecting a model thats unselectable desync? (probably not because its on the model side)

if you'd like to test it, be my guest. ill try when i get a chance
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I can't do anything about the first 3 points, it's just up to you.

I can say that 4 is okay or i wouldn't have even suggest it.
Now sure that creating two different items could desync by itself, i don't know how wc3 engine handle that, hence why a test is needed.

And i can't test myself, since i can't host.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Testing real fast (bad I/C) but i have another idea that might work

do my strategy, where if its not local player than create a dummy item than set both the dummy item and the real item (on the killing players)'s custom value to the item code of the main item and on the item command trigger you check if items custom value == items type id or item == dummy item type id than delete the item and create the custom value. (thats next test)

E/ It all worked o_O it was working perfectly untill i accidently equipped 5 weapons that did +10 damage on my side and had the other side only equip +5 weapons and i killed the monster before the other side o_O but he said i had more str than on my screen, different items, etc. so now, i guess ill be working on (above)
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Well, it's fine then.

Now you just have to learn how to make not visible an item through an animation, if making it not selectable is not enough for you.

I cant seem to get it to work, but i havent had much time for test&fix cuz im going to bed so can you take a look? (desyncs on pickup)

JASS:
library CustomDrop initializer init
    globals
        private hashtable Hash_t = InitHashtable()
        private location SendToItem = Location(0,0)
    endglobals
    
    private function OnDeath takes nothing returns nothing
        local unit u = GetDyingUnit()
        local integer unitId = GetUnitTypeId(u)
        local integer count = LoadInteger(Hash_t,unitId,0) // if the unit type was not registred for drop it will be equal to 0, else it will be > 0
        local real random
        local integer i
        local item drop
        local integer dummy = 'I005'
        
        loop // loop on all dropable item for unitID
        exitwhen count == 0 
            
            set i = 0
            loop // player loop
            exitwhen i == 11
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                    set random = GetRandomReal(0,100)
                    if random < LoadReal(Hash_t,unitId,count) then
                        if GetLocalPlayer() == Player(i) then
                            set dummy = LoadInteger(Hash_t,unitId,count)
                        endif
                        set drop = CreateItem(dummy,GetUnitX(u),GetUnitY(u))
                        call SetItemUserData(drop, LoadInteger(Hash_t,unitId,count))
                    endif
                endif
            set i = i+1
           endloop
     
        set count = count-1
        endloop
        set u = null
        set drop = null
    endfunction
    
    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing // chanceToDrop in percent
        local integer n = LoadInteger(Hash_t,unitId,0)
        /* integer : unitId ; 0 -> number of possible item drop for the unit type unitId
           integer : unitId ; x -> rawcode of the item to drop ; x > 0
           real : unitId ; x -> chance of the item x to drop
        */
        set n = n+1
        call SaveInteger(Hash_t,unitId,0,n)
        call SaveInteger(Hash_t,unitId,n,itemId)
        call SaveReal(Hash_t,unitId,n,chanceToDrop)
    endfunction
    private function onItemPickup takes nothing returns nothing
        local item it = GetOrderTargetItem()
        local unit u = GetTriggerUnit()
        local boolean b
        local integer i = 0
        local integer i2 = 0
        local item dummy
//        call SetItemVisible(GetOrderTargetItem(), true)
        if GetItemTypeId(it) == GetItemUserData(it) or GetItemTypeId(it) == 'I00N' then
            set dummy = CreateItem(GetItemUserData(it), GetItemX(it), GetItemY(it))
            call RemoveItem(it)
            set it = dummy
            call IssueTargetItemOrder(u,"smart",it)
            set it = null
            set u = null
            return
        endif
        loop
            set b = UnitItemInSlot(u, i) == null
            set i = i + 1
            exitwhen i == 5 or b == true
        endloop
        if b == true then
  //          call UnitAddItem(u, it)
        else
            set u = udg_Backpack[GetConvertedPlayerId(GetTriggerPlayer())]
            set i = 0
            loop
                set b = UnitItemInSlot(u, i) == null
                set i = i + 1
                exitwhen i == 6 or b == true
            endloop
            if b == true then
                call UnitAddItem(u, it)
                call print("The item has been sent to your backpack")
            else
                call print("You do not have enough room for that item")
            endif
        endif
    endfunction

 //    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing //
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        local trigger trig2 = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerRegisterAnyUnitEventBJ(trig2, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig,function OnDeath)
        call TriggerAddAction(trig2, function onItemPickup)
        call RegisterDrop('n000','I00U',7)
        call RegisterDrop('n001','I00U',7)
        call RegisterDrop('n002','I00U',7)
        call RegisterDrop('n00H','I00U',7)
        call RegisterDrop('n00G','I00U',7)
        call RegisterDrop('n00B','I01M',10)
        call RegisterDrop('n00C','I01M',10)
        call RegisterDrop('n00D','I01M',10)
        call RegisterDrop('n003','I01M',10)
        call RegisterDrop('n005','I01N',10)
        call RegisterDrop('n009','I01N',10)
        call RegisterDrop('n007','I01O',25)
        
    endfunction
    
endlibrary

Basically what it does is if its not local player than it creates 'I00N' (a blank item) and sets the item user data to the correct item id so when its issued pickup it will remove the item and re-add it (except for non-picking up players it will delete 'I00N' and place the correct iem)

(i also tested it wth a physical item that the other side could pick up and it also desynced, i think my problem is in the item switching method)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
In order to work correctly the only difference between 2 items (excepted the rawcode ofc) must be the model.
It must have exactly the same effects.
So no you just can't create a blank item.
For each item available you need to create the same but with a different model.
And once the item is created you don't need extra stuff, only care if you use the itemId in some trigger.

If you could play animations for an item you would only to edit the model, without creating for each item available an other one, but sadly you can't, it's the only way.
At least i don't see a more elegant one (result in game).

EDIT :

Well, your way could work maybe but i can't guarantee that.
I'm just sure my way is 100 % safe.
Anyway there is an error in your loop :

JASS:
            loop // player loop
            exitwhen i == 11
                set dummy = 'I005' // without it, it's screwed, hope you know why
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                    set random = GetRandomReal(0,100)
                    if random < LoadReal(Hash_t,unitId,count) then
                        if GetLocalPlayer() == Player(i) then
                            set dummy = LoadInteger(Hash_t,unitId,count)
                        endif
                        set drop = CreateItem(dummy,GetUnitX(u),GetUnitY(u))
                        call SetItemUserData(drop, LoadInteger(Hash_t,unitId,count))
                    endif
                endif
           set i = i+1
           endloop

Note that there i assume that 'I005' is your blank not selectable item.

Also it should be :

if GetItemTypeId(it) != GetItemUserData(it) then // "or GetItemTypeId(it) == 'I00N " : no need for this or, right ?

But meh, i'm almost sure it will always desync, coz you create/destroy an item + give an order in a local code ...
And btw the order is 100 % useless.

Try this, instead of the if :
JASS:
        set rawcode = GetItemUserData(it)
        call RemoveItem(it)
        set it = CreateItem(rawcode, GetUnitX(u), GetUnitY(u))
        call SetItemUserData(it,rawcode)
        // and eventually UnitAddItem but i'm not sure it's needed.

But even if it works, if the player drops the item, it will be selectable by all players, ofc you could try something with the item drop event to handle that.

If you care about that, i suppose you could define the owner of the item with the appropriate native function, and then use this data on drop event.

And also care about the pickup event, i don't know if this event fire when the units gets an item by a trigger action.
If it's the case, disable the trigger, give the item, enable the trigger, assuming it's instant, if it's delayed then it's getting harder and harder ...
 
Last edited:
Level 19
Joined
Aug 8, 2007
Messages
2,765
No friends online so i cant test, but you looked over a few things

set dummy = 'I005' // without it, it's screwed, hope you know why

I see what you mean...

if GetItemTypeId(it) != GetItemUserData(it) then // "or GetItemTypeId(it) == 'I00N " : no need for this or, right ?

Wrong. which links to

"But meh, i'm almost sure it will always desync, coz you create/destroy an item + give an order in a local code ..."

YOU made it local. my original function checks if the user data = item type OR item = the dummy item. The reason for this is so that for all players this runs (the player that picked up the item will run user data == item, other players will run item = dummy item) and the way i had it it removes the item for ALL players (wether its the correct item or ioon) than creates the correct item (even if it was the same item to begin with on the base players side, to prevent desync)

(btw players can pick up items and drop thats fine, i intended to go with a diablo 3-like layout)

Only have one friend online, when he gets back ill try the new vers with the count fix and the removed if and if that doesnt work im going to try copying the base item and removing the model and using that item instead of ioon
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I005 was the wrong item, i fixed it to I00N

and the if is NOT pointless, please tell me how it is always true?

if GetItemTypeId() == GetItemUserData() < only true if it was set that way
or GetItemTypeId() == 'I00N' < only true if the item is the dummy
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Its always going to be true for items with their user data set to the item I'd (which it is defaultly not) or the Dummy I still don't follow you

(and I didnt get a chance to run tests)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
JASS:
                        if GetLocalPlayer() == Player(i) then
                            set dummy = LoadInteger(Hash_t,unitId,count)
                        endif
                        set drop = CreateItem(dummy,GetUnitX(u),GetUnitY(u))
                        call SetItemUserData(drop, LoadInteger(Hash_t,unitId,count))

if GetItemTypeId(it) == GetItemUserData(it) or GetItemTypeId(it) == 'I00N' then

1) Player(i) = GetLocalPlayer()

item created = valid one
item data = valid item id
item data = item id

GetItemTypeId(it) == GetItemUserData(it) -> true
GetItemTypeId(it) == 'I00N' -> false

true or false -> true


2) Player(i) != GetLocalPlayer()

item created = dummy one
item data = valid item id
item data != item id

GetItemTypeId(it) == GetItemUserData(it) -> false
GetItemTypeId(it) == 'I00N' -> true

false or true -> true

So in both case the condition of the if is always true.
You said yourself that the result is not local, with or without the if it's just the same, expected as said if you don't want to handle all items.

I've just realized that you use the target order event, i thought you used the pickup item event, that's why you order the unit.
If the effect (remove/create item, re-order the unit) is visible in game, you could try to use the pickup item event, but maybe with this way it could desync if the item has a passive effect, or maybe not, i don't know if the effect apply is instant or not.

EDIT :

Just assume that when i hightlight something wrong in the code, it's just because i read the code, so no tests are needed, only logic, i almost never open the editor, because i need to reboot on windows, and it's boring.
I could use jasshelper in command line through wine, but meh it's even more boring ...
 
Last edited:
Level 19
Joined
Aug 8, 2007
Messages
2,765
JASS:
                        if GetLocalPlayer() == Player(i) then
                            set dummy = LoadInteger(Hash_t,unitId,count)
                        endif
                        set drop = CreateItem(dummy,GetUnitX(u),GetUnitY(u))
                        call SetItemUserData(drop, LoadInteger(Hash_t,unitId,count))

if GetItemTypeId(it) == GetItemUserData(it) or GetItemTypeId(it) == 'I00N' then

1) Player(i) = GetLocalPlayer()

item created = valid one
item data = valid item id
item data = item id

GetItemTypeId(it) == GetItemUserData(it) -> true
GetItemTypeId(it) == 'I00N' -> false

true or false -> true


2) Player(i) != GetLocalPlayer()

item created = dummy one
item data = valid item id
item data != item id

GetItemTypeId(it) == GetItemUserData(it) -> false
GetItemTypeId(it) == 'I00N' -> true

false or true -> true

So in both case the condition of the if is always true.
You said yourself that the result is not local, with or without the if it's just the same, expected as said if you don't want to handle all items.

I've just realized that you use the target order event, i thought you used the pickup item event, that's why you order the unit.
If the effect (remove/create item, re-order the unit) is visible in game, you could try to use the pickup item event, but maybe with this way it could desync if the item has a passive effect, or maybe not, i don't know if the effect apply is instant or not.

EDIT :

Just assume that when i hightlight something wrong in the code, it's just because i read the code, so no tests are needed, only logic, i almost never open the editor, because i need to reboot on windows, and it's boring.
I could use jasshelper in command line through wine, but meh it's even more boring ...

I still dont understand you... sigh...

Yes, the condition will always return true for items created by the system. Whats wrong with that? If i only make it true for !=, it will desync because im removing and creating an item locally. And i never said the result is local, i said its local because you made it local in your suggestion.

Just let me test these scenarios and ill get back to you :\
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Well, i can't be more clear.

I just said : literaly if you remove the if, but keep the actions inside, it's just the same.

But forget this, since you want an item be able to pick by any player once it's dropped, then you need this condition in order to avoid this stuff in this case.
And again as said if there are items that you don't want to handle that way.

Now, speaking about the target order event, i consider it quite lame, because if an unit targets the item, nothing forbids an other player to take it before.
The pick up item event approach would be more better (if it doesn't desync ...)
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
But forget this - Correct. not every item will be localized aswell

And ive narrowed it down to nothing! Nothing desyncs! On two screens i had 100% different items. (well it desynced when i picked up 2 stackables and they stacked on my screen and not his than i tried to pick up an item with only 1 slot left, i can get past that)

My current problem is the condition desyncs. I need to find out where thats happening. more tests!

(you can always speed it up by giving me ur bnet id)
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
doublepost, its important

So i got it working. :) (on a small-scale)

JASS:
library CustomDrop initializer init
    globals
        private hashtable Hash_t = InitHashtable()
        private location SendToItem = Location(0,0)
    endglobals
    
    private function OnDeath takes nothing returns nothing
        local unit u = GetDyingUnit()
        local integer unitId = GetUnitTypeId(u)
        local integer count = LoadInteger(Hash_t,unitId,0) // if the unit type was not registred for drop it will be equal to 0, else it will be > 0
        local real random
        local integer i
        local item drop
        local integer dummy = 'I01Q'
        
        loop // loop on all dropable item for unitID
        exitwhen count == 0 
            
            set i = 0
            loop // player loop
            exitwhen i == 11
                set dummy = 'I01Q'
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                    set random = GetRandomReal(0,100)
                    if random < LoadReal(Hash_t,unitId,count) then
                        if GetLocalPlayer() == Player(i) then
                            set dummy = LoadInteger(Hash_t,unitId,count)
                        endif
                        set drop = CreateItem(dummy,GetUnitX(u),GetUnitY(u))
                        call SetItemUserData(drop, LoadInteger(Hash_t,unitId,count))
                    endif
                endif
            set i = i+1
           endloop
     
        set count = count-1
        endloop
        set u = null
        set drop = null
    endfunction
    
    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing // chanceToDrop in percent
        local integer n = LoadInteger(Hash_t,unitId,0)
        /* integer : unitId ; 0 -> number of possible item drop for the unit type unitId
           integer : unitId ; x -> rawcode of the item to drop ; x > 0
           real : unitId ; x -> chance of the item x to drop
        */
        set n = n+1
        call SaveInteger(Hash_t,unitId,0,n)
        call SaveInteger(Hash_t,unitId,n,itemId)
        call SaveReal(Hash_t,unitId,n,chanceToDrop)
    endfunction
    private function onItemPickup takes nothing returns nothing
        local item it = GetManipulatedItem()
        local unit u = GetTriggerUnit()
        local boolean b
        local integer i = 0
        local integer i2 = 0
        local item dummy
//        set rawcode = GetItemUserData(it)
//        call RemoveItem(it)
//        set it = CreateItem(rawcode, GetUnitX(u), GetUnitY(u))
 //       call SetItemUserData(it,rawcode)
        if GetItemTypeId(it) == GetItemUserData(it) or GetItemTypeId(it) == 'I01Q' then
            call print(I2S(GetItemUserData(it)) +"                       ")
            call print(I2S(GetItemTypeId(it)) + "                       ")
            call print(I2S('I01Q') + "                       ")
            call print(R2S(GetItemX(it)) + "                       ")
            call print(R2S(GetItemY(it)) + "                       ")

            if udg_TBOOL >= 1 then
                set dummy = CreateItem(GetItemUserData(it), GetItemX(it), GetItemY(it))
                if udg_TBOOL >= 2 then
                    call RemoveItem(it)
                    if udg_TBOOL >= 3 then
                        call UnitAddItem(u,dummy)
                    endif
                endif
                set it = null
                set u = null
                return
            endif
        endif
  /*      loop
            set b = UnitItemInSlot(u, i) == null
            set i = i + 1
            exitwhen i == 5 or b == true
        endloop
        if b == true then
            call UnitAddItem(u, it)
        else
            set u = udg_Backpack[GetConvertedPlayerId(GetTriggerPlayer())]
            set i = 0
            loop
                set b = UnitItemInSlot(u, i) == null
                set i = i + 1
                exitwhen i == 6 or b == true
            endloop
            if b == true then
                call UnitAddItem(u, it)
                call print("The item has been sent to your backpack")
            else
                call print("You do not have enough room for that item")
            endif
        endif*/
    endfunction

 //    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing //
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        local trigger trig2 = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerRegisterAnyUnitEventBJ(trig2, EVENT_PLAYER_UNIT_PICKUP_ITEM  )
        call TriggerAddAction(trig,function OnDeath)
        call TriggerAddAction(trig2, function onItemPickup)
        call RegisterDrop('n000','I00U',70)
        call RegisterDrop('n000','I004',70)
        call RegisterDrop('n001','I00U',7)
        call RegisterDrop('n002','I00U',7)
        call RegisterDrop('n00H','I00U',7)
        call RegisterDrop('n00G','I00U',7)
        call RegisterDrop('n00B','I01M',10)
        call RegisterDrop('n00C','I01M',10)
        call RegisterDrop('n00D','I01M',10)
        call RegisterDrop('n003','I01M',10)
        call RegisterDrop('n005','I01N',10)
        call RegisterDrop('n009','I01N',10)
        call RegisterDrop('n007','I01O',25)
        
    endfunction
    
endlibrary

Played for about an hour. stacked items and whatnot. Gotta remove the debugs and that TBOOL stuff. Next testing phase is full house :D

e/ if your wondering "wait thats the original code".... i had an error outside the code. Thats why. :p

2e/ actually no now that i think of it the old code used I00N in the if statement even though i changed it to IO1Q

on a side note, does anyone have a non-selectable model for casting? I tried to use vexorian's dummy.mdl but is selectable. If i slap locust on it, can it still cast spells?
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
It's easy to make an animation not selectable once you've a working model, just read the link i've gave before.

So now it works without any desync, even with items which have a passive effect ? (such as aura or damage bonus)

Only works so as long as the items have the same abilities

(This can easily be fixed by changing the event from onItemPickup back to onIssuedOrder. All of my items have the same ability anyway ([clickable item]) so im too lazy to)
 
Status
Not open for further replies.
Top