• 🏆 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] ItemEvent

Level 5
Joined
Mar 15, 2017
Messages
96
This adds new functions and events on Items.

NOTE:
If there are any moderators reading this thread,
please delete this, I abandoned this thread.
Because only blizzard can make "Item enters region/map"
function..
vJASS:
library ItemEvent /* v1.1.3
****************************************************************************************************
*                                      _____________________
*                                      *     ItemEvent     *
*                                      * By: BloodForBlood *
*                                      ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*   */requires/*
*
*       */ optional Table /*
*           - https://www.hiveworkshop.com/threads/snippet-new-table.188084/
*       */ optional TimerUtils /*
*           - http://www.wc3c.net/showthread.php?t=101322
*
*   What is ItemEvent:
*       It adds new functions and events to items.
*       The two new events can be used to create
*       item indexer or any else.
*
*   Features:
*       Lightweight
*       Leakless(Maybe)
*       Bugless(Maybe)
*       Fixed runes death still showing small models
*
****************************************************************************************************
*   Configurations:                                                                               */
        globals
            private constant real REMOVE_DELAY = 1.00  // The delay of item removal
                                                       // on death.
/***************************************************************************************************
*
*   EVENT:
*       function RegisterItemEnterEvent takes code c returns nothing
*       - Adds item enters the map event
*           c: The function you want to run when the event get executed
*
*       function RegisterItemLeavEvent takes code c returns nothing
*       - Adds item leaves the map event
*           c: The function you want to run when the event get executed
*
*       function RegisterItemEnterEventEx takes code c returns nothing
*       - Adds item enters the map event including preplaced
*           c: The function you want to run when the event get executed
*
*   EVENT FUNCTIONS:
*       function GetEnteringItem takes nothing returns item
*       - Returns the entering item in the map
*
*       function GetLeavingItem takes nothing returns item
*       - Returns the leaving item from the map
*
*       function GetEnteringItemEx takes nothing returns item
*       - Used for "RegisterItemEnterEventEx"
*
*   Special Thanks to:
*       Bribe - for "NewTable"
*       Vexorian - for "TimerUtils"
*        
***************************************************************************************************/
        private item array ITEM
        private trigger array TRIG
        private trigger DEATH
    endglobals
 
    private struct Data
        static if LIBRARY_Table then
            static HashTable htb = HashTable.create
        else
            static hashtable ht = InitHashtable()
        endif
    endstruct
 
    function GetEnteringItem takes nothing returns item
        return ITEM[1]
    endfunction
 
    function GetLeavingItem takes nothing returns item
        return ITEM[2]
    endfunction
 
    function GetEnteringItemEx takes nothing returns item
        if (ITEM[3] == null) then
            return ITEM[1]
        endif
        return ITEM[3]
    endfunction
 
    function RegisterItemEnterEvent takes code c returns nothing
        call TriggerAddCondition(TRIG[1], Filter(c))
    endfunction
 
    function RegisterItemLeaveEvent takes code c returns nothing
        call TriggerAddCondition(TRIG[2], Filter(c))
    endfunction
 
    function RegisterItemEnterEventEx takes code c returns nothing
        call RegisterItemEnterEvent(c)
        call TriggerAddCondition(TRIG[3], Filter(c))
    endfunction

    private function EnterItem takes item it returns nothing
        local boolean b = false
        local item i = it
        local integer id = GetHandleId(i)
        static if LIBRARY_Table then
            set b = Data.htb[id].boolean[StringHash("IE_Entered")]
        else
            set b = LoadBoolean(Data.ht, id, StringHash("IE_Entered"))
        endif
        if (not b) then
            static if LIBRARY_Table then
                set Data.htb[id].boolean[StringHash("IE_Entered")] = true
                set Data.htb[StringHash("ItemEvent")].item[id] = i
            else
                call SaveBoolean(Data.ht, id, StringHash("IE_Entered"), true)
                call SaveItemHandle(Data.ht, StringHash("ItemEvent"), id, i)
            endif
            call TriggerRegisterDeathEvent(DEATH, i)
            set ITEM[1] = i
            call TriggerEvaluate(TRIG[1])
        endif
        set i = null
    endfunction
 
    private function onEnter takes nothing returns nothing
        local item i = GetEnumItem()
        call EnterItem(i)
        set i = null
    endfunction
 
    private function IdentifyItem takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local rect r
        local integer i = GetHandleId(t)
        static if LIBRARY_Table then
            set r = Data.htb[i].rect[StringHash("IE_Rect")]
        else
            set r = LoadRectHandle(Data.ht, i, StringHash("IE_Rect"))
        endif
        call EnumItemsInRect(r, null, function onEnter)
        static if LIBRARY_TimerUtils then
            call ReleaseTimer(t)
        else
            call DestroyTimer(t)
        endif
        call RemoveRect(r)
        set r = null
        set t = null
    endfunction
 
    private function onAquire takes nothing returns boolean
        local item i = GetManipulatedItem()
        call EnterItem(i)
        set i = null
        return false
    endfunction
 
    private function LoadItem takes real x, real y returns nothing
        local rect r = Rect(x-64, y-64, x+64, y+64)
        local timer t
        local integer i
        static if LIBRARY_TimerUtils then
            set t = NewTimer()
        else
            set t = CreateTimer()
        endif
        set i = GetHandleId(t)
        static if LIBRARY_Table then
            set Data.htb[i].rect[StringHash("IE_Rect")] = r
        else
            call SaveRectHandle(Data.ht, i, StringHash("IE_Rect"), r)
        endif
        call TimerStart(t, 0, false, function IdentifyItem)
        set r = null
        set t = null
    endfunction
 
    private function Widget2Item takes widget w returns item
        local integer i = GetHandleId(w)
        static if LIBRARY_Table then
           set ITEM[2] = Data.htb[StringHash("ItemEvent")].item[i]
        else
           set ITEM[2] = LoadItemHandle(Data.ht, StringHash("ItemEvent"), i)
        endif
        return ITEM[2]
    endfunction
 
    private function removeItem takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local item i
        local integer id = GetHandleId(t)
        static if LIBRARY_Table then
            set i = Data.htb[id].item[StringHash("IE_DeathItem")]
        else
            set i = LoadItemHandle(Data.ht, id, StringHash("IE_DeathItem"))
        endif
        call RemoveItem(i)
        set t = null
        set i = null
    endfunction
 
    private function onDeath takes nothing returns boolean
        local item i = Widget2Item(GetTriggerWidget())
        local timer t
        local integer id
        static if LIBRARY_TimerUtils then
            set t = NewTimer()
        else
            set t = CreateTimer()
        endif
        set id = GetHandleId(t)
        static if LIBRARY_Table then
            set Data.htb[id].item[StringHash("IE_DeathItem")] = i
        else
            call SaveItemHandle(Data.ht, id, StringHash("IE_DeathItem"), i)
        endif
        call TimerStart(t, REMOVE_DELAY, false, function removeItem)
        call TriggerEvaluate(TRIG[2])
        set i = null
        set t = null
        return false
    endfunction
 
    private function CreateItemHook takes integer itemid, real x, real y returns nothing
        call LoadItem(x, y)
    endfunction
 
    private function CreateItemLocHook takes integer itemId, location loc returns nothing
        call LoadItem(GetLocationX(loc), GetLocationY(loc))
    endfunction
 
    private function UnitAddItemByIdSwappedHook takes integer itemId, unit whichHero returns nothing
        if UnitInventoryCount(whichHero) == UnitInventorySize(whichHero) then
            call LoadItem(GetUnitX(whichHero), GetUnitY(whichHero))
        endif
    endfunction
 
    private function UnitAddItemByIdHook takes unit whichUnit, integer itemId returns nothing
        if UnitInventoryCount(whichUnit) == UnitInventorySize(whichUnit) then
            call LoadItem(GetUnitX(whichUnit), GetUnitY(whichUnit))
        endif
    endfunction
 
    private function UnitAddItemToSlotByIdHook takes unit whichUnit, integer itemId, integer itemSlot returns nothing
        if UnitInventoryCount(whichUnit) == UnitInventorySize(whichUnit) then
            call LoadItem(GetUnitX(whichUnit), GetUnitY(whichUnit))
        endif
    endfunction
 
    private function UnitDropItemHook takes unit inUnit, integer inItemID returns nothing
        call LoadItem(GetUnitX(inUnit), GetUnitY(inUnit))
    endfunction
 
    private function WidgetDropItemHook takes widget inWidget, integer inItemID returns nothing
        call LoadItem(GetWidgetX(inWidget), GetWidgetY(inWidget))
    endfunction
 
    hook CreateItem CreateItemHook
    hook CreateItemLoc CreateItemLocHook
    hook UnitAddItemByIdSwapped UnitAddItemByIdSwappedHook
    hook UnitAddItemById UnitAddItemByIdHook
    hook UnitAddItemToSlotById UnitAddItemToSlotByIdHook
    hook UnitDropItem UnitDropItemHook
    hook WidgetDropItem WidgetDropItemHook
 
    private function onInventory takes unit uu returns boolean
        local integer i = 0
        local unit u = uu
        local item it = null
        local integer id = 0
        local boolean b = false
        if (UnitInventorySize(u) > 0) then
            loop
                set it = UnitItemInSlot(u, i)
                if (it != null) then
                    set id = GetHandleId(it)
                    static if LIBRARY_Table then
                        set b = Data.htb[id].boolean[StringHash("IE_Entered")]
                    else
                        set b = LoadBoolean(Data.ht, id, StringHash("IE_Entered"))
                    endif
                    if (not b) then
                        static if LIBRARY_Table then
                            set Data.htb[id].boolean[StringHash("IE_Entered")] = true
                            set Data.htb[StringHash("ItemEvent")].item[id] = it
                        else
                            call SaveBoolean(Data.ht, id, StringHash("IE_Entered"), true)
                            call SaveItemHandle(Data.ht, StringHash("ItemEvent"), id, it)
                        endif
                        call TriggerRegisterDeathEvent(DEATH, it)
                        set ITEM[3] = it
                        call TriggerEvaluate(TRIG[3])
                        set ITEM[3] = null
                    endif
                endif
                set i = i + 1
                exitwhen i > UnitInventorySize(u)
            endloop
        endif
        set u = null
        set it = null
        return false
    endfunction
 
    private function addPreplaced takes nothing returns nothing
        local item i = GetEnumItem()
        local boolean b = false
        local integer id = GetHandleId(i)
        static if LIBRARY_Table then
            set b = Data.htb[id].boolean[StringHash("IE_Entered")]
        else
            set b = LoadBoolean(Data.ht, id, StringHash("IE_Entered"))
        endif
        if (not b) then
            static if LIBRARY_Table then
                set Data.htb[id].boolean[StringHash("IE_Entered")] = true
                set Data.htb[StringHash("ItemEvent")].item[id] = i
            else
                call SaveBoolean(Data.ht, id, StringHash("IE_Entered"), true)
                call SaveItemHandle(Data.ht, StringHash("ItemEvent"), id, i)
            endif
            call TriggerRegisterDeathEvent(DEATH, i)
            set ITEM[3] = i
            call TriggerEvaluate(TRIG[3])
            set ITEM[3] = null
        endif
        set i = null
    endfunction
 
    private function InitPreplaced takes nothing returns nothing
        local rect r = GetWorldBounds()
        local group g = CreateGroup()
        local unit u
        call EnumItemsInRect(r, null, function addPreplaced)
        static if LIBRARY_TimerUtils then
            call ReleaseTimer(GetExpiredTimer())
        else
            call DestroyTimer(GetExpiredTimer())
        endif
        call GroupEnumUnitsInRect(g, r, null)
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            call GroupRemoveUnit(g, u)
            call onInventory(u)
        endloop
        call RemoveRect(r)
        call DestroyGroup(g)
        set r = null
        set g = null
    endfunction
 
    private module m
        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            set TRIG[1] = CreateTrigger()
            set TRIG[2] = CreateTrigger()
            set TRIG[3] = CreateTrigger()
            set DEATH = CreateTrigger()
            static if LIBRARY_TimerUtils then
                call TimerStart(NewTimer(), 0, false, function InitPreplaced)
            else
                call TimerStart(CreateTimer(), 0, false, function InitPreplaced)
            endif
            call TriggerAddCondition(DEATH, Condition(function onDeath))
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
            call TriggerAddCondition(t, Condition(function onAquire))
            set t = null
        endmethod
    endmodule
 
    private struct s
        implement m
    endstruct
 
