HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Items events, need feedbacks

06-21-2009, 04:57 PM#1
Troll-Brain
Collapse JASS:
library IE initializer init uses TimerUtils // ItemEvents

private function interface JustAfunction takes nothing returns nothing

globals
    private constant real GIVE_ITEM_RANGE = 150. // in the constant interface, this is the default value
endglobals

globals
    constant integer IE_EVENT_PLAYER_UNIT_PUT_ITEM = 1 // when an unit put an item on the floor
    constant integer IE_EVENT_PLAYER_UNIT_GIVE_ITEM = 2 // when an unit give the item to an other unit
    constant integer IE_EVENT_PLAYER_UNIT_FINISH_ITEM = 3 // when the item is destroyed (last charge) or sold
   
    // for completness reason, they are just basically the native ones
    constant integer IE_EVENT_PLAYER_UNIT_USE_ITEM = 4
    constant integer IE_EVENT_PLAYER_UNIT_PICKUP_ITEM = 5
    constant integer IE_EVENT_PLAYER_UNIT_DROP_ITEM = 6
    constant integer IE_EVENT_PLAYER_UNIT_SELL_ITEM = 7
    constant integer IE_EVENT_PLAYER_UNIT_PAWN_ITEM = 8
endglobals

// don't edit below this line

//! runtextmacro t_IE_Globals("PUT")
//! runtextmacro t_IE_Globals("GIVE")
//! runtextmacro t_IE_Globals("FINISH")
//! runtextmacro t_IE_Globals("USE")
//! runtextmacro t_IE_Globals("PICKUP")
//! runtextmacro t_IE_Globals("DROP")
//! runtextmacro t_IE_Globals("SELL")
//! runtextmacro t_IE_Globals("PAWN")

globals
    private integer Index = -1
    private group Grp
    private unit U = null
    private item Ite = null
    private item Item = null
    private unit Unit = null
    private integer ItemEvent = 1337
    private integer ItemTypeId = 0
endglobals

private struct s_data
    item ite
    integer itemId
    
    static method create takes item ite returns s_data
        local thistype this = .allocate()
        set .ite = ite
        set .itemId = GetItemTypeId(ite)
        return this
    endmethod
    
    method onDestroy takes nothing returns nothing
        set .ite = null
        set U = null
        set Ite = null
        set . itemId = 0
    endmethod
endstruct

// maybe i should add some debugs for these 2 functions below, but it's really boring to make much more code just to prevent people being dumb

function GetTriggerItem takes nothing returns item // this is not multi instanciable by itself you must use a local if you want to use a wait
    return Item
endfunction

function GetTriggerItemTypeId takes nothing returns integer // this is not multi instanciable by itself you must use a local if you want to use a wait
    return ItemTypeId
endfunction

function IE_RemoveThisAction takes nothing returns boolean
    local eventid evd = GetTriggerEventId()
    
    //! runtextmacro IE_HandleRemoveActions("DROP")
    //! runtextmacro IE_HandleRemoveActions("PAWN")
    //! runtextmacro IE_HandleRemoveActions("PICKUP")
    //! runtextmacro IE_HandleRemoveActions("SELL")
    //! runtextmacro IE_HandleRemoveActions("USE")
    debug call BJDebugMsg("you try to use IE_RemoveThisAction with a wrong event")
    return false
endfunction

function AddGenericItemEvent takes integer whichPlayerUnitItemEvent , JustAfunction whichFunction returns boolean
    
    if whichFunction == 0 then
        debug call BJDebugMsg("whichFunction of the function AddGenericItemEvent is not valid (==0)")
        return false
    endif
    
    // classic events
    //! runtextmacro IE_AddEvents("PUT")
    //! runtextmacro IE_AddEvents("GIVE")
    //! runtextmacro IE_AddEvents("FINISH")
    //! runtextmacro IE_AddEvents("USE")
    //! runtextmacro IE_AddEvents("PICKUP")
    //! runtextmacro IE_AddEvents("DROP")
    //! runtextmacro IE_AddEvents("SELL")
    //! runtextmacro IE_AddEvents("PAWN")
    
    // custom events
    
    
    //debug call BJDebugMsg("whichPlayerUnitItemEvent of the function AddGenericItemEvent is not valid") 
    return false
endfunction

private function FilterOwners takes nothing returns boolean
    if UnitHasItem(GetFilterUnit(),Ite) then
        set U = GetFilterUnit()
    endif
    return false
endfunction

