• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

dropitem order location

Level 5
Joined
Jun 19, 2018
Messages
43
Is it even possible to get the location of an order to drop an item in the latest warcraft 3 patch?
No you can't catch it with EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER
 
I believe this was always a thing with EVENT_PLAYER_UNIT_DROP_ITEM
then it goes with this to get the item location of the dropped item ___ = GetItemLoc(GetLastRemovedItem())
Not only EVENT_PLAYER_UNIT_DROP_ITEM fires when the order is already finished, not when it is ordered, but also it fires before the item is actually dropped and therefore shows previous location. But yes it is possible to get dropped item location when the item is already on the ground.
 
I can confirm, neither player_unit nor unit_ orders are fired when you drop an item.
In the other thread they suggest a polling method: https://www.hiveworkshop.com/threads/drop-item.167300/ & confirm your question: What is the event to detect item drop order?

Item pickup is a smart order with target widget being the item.
Thanks for clarifying, I actually tried approaching this with a more event-driven pattern (mouse → next-frame order check → drop event), mainly to avoid continuous polling.

It works surprisingly well in small-scale testing, but I’m still not fully convinced how reliable it is at scale or under heavier load (especially with multiple players issuing actions simultaneously xd).

Still experimenting here, so I appreciate the perspective:


:ugly:Found the issue: It’s not a coordinate recalculation bug(as i thought)

EVENT_PLAYER_MOUSE_DOWN also fires on UI interactions (inventory/skill frames), but those events do not represent a valid world click I suppose

So BlzGetTriggerPlayerMouseX/Y() is sometimes reading stale or non-world-projected values when UI is clicked, which made it look like coordinates were being “re-locked” or recalculated incorrectly, I'll see what I can do with this.

.....Okay so they did not separate the world and UI click are you kidding me......Is UI a transparent sticker atp ?

vJASS:
library DreadguardDrop initializer Init

    globals
        private hashtable hash = InitHashtable()
        private string COL_INTENT  = "|cffff0000" // Red
        private string COL_CONFIRM = "|cff00ffff" // Blue
        private string COL_DREAD   = "|cff32cd32" // Blight Green
 
        private group tempGroup = CreateGroup()
        private unit testHero   = null
    endglobals

    private function OnItemEject takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local integer uid = GetHandleId(u)
        if HaveSavedReal(hash, uid, 1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 10, COL_DREAD + "[DREADGUARD]:|r Item hit the ground!")
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 10, COL_CONFIRM + "X: " + R2S(LoadReal(hash, uid, 1)) + " | Y: " + R2S(LoadReal(hash, uid, 2)))
            call FlushChildHashtable(hash, uid)
        endif
        set u = null
    endfunction

    private function CheckOrderFrame takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer tid = GetHandleId(t)
        local unit u = LoadUnitHandle(hash, tid, 1)
        local integer uid = GetHandleId(u)
        local integer order = GetUnitCurrentOrder(u)

        if order >= 852001 and order <= 852007 then
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, COL_INTENT + "[INTENT]|r Locking coordinates...standby...")
            call SaveReal(hash, uid, 1, LoadReal(hash, tid, 2))
            call SaveReal(hash, uid, 2, LoadReal(hash, tid, 3))
        endif

        call FlushChildHashtable(hash, tid)
        call DestroyTimer(t)
        set t = null
        set u = null
    endfunction

    private function OnMouseClick takes nothing returns nothing
        local timer t
        local integer tid
        local player p = GetTriggerPlayer()
        local unit selected = null
 
        if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_LEFT then
            call GroupEnumUnitsSelected(tempGroup, p, null)
            set selected = FirstOfGroup(tempGroup)
            call GroupClear(tempGroup)

            if selected != null then
                set t = CreateTimer()
                set tid = GetHandleId(t)
                call SaveUnitHandle(hash, tid, 1, selected)
                call SaveReal(hash, tid, 2, BlzGetTriggerPlayerMouseX())
                call SaveReal(hash, tid, 3, BlzGetTriggerPlayerMouseY())
                call TimerStart(t, 0.00, false, function CheckOrderFrame)
            endif
        endif
 
        set t = null
        set p = null
        set selected = null
    endfunction

    private function DelayedSetup takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local player p = Player(0)
 
        call DestroyTimer(t)
        set t = null
 
        set testHero = CreateUnit(p, 'Usyl', 0, 0, 270)
        call SelectUnitForPlayerSingle(testHero, p)
        call UnitAddItemById(testHero, 'phea')
 
        call DisplayTimedTextToPlayer(p, 0, 0, 30, COL_DREAD + "DREADGUARD SYSTEM READY.|r")
        call DisplayTimedTextToPlayer(p, 0, 0, 30, "Right-click item -> Left-click, drop it like it's hot!")
 
        set p = null
    endfunction

    private function Init takes nothing returns nothing
        local trigger m = CreateTrigger()
        local trigger d = CreateTrigger()
        local integer i = 0
 
        loop
            exitwhen i > 12
            call TriggerRegisterPlayerEvent(m, Player(i), EVENT_PLAYER_MOUSE_DOWN)
            set i = i + 1
        endloop
 
        call TriggerAddAction(m, function OnMouseClick)
        call TriggerRegisterAnyUnitEventBJ(d, EVENT_PLAYER_UNIT_DROP_ITEM)
        call TriggerAddAction(d, function OnItemEject)
 
        call TimerStart(CreateTimer(), 0.50, false, function DelayedSetup)
 
        // Final nulling
        set m = null
        set d = null
    endfunction

endlibrary


UPDATED: We'll call this (f) DropItLikeItsTransparent:

Code:
library DreadguardDrop initializer Init

    globals
        private string COL_CONFIRM = "|cff00ffff" // Blue
        private string COL_DREAD   = "|cff32cd32" // Blight Green
        private unit testHero      = null
    endglobals

 
    private function OnItemEject takes nothing returns nothing
        local item i = GetManipulatedItem()
        // We read X and Y after the item has been declared the 'Manipulated Item'
        local real x = GetItemX(i)
        local real y = GetItemY(i)
       
       
        if i != null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 10, COL_DREAD + "[DREADGUARD]:|r Drop Event Validated.")
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 10, COL_CONFIRM + "World Coordinates -> X: " + R2S(x) + " | Y: " + R2S(y))
        endif

        set i = null
    endfunction


    private function DelayedSetup takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local player p = Player(0)
        call DestroyTimer(t)
        set t = null
       
        set testHero = CreateUnit(p, 'Usyl', 0, 0, 270)
        call SelectUnitForPlayerSingle(testHero, p)
        call UnitAddItemById(testHero, 'phea')
       
        call DisplayTimedTextToPlayer(p, 0, 0, 30, COL_DREAD + "DREADGUARD SYSTEM: Drop it like it's transparent.|r")
        set p = null
    endfunction

    private function Init takes nothing returns nothing
        local trigger d = CreateTrigger()
       
       
        call TriggerRegisterAnyUnitEventBJ(d, EVENT_PLAYER_UNIT_DROP_ITEM)
        call TriggerAddAction(d, function OnItemEject)
       
        call TimerStart(CreateTimer(), 0.50, false, function DelayedSetup)
        set d = null
    endfunction

endlibrary

Not ideal if you need pre-drop intent, but solid if you just need the final location.

Argh, I really wanted this to be pre-event driven :’)))
 
Last edited:
Back
Top