endlibrary

Here's a demo on how to use it:
vJASS:
scope Demo initializer Init
 
    private function Enter takes nothing returns nothing
        local item i = GetEnteringItem() // Getting the entering item
        call DisplayTimedTextToPlayer(Player(0), 0, 0, 3, GetItemName(i) + " entered the map")
        set i = null
    endfunction
 
    private function Leave takes nothing returns nothing
        local item i = GetLeavingItem() // Getting the leaving item
        call DisplayTimedTextToPlayer(Player(0), 0, 0, 3, GetItemName(i) + " leaved the map.")
        set i = null
    endfunction
 
    private function Init takes nothing returns nothing
        call RegisterItemLeaveEvent(function Leave) // Registers leave event to the function
        call RegisterItemEnterEvent(function Enter) // Registers enter event to the function
    endfunction
 
endscope
 
Last edited:

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
This snippet contains superior version of your extension methods. Such functions belong to small code snippet - that's why I'm currently not releasing said pastebin.
No module initializer breaks compatibility with other systems.
This snippet will fail when item drops off mob.
Should be using InventoryEvent and RegisterPlayerUnitEvent if ever to approve - code duplication.
UnitInventoryCount should be removed, as well as spam GetHandleId replaced with locals.
Such snippets were already submitted on this forum, yet all rejected due to holes and issues that cannot be easily fixed without Blizzard intervention.