private function DetectWhatKindOfDrop takes nothing returns nothing
    local s_data s = GetTimerData(GetExpiredTimer())
    
    set Ite = s.ite
    set ItemTypeId = s.itemId
    call GroupEnumUnitsInRange(Grp,GetItemX(Ite),GetItemY(Ite),GIVE_ITEM_RANGE,Filter(function FilterOwners))
    
    if U != null then // the item was given to an other unit
        set ItemEvent = 2
        set Item = Ite
        set Unit = U
        set Index = GIVEmaxArray
        loop
        exitwhen Index < 0
            call GIVEactions[Index].execute()
            set Index = Index-1
        endloop
    
    elseif GetWidgetLife(Ite) <= 0.405 then // the item is dead
        set ItemEvent = 3
        set Item = null
        set Unit = null
        set Index = FINISHmaxArray
        loop
        exitwhen Index < 0
            call FINISHactions[Index].execute()
            set Index = Index-1
        endloop
        call RemoveItem(Ite) // for books and such items
        
    // the item is on the floor
    else
        set ItemEvent = 1
        set Item = Ite
        set Unit = null
        set Index = PUTmaxArray
        loop
        exitwhen Index < 0
            call PUTactions[Index].execute()
            set Index = Index-1
        endloop
    endif
    
    set ItemEvent = 1337
    call ReleaseTimer(GetExpiredTimer())
    call s.destroy()
endfunction

private function Actions takes nothing returns nothing
    local eventid evd = GetTriggerEventId()
    local timer tim = null
    
    set Item = GetManipulatedItem()
    // classic events
    //! runtextmacro IE_HandleEvents("DROP")
    set ItemEvent = 6
    //! runtextmacro IE_HandleEvents("PAWN")
    set ItemEvent = 8
    //! runtextmacro IE_HandleEvents("PICKUP")
    set ItemEvent = 5
    //! runtextmacro IE_HandleEvents("SELL")
    set ItemEvent = 7
    //! runtextmacro IE_HandleEvents("USE")
    set ItemEvent = 4
    
    
    // custom events
    if evd == EVENT_PLAYER_UNIT_DROP_ITEM then
        set tim = NewTimer()
        call SetTimerData(tim,s_data.create(GetManipulatedItem()))
        call TimerStart(tim,0.,false,function DetectWhatKindOfDrop)
    endif
    set Index = -1
endfunction

//! textmacro t_IE_Globals takes NAME
    globals
        private JustAfunction array $NAME$actions
        private integer $NAME$maxArray = -1
    endglobals
//! endtextmacro

//! textmacro IE_HandleEvents takes NAME
    if evd == EVENT_PLAYER_UNIT_$NAME$_ITEM then
        set Index = $NAME$maxArray
        loop
        exitwhen Index < 0
            call $NAME$actions[Index].execute()
            set Index = Index-1
        endloop
    endif
//! endtextmacro

//! textmacro IE_HandleRemoveActions takes NAME
    if evd == EVENT_PLAYER_UNIT_$NAME$_ITEM then
        
        if Index == -1 then
            debug call BJDebugMsg("You try to use IE_RemoveThisAction after a wait or with a wrong function")
            return false
        endif
    
    if Index != $NAME$maxArray then
            set $NAME$actions[Index] = $NAME$actions[$NAME$maxArray]
        endif
        set $NAME$actions[$NAME$maxArray] = 0
        set $NAME$maxArray = $NAME$maxArray - 1
    return true    
    endif
//! endtextmacro

//! textmacro IE_AddEvents takes NAME
    if whichPlayerUnitItemEvent == IE_EVENT_PLAYER_UNIT_$NAME$_ITEM then
        set $NAME$maxArray = $NAME$maxArray + 1
        set $NAME$actions[$NAME$maxArray] = whichFunction
        return true
    endif
//! endtextmacro

private function init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_DROP_ITEM)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_PAWN_ITEM)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SELL_ITEM)
    call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_USE_ITEM)
    call TriggerAddAction(trig,function Actions)
    set Grp = CreateGroup()
endfunction

endlibrary

Well, this is the first system i've made that i'm sure i will use,
In fact i just need the "GIVE" and "PUT" events, i've made the rest for completeness reason.
I will use it for make an easy "system" to handle item owners (if an unit put the item on the floor, only the previous owner can take them, but not if an unit give it to an other one, i will also handle leavers, and so one ...)

So the question is :
Does it sounds enough interesting to make a documentation and release it in the submissions, or in other words would you use it ?

Ofc as usual, all constructive comments of the code itself are welcome.

EDIT : A short fast code to test the events :

Collapse JASS:
//! runtextmacro t_test("PUT")
//! runtextmacro t_test("GIVE")
//! runtextmacro t_test("FINISH")
//! runtextmacro t_test("USE")
//! runtextmacro t_test("PICKUP")
//! runtextmacro t_test("DROP")
//! runtextmacro t_test("SELL")
//! runtextmacro t_test("PAWN")

//! textmacro t_test takes NAME

scope s$NAME$ initializer init

private function $NAME$ takes nothing returns nothing
    call BJDebugMsg(" ")
    call BJDebugMsg("an item is $NAME$")
    call BJDebugMsg(GetItemName(GetTriggerItem()))
    call BJDebugMsg(I2S(GetTriggerItemTypeId()))
endfunction

private function init takes nothing returns nothing
    call AddGenericItemEvent(IE_EVENT_PLAYER_UNIT_$NAME$_ITEM,$NAME$)
endfunction

endscope
//! endtextmacro

EDIT2 : The code is not fully finished btw, it might be have some bugs to fixed, add more debugs and features like UNIT and PLAYER_UNIT events instead of simply "generic" unit event.