| 06-21-2009, 04:57 PM | #1 |
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 : 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. |