Due to fact that this is not the first attempt, and all others were graveyarded, I vote for graveyard.
 
Last edited:
Level 5
Joined
Mar 15, 2017
Messages
96
This snippet contains superior version of your extension methods. Such functions belong to small code snippet - that's why I'm currently not releasing said pastebin.
No module initializer breaks compatibility with other systems.
This snippet will fail when item drops off mob.
Should be using InventoryEvent and RegisterPlayerUnitEvent if ever to approve - code duplication.
UnitInventoryCount should be removed, as well as spam GetHandleId replaced with locals.
Such snippets were already submitted on this forum, yet all rejected due to holes and issues that cannot be easily fixed without Blizzard intervention.

Due to fact that this is not the first attempt, and all others were graveyarded, I vote for graveyard.
Thanks for your opinion..But you can't blame me,I have learned vJASS only at this year,I don't have
more experiences at vJASS.
 
Last edited:

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Additionally to what Bannar said:

You should use better names for your variables. ht or t are not good names for global variables.
Instead name them for what you want to use them.
The arrays are not really used like one would usually use an array. In that case it is better to use non-array variables and name them depending on their purpose.
e.g. ITEM -> triggerItem or eventItem
t[0] is the trigger that detects when item leave the map. Call it leaveTrigger or similar, so everyone can immediatly see what the variable is used for.
Good variable names make your code more readable and helps people who don't know the code to understand it faster.

