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

[vJASS] [Snippet] InventoryEvent

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
A system to catch a unit's inventory events.
I've been using successfully for quite some time now.
JASS:
/*****************************************************************************
*
*    InventoryEvent v1.0.1.8
*       by Bannar
*
*    For intuitive inventory event handling.
*
******************************************************************************
*
*    Requirements:
*
*       RegisterPlayerUnitEvent by Bannar
*          hiveworkshop.com/threads/snippet-registerevent-pack.250266/
*
******************************************************************************
*
*    Event API:
*
*       integer EVENT_ITEM_INVENTORY_MOVE
*       integer EVENT_ITEM_INVENTORY_USE
*
*       Use RegisterNativeEvent or RegisterIndexNativeEvent for event registration.
*       GetNativeEventTrigger and GetIndexNativeEventTrigger provide access to trigger handles.
*
*
*       function GetInventoryManipulatingUnit takes nothing returns unit
*          Returns unit which manipulated event item.
*
*       function GetInventoryManipulatedItem takes nothing returns item
*          Returns manupilated event item.
*
*       function GetInventorySlotFrom takes nothing returns integer
*          Returns slot index of manipulated item from which it was moved or used.
*
*       function GetInventorySlotTo takes nothing returns integer
*          Returns slot index of manipulated item to which it was moved.
*
*       function GetInventorySwappedItem takes nothing returns item
*          Returns item which manipulated item switched position with if any.
*
*****************************************************************************/
library InventoryEvent requires RegisterPlayerUnitEvent, ExtensionMethods

globals
    integer EVENT_ITEM_INVENTORY_MOVE
    integer EVENT_ITEM_INVENTORY_USE
endglobals

globals
    private unit eventUnit = null
    private item eventItem = null
    private integer eventSlotFrom = -1
    private integer eventSlotTo = -1
endglobals

function GetInventoryManipulatingUnit takes nothing returns unit
    return eventUnit
endfunction

function GetInventoryManipulatedItem takes nothing returns item
    return eventItem
endfunction

function GetInventorySlotFrom takes nothing returns integer
    return eventSlotFrom
endfunction

function GetInventorySlotTo takes nothing returns integer
    return eventSlotTo
endfunction

function GetInventorySwappedItem takes nothing returns item
    return UnitItemInSlot(eventUnit, eventSlotTo)
endfunction

function GetEventInventoryUnit takes nothing returns unit
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Function GetEventInventoryUnit is obsolete, use GetInventoryManipulatingUnit instead.")
    return GetInventoryManipulatingUnit()
endfunction

function GetEventInventoryItem takes nothing returns item
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Function GetEventInventoryItem is obsolete, use GetInventoryManipulatedItem instead.")
    return GetInventoryManipulatedItem()
endfunction

function GetEventInventorySlotFrom takes nothing returns integer
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Function GetEventInventorySlotFrom is obsolete, use GetInventorySlotFrom instead.")
    return GetInventorySlotFrom()
endfunction

function GetEventInventorySlotTo takes nothing returns integer
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Function GetEventInventorySlotTo is obsolete, use GetInventorySlotTo instead.")
    return GetInventorySlotTo()
endfunction

function GetEventInventorySwapped takes nothing returns item
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Function GetEventInventorySwapped is obsolete, use GetInventorySwappedItem instead.")
    return GetInventorySwappedItem()
endfunction

function GetInventoryEventTrigger takes integer whichEvent returns trigger
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Function GetInventoryEventTrigger is obsolete, use GetNativeEventTrigger instead.")
    return GetNativeEventTrigger(whichEvent)
endfunction

function RegisterInventoryEvent takes code func, integer whichEvent returns nothing
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Function RegisterInventoryEvent is obsolete, use RegisterNativeEvent instead.")
    call RegisterNativeEvent(whichEvent, func)
endfunction

private function FireEvent takes integer evt, unit u, item itm, integer slotFrom, integer slotTo returns nothing
    local unit prevUnit = eventUnit
    local item prevItem = eventItem
    local integer prevSlotFrom = eventSlotFrom
    local integer prevSlotTo = eventSlotTo
    local integer playerId = GetPlayerId(GetOwningPlayer(u))

    set eventUnit = u
    set eventItem = itm
    set eventSlotFrom = slotFrom
    set eventSlotTo = slotTo

    call TriggerEvaluate(GetNativeEventTrigger(evt))
    if IsNativeEventRegistered(playerId, evt) then
        call TriggerEvaluate(GetIndexNativeEventTrigger(playerId, evt))
    endif

    set eventUnit = prevUnit
    set eventItem = prevItem
    set eventSlotFrom = prevSlotFrom
    set eventSlotTo = prevSlotTo

    set prevUnit = null
    set prevItem = null
endfunction

private function OnItemOrder takes nothing returns nothing
    local integer order = GetIssuedOrderId()
    local unit u = GetTriggerUnit()
    local item itm
    local integer slotFrom
    local integer slotTo

    if order >= 852002 and order <= 852007 then // between moveslot1 and moveslot6
        set itm = GetOrderTargetItem()
        set slotFrom = GetUnitItemSlot(u, itm)
        set slotTo = order - 852002 // moveslot1
        call FireEvent(EVENT_ITEM_INVENTORY_MOVE, u, itm, slotFrom, slotTo)
    else
        set slotFrom = order - 852008 //  useslot1
        set itm = UnitItemInSlot(u, slotFrom)
        call FireEvent(EVENT_ITEM_INVENTORY_USE, u, itm, slotFrom, -1)
    endif

    set u = null
    set itm = null
