HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Unit Drops item but item still counted as being in slot

05-14-2007, 04:35 AM#1
hobo
I'm having a interesting result from this trigger.

Collapse JASS:
function Trig_VisionItem_Conditions takes nothing returns boolean
return ( GetItemTypeId(GetManipulatedItem()) == 'clsd' ) 
endfunction

function Trig_VisionItem_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local boolean b = UnitHasItemOfTypeBJ(u,'clsd')
local player p = GetTriggerPlayer()
local integer i = 0

    
    loop
     exitwhen i>11
     if not IsPlayerAlly(p,Player(i)) then
        call UnitShareVision( u, Player(i), b )
     endif         
     set i=i+1
    endloop
    
    set u = null
endfunction

//===========================================================================
function InitTrig_VisionItem takes nothing returns nothing
    set gg_trg_VisionItem = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_VisionItem, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_VisionItem, EVENT_PLAYER_UNIT_DROP_ITEM )
    call TriggerAddCondition( gg_trg_VisionItem, Condition( function Trig_VisionItem_Conditions ) )
    call TriggerAddAction( gg_trg_VisionItem, function Trig_VisionItem_Actions )
endfunction

As you can see if a unit gets or loses this item the trigger checks to see if the unit has the item then then passes that boolean result as whether vision is shared with enemy players or not.

Apparently when a unit drops an item it is still considered to be in the slot.

I tried writing my own replacement for UnitHasItemOfTypeBJ()

Collapse JASS:
function UnitHasVisionItem takes unit u returns boolean
    local integer i = 0

    loop
        exitwhen i > 5
        call  
        if GetItemTypeId(UnitItemInSlot(u, i))== 'clsd' then
            return true
        endif
        set i = i + 1
    endloop
    return false
endfunction

But got the same result. Anyone know what I'm missing here? I can't just do units drops item then share vision = false in case the unit has 2 of the items, I could use arrays to zero sum the item picked up and item dropped orders but that is WAY inelegant. Whats up with UnitHasItemOfTypeBJ() = true on a unit drops item event.
05-14-2007, 04:55 AM#2
MaD[Lion]
also there is another case. When you drop an item from hero, then do a remove on it. It will trigger the unit lose item event twice
05-14-2007, 05:18 AM#3
Vexorian
hobo: This is the reason we got so used to 0 seconds timers.
05-14-2007, 05:23 AM#4
hobo
Thanks MadLion, knowing your adversary is important in battle.

So I pondered this problem for a while before posting and, wouldn't you know it, I solved it not an hour after posting!

Here ya go:

Collapse JASS:
function Trig_VisionItem_Conditions takes nothing returns boolean
return ( GetItemTypeId(GetManipulatedItem()) == 'clsd' ) 
endfunction

function Trig_VisionItem_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer i = 0
local integer j = 1
local boolean b = false
local player p = GetTriggerPlayer()

    if GetTriggerEventId()== EVENT_PLAYER_UNIT_DROP_ITEM then
        set j = 0
    endif
    
    loop
        exitwhen i > 5    
        if GetItemTypeId(UnitItemInSlot(u, i))== 'clsd' then
            set j = j+1
        endif
        if j > 1 then
            set b = true
        endif
        set i = i+1
    endloop

if b then // delete me, you know you want to...
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"picked up Vision Item")
else
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"dropped Vision Item")
endif
 
    set i = 0   
    loop
     exitwhen i>11
     if not IsPlayerAlly(p,Player(i)) then
        call UnitShareVision( u, Player(i), b )
     endif         
     set i=i+1
    endloop
    
    set u = null
endfunction

//===========================================================================
function InitTrig_VisionItem takes nothing returns nothing
    set gg_trg_VisionItem = CreateTrigger(  )
call TriggerRegisterPlayerSelectionEventBJ( gg_trg_VisionItem, Player(0), true )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_VisionItem, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_VisionItem, EVENT_PLAYER_UNIT_DROP_ITEM )
    call TriggerAddCondition( gg_trg_VisionItem, Condition( function Trig_VisionItem_Conditions ) )
    call TriggerAddAction( gg_trg_VisionItem, function Trig_VisionItem_Actions )
endfunction

Even got rid of that extra function call for the boolean.

Vex: I tried TriggerSleepAction(0) but it had no effect, please enlighten me as to 0 second timer solving this, I would be very happy
05-14-2007, 11:10 AM#5
MaD[Lion]
ye, or we can use 0 sec timer ;)
05-15-2007, 05:41 AM#6
hobo
Quote:
Originally Posted by MaD[Lion]
ye, or we can use 0 sec timer ;)

Don't suppose you're gonna tell me how that works? Vexorian dropped a hint about it too but neither of you seem to want to actually tell me. Do I start a 0 second timer and run another function on expiration? If so wouldn't I need to pass all the data to that function via a struct?
05-18-2007, 12:04 AM#7
hobo
...is bad kids. Don't do it, EVER. Not even to bump a thread rather than creating a whole new one. Now you know, and knowing's half the battle!
05-21-2007, 12:19 AM#8
Get Undeniable Interest
[SHOCK HORROR] DOUBLE POSTING! Then why did you double post?[/SHOCK HORROR]
05-22-2007, 10:50 PM#9
hobo
I did it to bump the thread. Still haven't figured out the use of a 0 second timer, and no one has seen fit to inform me.