You often use StringHash("IE_Added") to get a unique id.
You said you are new to vJASS, so you probably don't know, that you can use keys for that purpose.
A key generates a unique integer constant. Using an integer would not require the game to use the StringHash function.

JASS:
private function setDeathItem takes nothing returns boolean
        set ITEM[1] = ht[StringHash("ItemEvent")].item[GetHandleId(GetTriggerWidget())]
        return false
endfunction
What is the purpose of using the hashtable to get the item? GetTriggerWidget() would return the item as well or am I missing something?

In Init2 the timer should be destroyed in both cases.

What is the reason for RemoveItemHook to trigger a real variable event instead of simply calling the function attached to the trigger with the real variable event.
I don't see where EVENT_ITEM is set to 2. Why is there a real variable event EVENT_ITEM == 2, if you never set it to 2?

You should think about changing the way you execute the user defined code on your events.
In the leave event ITEM[1] is first set. After that all user defined code will be executed.
If the user defined code removes an item, ITEM[1] will be overwritten.
Take a look at Bannar's SmoothitemPickup: [vJASS] - SmoothItemPickup
In the function FireEvent the old event variables are stored. Then the new event variables are set and the user defined code for the new event is executed. After the new event is finished the event variables are reverted to the old event variables, as the old event will now continue.