endfunction

private function OnAnyOrder takes nothing returns nothing
    local integer order = GetIssuedOrderId()
    if order >= 852002 and order <= 852013 then // between moveslot1 and useslot6
        call OnItemOrder()
    endif
endfunction

private module InventoryEventInit
    private static method onInit takes nothing returns nothing
        set EVENT_ITEM_INVENTORY_MOVE = CreateNativeEvent()
        set EVENT_ITEM_INVENTORY_USE = CreateNativeEvent()
        set MOVED = EVENT_ITEM_INVENTORY_MOVE
        set USED = EVENT_ITEM_INVENTORY_USE

        // MOVED is order of type TARGET_ORDER yet USED can be anyone of them
        call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function OnAnyOrder)
        call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function OnAnyOrder)
        call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, function OnAnyOrder)
    endmethod
endmodule

struct InventoryEvent extends array
    // Events below are depreated in favor of EVENT_ alike globals
    readonly static integer MOVED
    readonly static integer USED

    implement InventoryEventInit
endstruct

endlibrary

Just copy test code into a map:
JASS:
scope InventoryEventDemo initializer Init

private function OnInventoryMoved takes nothing returns nothing
    local unit u = GetInventoryManipulatingUnit()
    local item itm = GetInventoryManipulatedItem()
    local item swapped = GetInventorySwappedItem()
    local integer slotFrom = GetInventorySlotFrom()
    local integer slotTo = GetInventorySlotTo()
    local string s

    if swapped != null then
        set s = GetUnitName(u) + " swapped " + GetItemName(itm) + "[" + I2S(slotFrom) + "] with "
        set s = s + GetItemName(swapped) + "[" + I2S(slotTo) + "]"
    else
        set s = GetUnitName(u) + " moved " + GetItemName(itm) + "[" + I2S(slotFrom) + "] to slot " + I2S(slotTo)
    endif

    call ClearTextMessages()
    call BJDebugMsg(s)

    set u = null
    set itm = null
    set swapped = null
endfunction

private function OnInventoryUsed takes nothing returns nothing
    local unit u = GetInventoryManipulatingUnit()
    local item itm = GetInventoryManipulatedItem()
    local integer slotFrom = GetInventorySlotFrom()

    local string s
    set s = GetUnitName(u) + " used " + GetItemName(itm) + "[" + I2S(slotFrom) + "]"

    call ClearTextMessages()
    call BJDebugMsg(s)

    set u = null
    set itm = null
endfunction

private function Callback takes nothing returns nothing
    local player p = GetLocalPlayer()
    local real x = GetCameraTargetPositionX()
    local real y = GetCameraTargetPositionY()

    // boots
    call CreateItem('bspd', x, y)
    // crystall ball
    call CreateItem('crys', x, y)
    // inferno
    call CreateItem('infs', x, y)
    // claws of attack
    call CreateItem('ratc', x, y)

    call SelectUnit(CreateUnit(p, 'Hpal', x, y, 0), true)

    call DestroyTimer(GetExpiredTimer())
endfunction

private function Init takes nothing returns nothing
    call RegisterNativeEvent(EVENT_ITEM_INVENTORY_MOVE, function OnInventoryMoved)
    call RegisterNativeEvent(EVENT_ITEM_INVENTORY_USE, function OnInventoryUsed)
    call TimerStart(CreateTimer(), 1, false, function Callback)
endfunction

endscope
 
Last edited:

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
@BPower This has been probably known for years.
This snippet itself is 2 years old.

Offtopic:
What, someone posted thread on my behalf? :D Dam those new features. One could imagen crazy things mods can do with these ^)^

Back to the topic:
Made this for Island Troll Tribes refactor which hasn't made it to battle.net (yet?).
Can upload few examples of usage, if people are willing to see those.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Updated from 1.0.0.0 to 1.0.1.2:

Library has been changed from method-based to function-based.
Now wurst friendly:
- Removal of TriggerRegisterVariableEvent and related globals. Those have been replaced by direct TriggerEvaluate calls
- Removed TriggerRegisterInventoryEvent function

GetInventoryEventTrigger deprecated in favour of GetNativeEventTrigger.
RegisterInventoryEvent deprecated in favour of RegisterNativeEvent.
Added debug messages to inform user of said deprecation.

GetUnitItemSlot function has been moved to ExtensionMethods.
Improved documentation and code readability.
Updated demo code.
 
Last edited:

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Deprecation train continues.

Inventory.MOVED and Inventory.USED have reserved their own cart in said train.
As of now EVENT_ITEM_INVENTORY_MOVE and EVENT_ITEM_INVENTORY_USE instead.

Following functions have been deprecated:
- GetEventInventoryUnit in favor of GetInventoryManipulatingUnit
- GetEventInventoryItem in favor of GetInventoryManipulatedItem
- GetEventInventorySlotFrom in favor of GetInventorySlotFrom
- GetEventInventorySlotTo in favor of GetInventorySlotTo
- GetEventInventorySwapped in favor of GetInventorySwapppedItem

Reasoning: event API unification and readability improvements.

As in other cases, obsolete members are schedules for removal when 3-6 months deprecation period ends.
 
Last edited:
Top