In the end the issue with such item systems remains. You cannot detect when the item enters the map. This system uses a periodic timer and item enumeration to add events items very quickly. It is not instant, so it will not always work. Periodic timer with item enumeration is also bad for the performance of the map.
 
Level 5
Joined
Mar 15, 2017
Messages
96
Additionally to what Bannar said:

You should use better names for your variables. ht or t are not good names for global variables.
Instead name them for what you want to use them.
The arrays are not really used like one would usually use an array. In that case it is better to use non-array variables and name them depending on their purpose.
e.g. ITEM -> triggerItem or eventItem
t[0] is the trigger that detects when item leave the map. Call it leaveTrigger or similar, so everyone can immediatly see what the variable is used for.
Good variable names make your code more readable and helps people who don't know the code to understand it faster.

You often use StringHash("IE_Added") to get a unique id.
You said you are new to vJASS, so you probably don't know, that you can use keys for that purpose.
A key generates a unique integer constant. Using an integer would not require the game to use the StringHash function.

JASS:
private function setDeathItem takes nothing returns boolean
        set ITEM[1] = ht[StringHash("ItemEvent")].item[GetHandleId(GetTriggerWidget())]
        return false
endfunction
What is the purpose of using the hashtable to get the item? GetTriggerWidget() would return the item as well or am I missing something?

In Init2 the timer should be destroyed in both cases.

What is the reason for RemoveItemHook to trigger a real variable event instead of simply calling the function attached to the trigger with the real variable event.
I don't see where EVENT_ITEM is set to 2. Why is there a real variable event EVENT_ITEM == 2, if you never set it to 2?

You should think about changing the way you execute the user defined code on your events.
In the leave event ITEM[1] is first set. After that all user defined code will be executed.
If the user defined code removes an item, ITEM[1] will be overwritten.
Take a look at Bannar's SmoothitemPickup: [vJASS] - SmoothItemPickup
In the function FireEvent the old event variables are stored. Then the new event variables are set and the user defined code for the new event is executed. After the new event is finished the event variables are reverted to the old event variables, as the old event will now continue.

In the end the issue with such item systems remains. You cannot detect when the item enters the map. This system uses a periodic timer and item enumeration to add events items very quickly. It is not instant, so it will not always work. Periodic timer with item enumeration is also bad for the performance of the map.
Well,you're right..I'm not good at vJASS,LOLS.But you can set the PERIODIC to 0.001 or 0 (LOL) if you wan't to..But this should be only used at small maps maybe :/
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Well,you're right..I'm not good at vJASS,LOLS
You are still new to vJASS so you cannot expect to be good yet. Practice and feedback will help you improve.

But you can set the PERIODIC to 0.001 or 0 (LOL) if you wan't to..But this should be only used at small maps maybe :/
Even a 0 second delay would not be instant.

Consider the following situation. I use the enter event to give all items a random number between 0 and 100. This number can be attached with table for example.

When I create an item, I want that this number exists right after the item was created, so it can be used instantly.
JASS:
local item itm = CreateItem(...)
//the item enter event should now fire, so the registered code already ran
if table[GetHandleId(itm)] < 25 then
    call RemoveItem(itm)
endif

The idea is, that a created item has a chance to be removed.

With the timer, the number will be attached only after the code has run.

Unfortunately it is not possible to create an enter event for items.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
I don't get it..
It was an example that showcases, why it is important that the event is instant.

The enter event is used to attach an integer to the entering item.

When an item is created one expects the enter event to trigger immediatly.
JASS:
local item itm = CreateItem(...)
//the item enter event should now fire
//due to the timer this is not the case and table[GetHandleId(itm)].integer is not set yet
//as a result the following code will not work as intended
if table[GetHandleId(itm)].integer < 25 then
    call RemoveItem(itm)
endif

You can't convert widget to item..
Thanks for the information. Yeah makes sense.
 
Level 5
Joined
Mar 15, 2017
Messages
96
It was an example that showcases, why it is important that the event is instant.

The enter event is used to attach an integer to the entering item.

When an item is created one expects the enter event to trigger immediatly.
JASS:
local item itm = CreateItem(...)
//the item enter event should now fire
//due to the timer this is not the case and table[GetHandleId(itm)].integer is not set yet
//as a result the following code will not work as intended
if table[GetHandleId(itm)].integer < 25 then
    call RemoveItem(itm)
endif


Thanks for the information. Yeah makes sense.
Well,the only way is to use hooks, and unit aquires item.
I don't blame you. In contrary, I respect every submitter and because I do, I give honest review.
Whatmore, I'm glad new peps still show up these days ;*

Well,the only way is to use hooks, and unit aquires item.
Edit: UPDATED!
Removed a lot of stupidity
All requirements are optional
Removed Timer Requirement
 
Last edited:

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
It's now instant
There is a difference between instant and a 0 second timer.

In a unit indexer the unit gets the index with the event "enters region". This means right after creating the unit, it has an index.
JASS:
set u = CreateUnit(...) //enters region event triggers, unit indexer assigns the index to the unit
set index = GetUnitIndex(u) //function of the unit indexer to retrieve the index
Now index has the correct value.

Doing the same with an item indexer that uses ItemEvent will not work
JASS:
set i = CreateItem(...) //hook starts the 0 second timer. Index will be assigned later
set index = GetItemIndex(i) //function of the item indexer to retrieve the index
When this code runs, the 0 second timer has not expired yet and no index is assigned to the item.
index will be the default value, that is dependant on the implementation of the item indexer (0 for example)

Additionally if I were to move the item right after it was created, the item would no longer be in the rect attached to the 0-timer.
Now this is obviously not something you usually do, but when creating these kind of general systems it is important that the system performs correctly in all cases.
If there are cases in which the system will fail, it needs to be documented.
 
Level 5
Joined
Mar 15, 2017
Messages
96
There is a difference between instant and a 0 second timer.

In a unit indexer the unit gets the index with the event "enters region". This means right after creating the unit, it has an index.
JASS:
set u = CreateUnit(...) //enters region event triggers, unit indexer assigns the index to the unit
set index = GetUnitIndex(u) //function of the unit indexer to retrieve the index
Now index has the correct value.

Doing the same with an item indexer that uses ItemEvent will not work
JASS:
set i = CreateItem(...) //hook starts the 0 second timer. Index will be assigned later
set index = GetItemIndex(i) //function of the item indexer to retrieve the index
When this code runs, the 0 second timer has not expired yet and no index is assigned to the item.
index will be the default value, that is dependant on the implementation of the item indexer (0 for example)

Additionally if I were to move the item right after it was created, the item would no longer be in the rect attached to the 0-timer.
Now this is obviously not something you usually do, but when creating these kind of general systems it is important that the system performs correctly in all cases.
If there are cases in which the system will fail, it needs to be documented.
Oh, so hook uses timer(not instant, 0 second)?Damn...I need to find other way to fix this..
Actually, I have a better idea.But I have to use cJASS because of "#define".Is cJASS available here?
If not, I will go through the hard way.
 
Last edited:

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Damn...I need to find other way to fix this..
I don't think there is a way. There is no native event that catches when an item is created.

The hook runs before the function runs, so you need this 0 second timer to wait until the function runs and the item is created. If there was a different kind of hook that runs after the function is completed, it would be doable.
cJASS is not allowed according to the submission rules:
cJass is invalid as it has too many bugs to be acceptable.
Still if you could pull it off it would be very impressive.

You could of course publish your cJASS system in the lab.
 
Level 5
Joined
Mar 15, 2017
Messages
96
I don't think there is a way. There is no native event that catches when an item is created.

The hook runs before the function runs, so you need this 0 second timer to wait until the function runs and the item is created. If there was a different kind of hook that runs after the function is completed, it would be doable.
cJASS is not allowed according to the submission rules:

Still if you could pull it off it would be very impressive.

You could of course publish your cJASS system in the lab.
If cJass is invalid as it has too many bugs to be acceptable, then I have a better idea.But every user of my system have to use CreateItemEx(...) function.It's the only way.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
This was already done before. I highly recommend to check out this thread: [System] ItemIndexer
Catching the removal of items is also really difficult: using a remove function, selling the item, using the last charge, death
There are a lot of different ways to remove items and I don't think there is a way to safely catch them all.
 
Level 5
Joined
Mar 15, 2017
Messages
96
This was already done before. I highly recommend to check out this thread: [System] ItemIndexer
Catching the removal of items is also really difficult: using a remove function, selling the item, using the last charge, death
There are a lot of different ways to remove items and I don't think there is a way to safely catch them all.
But it was graveyarded.. :eekani::eek:2:cry:
There is a difference between instant and a 0 second timer.

In a unit indexer the unit gets the index with the event "enters region". This means right after creating the unit, it has an index.
Fixed!But removed "USE_USER_DATA" option,for good!Here check this out!
But I just realized that this system(ItemEvent) is not instant..LOLS.

EDIT:
Are you really sure it's okay to use cJASS?Because it's the only last hope to make it instant..
 
Last edited:
  1. If this library cannot instantly detect when an item enters or leaves the map then it likely won't get approved. You should be able to CreateItem and in the very next line get the item's index.
  2. The library is titled "ItemEvent", yet it only provides events related to indexing and offers no dynamic functionality to extend item events in any way.
  3. Documentation typo: //RegisterItemLeavEvent
  4. Maybe this should be merged with your ItemIndexer library. Generally these things go hand-in-hand and I don't know many cases where you would want the events separated from the indexer. However unless you can make the changes listed above, I would suggest not updating.
 
Last edited:

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Such snippets were already submitted on this forum, yet all rejected due to holes and issues that cannot be easily fixed without Blizzard intervention.

Due to fact that this is not the first attempt, and all others were graveyarded, I vote for graveyard.
As stated earlier, both item-related libraries cannot be approved. In any case, one would have to ungraveyard older scripts and grayveard these instead. Until Blizzard folks fix all the issues, subject is closed.
 
Level 5
Joined
Mar 15, 2017
Messages
96
As stated earlier, both item-related libraries cannot be approved. In any case, one would have to ungraveyard older scripts and grayveard these instead. Until Blizzard folks fix all the issues, subject is closed.
Yeah, I know.
  1. If this library cannot instantly detect when an item enters or leaves the map then it likely won't get approved. You should be able to CreateItem and in the very next line get the item's index.
  2. The library is titled "ItemEvent", yet it only provides events related to indexing and offers no dynamic functionality to extend item events in any way.
  3. Documentation typo: //RegisterItemLeavEvent
  4. Maybe this should be merged with your ItemIndexer library. Generally these things go hand-in-hand and I don't know many cases where you would want the events separated from the indexer. However unless you can make the changes listed above, I would suggest not updating.
I'll just delete this thread and merge it to ItemIndexer.

EDIT:
How can I delete/remove this thread?
 
Last edited:
Top