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

Baradé's Item Respawn System 1.1

  • Like
Reactions: deepstrasz
JASS:
// Baradé's Item Respawn System 1.1
//
// Allows picked up or destroyed items to respawn after some time.
//
// Usage:
// - Copy this code into your map script or a trigger converted into code.
// - Place some items on the map.
//
// API:
//
// function TriggerRegisterItemRespawnEvent takes trigger whichTrigger returns nothing
//
// Registers an item respawn event for the specified trigger. This means that the trigger is evaluated and executed if
// the condition is true whenever any item is respawned by this system. You can access the triggering respawning item
// and index from the system via functions.
//
// function TriggerRegisterItemRespawnStartsEvent takes trigger whichTrigger returns nothing
//
// Registers an item respawn start event for the specified trigger. This means that the trigger is evaluated and executed if
// the condition is true whenever any item respawn timer is started by this system. You can access the previously pickedup or destroyed item
// and index from the system via functions.
//
// function GetTriggerRespawnItem takes nothing returns item
//
// Returns the triggering respawned item from a trigger which was evaluated or executed due to a respawn event.
// Returns the triggering picked up previously respawned item if the event is a respawn starts event.
//
// function GetTriggerRespawnItemIndex takes nothing returns integer
//
// Returns the corresponding index of the item respawn from the respawned item or item for which the respawn timer has been started of the
// evaluated or executed trigger.
//
// function GetItemRespawnIndex takes item whichItem returns integer
//
// Returns the corresponding index of the item respawn matching the passed item. If there is none, it returns -1.
//
// function GetItemRespawnCounter takes nothing returns integer
//
// Returns the maximum number of item respawn indices. Note that not every index in between has to be valid. This function might help integer
// loops to go through all existing item respawns. Please use IsRespawnItemValid to check if an index in between 0 and the return value of
// this function is actually used.
//
// function IsRespawnItemValid takes integer index returns boolean
//
// Returns if the passed index belongs to a valid item respawn.
//
// function RespawnItem takes integer index returns boolean
//
// Respawns the item from the item respawn with the corresponding index. The index must be valid. Returns false if
// the passed index is not valid.
//
// function RespawnAllItems takes nothing returns nothing
//
// Respawns all items from all item respawns which have no item at the moment.
//
// function StartItemRespawn takes integer index returns nothing
//
// Manually starts the respawn of an item respawn no matter if the item has not been picked up or destroyed yet.
//
// function AddRespawnItem takes item whichItem returns integer
//
// Creates a new item respawn for the specified item and returns the corresponding index.
//
// function AddRespawnItemPool takes itempool whichItemPool, real x, real y returns integer
//
// function AddRespawnItemRandom takes integer level, real x, real y returns integer
//
// function AddRespawnItemRandomEx takes itemtype whichType, integer level, real x, real y returns integer
//
// function RemoveRespawnItem takes integer index returns boolean
//
// function SetRespawnItemEnabled takes integer index, boolean enabled returns nothing
//
// function IsRespawnItemEnabled takes integer index returns boolean
//
// function GetRespawnItemTimer takes integer index returns timer
//
// function GetRespawnItemType takes integer index returns integer
//
// function SetRespawnItemTimeout takes integer index, real timeout returns nothing
//
// function GetRespawnItemTimeout takes integer index returns real
//
// function SetRespawnItemX takes integer index, real x returns nothing
//
// function GetRespawnItemX takes integer index returns real
//
// function SetRespawnItemY takes integer index, real y returns nothing
//
// function GetRespawnItemY takes integer index returns real
//
// function SetRespawnItem takes integer index, item whichItem returns nothing
//
// function GetRespawnItem takes integer index returns item
//
// function SetRespawnItemPool takes integer index, itempool whichItemPool returns nothing
//
// function GetRespawnItemPool takes integer index returns itempool
//
// function SetRespawnItemLevel takes integer index, integer level returns nothing
//
// function GetRespawnItemLevel takes integer index returns integer
//
// function SetRespawnItemItemType takes integer index, itemtype whichItemType returns nothing
//
// function GetRespawnItemItemType takes integer index returns itemtype
//
library ItemRespawnSystem

globals
    // The default delay until an item will be respawned.
    public constant real DEFAULT_TIMEOUT = 30.0
    // All preplaced items on the map will automatically respawn if this value is true. Otherwise, you will have to add them manually.
    public constant boolean AUTO_ADD_ALL_PREPLACED_ITEMS = true

    public constant integer ITEM_RESPAWN_TYPE_ITEM = 0
    public constant integer ITEM_RESPAWN_TYPE_ITEMPOOL = 1
    public constant integer ITEM_RESPAWN_TYPE_RANDOM_LEVEL = 2
    public constant integer ITEM_RESPAWN_TYPE_RANDOM_TYPE_AND_LEVEL = 3

    private integer respawnItemCounter = 0
    private integer respawnItemFreeIndex = 0
    private boolean array respawnItemIsValid
    private integer array respawnItemType
    private item array respawnItemItem
    private integer array respawnItemHandleId
    private integer array respawnItemItemTypeId
    private itempool array respawnItemPool
    private integer array respawnItemRandomLevel
    private itemtype array respawnItemRandomType
    private real array respawnItemX
    private real array respawnItemY
    private timer array respawnItemTimer
    private real array respawnItemTimeout
    private boolean array respawnItemEnabled
    private trigger array respawnItemDeathTrigger

    private integer callbackRespawnTriggersCounter = 0
    private trigger array callbackRespawnTriggers

    private integer callbackRespawnStartsTriggersCounter = 0
    private trigger array callbackRespawnStartsTriggers

    private item callbackItem = null
    private integer callbackIndex = -1

    private trigger pickupItemTrigger = CreateTrigger()
    private hashtable respawnItemHashTable = InitHashtable()
    private integer evaluateIndex = -1
    private trigger refreshEvaluateTrigger = CreateTrigger()
endglobals

function GetTriggerRespawnItem takes nothing returns item
    return callbackItem
endfunction

function GetTriggerRespawnItemIndex takes nothing returns integer
    return callbackIndex
endfunction

function TriggerRegisterItemRespawnEvent takes trigger whichTrigger returns nothing
    local integer index = callbackRespawnTriggersCounter
    set callbackRespawnTriggers[index] = whichTrigger
    set callbackRespawnTriggersCounter = callbackRespawnTriggersCounter + 1
endfunction

private function EvaluateAndExecuteCallbackRespawnTriggers takes integer index returns nothing
    local integer i = 0
    loop
        exitwhen (i >= callbackRespawnTriggersCounter)
        set callbackItem = respawnItemItem[index]
        set callbackIndex = index
        call ConditionalTriggerExecute(callbackRespawnTriggers[i])
        set i = i + 1
    endloop
endfunction

function TriggerRegisterItemRespawnStartsEvent takes trigger whichTrigger returns nothing
    local integer index = callbackRespawnStartsTriggersCounter
    set callbackRespawnStartsTriggers[index] = whichTrigger
    set callbackRespawnStartsTriggersCounter = callbackRespawnStartsTriggersCounter + 1
endfunction

private function EvaluateAndExecuteCallbackRespawnStartsTriggers takes integer index returns nothing
    local integer i = 0
    loop
        exitwhen (i >= callbackRespawnStartsTriggersCounter)
        set callbackItem = respawnItemItem[index]
        set callbackIndex = index
        call ConditionalTriggerExecute(callbackRespawnStartsTriggers[i])
        set i = i + 1
    endloop
endfunction

private function ClearItemRespawnIndex takes integer handleID returns nothing
    if (HaveSavedInteger(respawnItemHashTable, handleID, 0)) then
        call FlushChildHashtable(respawnItemHashTable, handleID)
    endif
endfunction

private function GetItemRespawnIndexByHandleID takes integer handleID returns integer
    if (HaveSavedInteger(respawnItemHashTable, handleID, 0)) then
        return LoadInteger(respawnItemHashTable, handleID, 0)
    endif

    return -1
endfunction

function GetItemRespawnIndex takes item whichItem returns integer
    return GetItemRespawnIndexByHandleID(GetHandleId(whichItem))
endfunction

function GetItemRespawnCounter takes nothing returns integer
    return respawnItemCounter
endfunction

function IsRespawnItemValid takes integer index returns boolean
    if (index < 0) then
        return false
    endif
    return respawnItemIsValid[index]
endfunction

function RespawnItem takes integer index returns boolean
    if (not IsRespawnItemValid(index)) then
        return false
    endif
    if (respawnItemType[index] == ITEM_RESPAWN_TYPE_ITEM) then
        set respawnItemItem[index] = CreateItem(respawnItemItemTypeId[index], respawnItemX[index], respawnItemY[index])
    elseif (respawnItemType[index] == ITEM_RESPAWN_TYPE_ITEMPOOL) then
        set respawnItemItem[index] = PlaceRandomItem(respawnItemPool[index], respawnItemX[index], respawnItemY[index])
    elseif (respawnItemType[index] == ITEM_RESPAWN_TYPE_RANDOM_LEVEL) then
        set respawnItemItem[index] = CreateItem(ChooseRandomItem(respawnItemRandomLevel[index]), respawnItemX[index], respawnItemY[index])
    elseif (respawnItemType[index] == ITEM_RESPAWN_TYPE_RANDOM_TYPE_AND_LEVEL) then
        set respawnItemItem[index] = CreateItem(ChooseRandomItemEx(respawnItemRandomType[index], respawnItemRandomLevel[index]), respawnItemX[index], respawnItemY[index])
    endif
    set respawnItemHandleId[index] = GetHandleId(respawnItemItem[index])
    call SaveInteger(respawnItemHashTable, respawnItemHandleId[index], 0, index)
    set evaluateIndex = index
    call TriggerEvaluate(refreshEvaluateTrigger)
    call EvaluateAndExecuteCallbackRespawnTriggers(index)
    return true
endfunction

function RespawnAllItems takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen (i >= respawnItemCounter)
        if (IsRespawnItemValid(i) and respawnItemItem[i] == null) then
            call RespawnItem(i)
        endif
        set i = i + 1
    endloop
endfunction

private function TimerFunctionRespawnItem takes nothing returns nothing
    local integer index = LoadInteger(respawnItemHashTable, GetHandleId(GetExpiredTimer()), 0)
    call RespawnItem(index)
endfunction

function StartItemRespawn takes integer index returns nothing
    call EvaluateAndExecuteCallbackRespawnStartsTriggers(index)

    if (respawnItemHandleId[index] != 0) then
        call ClearItemRespawnIndex(respawnItemHandleId[index])
    endif
    set respawnItemItem[index] = null
    set respawnItemHandleId[index] = 0
    call TimerStart(respawnItemTimer[index], respawnItemTimeout[index], false, function TimerFunctionRespawnItem)
endfunction

private function TriggerActionDeath takes nothing returns nothing
    local integer index = GetItemRespawnIndexByHandleID(GetHandleId(GetTriggerWidget()))
    call StartItemRespawn(index)
endfunction

private function RefreshDeathTrigger takes integer index returns nothing
    if (respawnItemDeathTrigger[index] != null) then
        call DestroyTrigger(respawnItemDeathTrigger[index])
        set respawnItemDeathTrigger[index] = null
    endif

    set respawnItemDeathTrigger[index] = CreateTrigger()
    call TriggerRegisterDeathEvent(respawnItemDeathTrigger[index], respawnItemItem[index])
    call TriggerAddAction(respawnItemDeathTrigger[index], function TriggerActionDeath)
endfunction

private function RefreshDeathTriggerEvaluate takes nothing returns boolean
    call RefreshDeathTrigger(evaluateIndex)
    return false
endfunction

private function AddRespawnItemDefault takes integer index, real x, real y returns nothing
    set respawnItemIsValid[index] = true
    set respawnItemX[index] = x
    set respawnItemY[index] = y
    set respawnItemTimer[index] = CreateTimer()
    set respawnItemTimeout[index] = DEFAULT_TIMEOUT
    call SaveInteger(respawnItemHashTable, GetHandleId(respawnItemTimer[index]), 0, index)
    set respawnItemEnabled[index] = true
    call RefreshDeathTrigger(index)

    loop
        set respawnItemFreeIndex = respawnItemFreeIndex + 1
        exitwhen (not IsRespawnItemValid(respawnItemFreeIndex))
    endloop

    if (index >= respawnItemCounter) then
        set respawnItemCounter = index + 1
    endif
endfunction

function AddRespawnItem takes item whichItem returns integer
    local integer index = respawnItemFreeIndex
    set respawnItemType[index] = ITEM_RESPAWN_TYPE_ITEM
    set respawnItemItem[index] = whichItem
    set respawnItemHandleId[index] = GetHandleId(whichItem)
    set respawnItemItemTypeId[index] = GetItemTypeId(whichItem)
    set respawnItemPool[index] = null
    call AddRespawnItemDefault(index, GetItemX(whichItem), GetItemY(whichItem))

    call SaveInteger(respawnItemHashTable, respawnItemHandleId[index], 0, index)

    return index
endfunction

function AddRespawnItemPool takes itempool whichItemPool, real x, real y returns integer
    local integer index = respawnItemFreeIndex
    set respawnItemType[index] = ITEM_RESPAWN_TYPE_ITEMPOOL
    set respawnItemItem[index] = null
    set respawnItemHandleId[index] = 0
    set respawnItemItemTypeId[index] = 0
    set respawnItemPool[index] = whichItemPool
    call AddRespawnItemDefault(index, x, y)

    call RespawnItem(index)

    return index
endfunction

function AddRespawnItemRandom takes integer level, real x, real y returns integer
    local integer index = respawnItemFreeIndex
    set respawnItemType[index] = ITEM_RESPAWN_TYPE_RANDOM_LEVEL
    set respawnItemItem[index] = null
    set respawnItemHandleId[index] = 0
    set respawnItemItemTypeId[index] = 0
    set respawnItemPool[index] = null
    set respawnItemRandomLevel[index] = level
    set respawnItemRandomType[index] = null
    call AddRespawnItemDefault(index, x, y)

    call RespawnItem(index)

    return index
endfunction

function AddRespawnItemRandomEx takes itemtype whichType, integer level, real x, real y returns integer
    local integer index = respawnItemFreeIndex
    set respawnItemType[index] = ITEM_RESPAWN_TYPE_RANDOM_TYPE_AND_LEVEL
    set respawnItemItem[index] = null
    set respawnItemHandleId[index] = 0
    set respawnItemItemTypeId[index] = 0
    set respawnItemPool[index] = null
    set respawnItemRandomLevel[index] = level
    set respawnItemRandomType[index] = whichType
    call AddRespawnItemDefault(index, x, y)

    call RespawnItem(index)

    return index
endfunction

function RemoveRespawnItem takes integer index returns boolean
    if (IsRespawnItemValid(index)) then
        set respawnItemIsValid[index] = false

        if (respawnItemItem[index] != null) then
            call ClearItemRespawnIndex(GetHandleId(respawnItemItem[index]))
        endif

        set respawnItemTimeout[index] = 0
        set respawnItemType[index] = 0
        set respawnItemItem[index] = null
        set respawnItemHandleId[index] = 0
        set respawnItemItemTypeId[index] = 0
        set respawnItemPool[index] = null
        set respawnItemRandomLevel[index] = 0
        set respawnItemRandomType[index] = null

        call PauseTimer(respawnItemTimer[index])
        call FlushChildHashtable(respawnItemHashTable, GetHandleId(respawnItemTimer[index]))
        call DestroyTimer(respawnItemTimer[index])

        set respawnItemFreeIndex = index

        if (index == respawnItemCounter - 1) then
            set respawnItemCounter = respawnItemCounter - 1
        endif

        return true
    endif

    return false
endfunction

function SetRespawnItemEnabled takes integer index, boolean enabled returns nothing
    set respawnItemEnabled[index] = enabled
endfunction

function IsRespawnItemEnabled takes integer index returns boolean
    return respawnItemEnabled[index]
endfunction

function GetRespawnItemTimer takes integer index returns timer
    return respawnItemTimer[index]
endfunction

function GetRespawnItemType takes integer index returns integer
    return respawnItemType[index]
endfunction

function SetRespawnItemTimeout takes integer index, real timeout returns nothing
    set respawnItemTimeout[index] = timeout
endfunction

function GetRespawnItemTimeout takes integer index returns real
    return respawnItemTimeout[index]
endfunction

function SetRespawnItemX takes integer index, real x returns nothing
    set respawnItemX[index] = x
endfunction

function GetRespawnItemX takes integer index returns real
    return respawnItemX[index]
endfunction

function SetRespawnItemY takes integer index, real y returns nothing
    set respawnItemX[index] = y
endfunction

function GetRespawnItemY takes integer index returns real
    return respawnItemY[index]
endfunction

function SetRespawnItem takes integer index, item whichItem returns nothing
    set respawnItemItem[index] = whichItem
endfunction

function GetRespawnItem takes integer index returns item
    return respawnItemItem[index]
endfunction

function SetRespawnItemPool takes integer index, itempool whichItemPool returns nothing
    set respawnItemPool[index] = whichItemPool
endfunction

function GetRespawnItemPool takes integer index returns itempool
    return respawnItemPool[index]
endfunction

function SetRespawnItemLevel takes integer index, integer level returns nothing
    set respawnItemRandomLevel[index] = level
endfunction

function GetRespawnItemLevel takes integer index returns integer
    return respawnItemRandomLevel[index]
endfunction

function SetRespawnItemItemType takes integer index, itemtype whichItemType returns nothing
    set respawnItemRandomType[index] = whichItemType
endfunction

function GetRespawnItemItemType takes integer index returns itemtype
    return respawnItemRandomType[index]
endfunction

private function TriggerConditionRespawnItem takes nothing returns boolean
    local integer index = GetItemRespawnIndex(GetManipulatedItem())
    return IsRespawnItemValid(index) and IsRespawnItemEnabled(index)
endfunction

private function TriggerActionRespawnItem takes nothing returns nothing
    local integer index = GetItemRespawnIndex(GetManipulatedItem())
    call StartItemRespawn(index)
endfunction

private function AddEnumItem takes nothing returns nothing
    call AddRespawnItem(GetEnumItem())
endfunction

private module Init

    private static method onInit takes nothing returns nothing
        call TriggerRegisterAnyUnitEventBJ(pickupItemTrigger, EVENT_PLAYER_UNIT_PICKUP_ITEM)
        call TriggerAddCondition(pickupItemTrigger, Condition(function TriggerConditionRespawnItem))
        call TriggerAddAction(pickupItemTrigger, function TriggerActionRespawnItem)

        call TriggerAddCondition(refreshEvaluateTrigger, Condition(function RefreshDeathTriggerEvaluate))

        static if (AUTO_ADD_ALL_PREPLACED_ITEMS) then
            call EnumItemsInRect(GetPlayableMapRect(), null, function AddEnumItem)
        endif
    endmethod
endmodule

private struct S
    implement Init
endstruct

private function RemoveItemCleanup takes item whichItem returns nothing
    local integer handleID = GetHandleId(whichItem)
    call ClearItemRespawnIndex(handleID)
endfunction

hook RemoveItem RemoveItemCleanup


// Change Log:
//
// 1.1 2022-07-30:
// - Move system initializer into module to give it the highest priority possible.
// - Store item respawn index per item in a hashtable to improve the performance.
// - Add constant AUTO_ADD_ALL_PREPLACED_ITEMS which is true by default to automatically add all preplaced items.
// - Support item respawns from item pools, levels and types.
// - Support removing item respawns.
// - Support registering callbacks for respawn start events.
// - Add functions AddRespawnItemPool, AddRespawnItemRandom and AddRespawnItemRandomEx, RemoveRespawnItem, IsRespawnItemValid, TriggerRegisterItemRespawnStartsEvent and many setters and getters.
// - Add constants for the different types.
endlibrary

1.1 2022-07-30:
- Move system initializer into module to give it the highest priority possible.- Store item respawn index per item in a hashtable to improve the performance.
- Add constant AUTO_ADD_ALL_PREPLACED_ITEMS which is true by default to automatically add all preplaced items.
- Support item respawns from item pools, levels and types.
- Support removing item respawns.
- Support registering callbacks for respawn start events.
- Add functions AddRespawnItemPool, AddRespawnItemRandom and AddRespawnItemRandomEx, RemoveRespawnItem, IsRespawnItemValid, TriggerRegisterItemRespawnStartsEvent and many setters and getters.
- Add constants for the different types.

Contents

Baradé's Item Respawn System 1.1 (Map)

Reviews
MyPad
All of these changes are appreciated. That said, I'd like to bring up the following points: Going back to my previous post, I'd like to clarify the thing about merging TriggerActionRespawnItem and TriggerConditionRespawnItem. What I wanted to convey...
Hello there. This system looks kind of intriguing, simple as it may be.

  • vJASS systems usually rely on module initializers for the reliable order of initialization. Any other type of initialization may fail to retain order of initialization, resulting in possible issues down the line. (For example, if a dependency calls a function from this system and the called function acts on the system with the prior assumption that the initialization has already occurred, the called function may fail). From the looks of it, struct and module initializers are likely to break this system.

  • I'm not sure which functions are actually accessible from outside the scope of the library, since I've spotted some functions which may look like private functions, but are not declared as such. (Functions in libraries are public by default in vJASS)
    • GetItemRespawn looks like a function which retrieves the index of the queried item handle. Curiously, the parameter itself appears to be unused, with GetManipulatedItem() being used in its place.

    • Is RespawnAllItems supposed to be a public function by any means? Based on the purpose of the system, it would make a lot more sense to keep it private if it's not intended to be public. Also, from what I can ctrl+find, it appears to be a dead function, with nothing in the system explicitly calling it.
  • Functions TriggerConditionRespawnItem and TriggerActionRespawnItem can be merged into a single function, seeing that the first lines of code of each function are the same and the boolean result can simply be evaluated in an if-then conditional block, calling the relevant functions within TriggerActionRespawnItem.

  • GUI generated functions Trig_Barades_Item_Respawn_System_Actions and InitTrig_Barades_Item_Respawn_System do not appear to be doing anything relevant to the system. They're likely not accessed anywhere as well, making them dead functions.

  • The performance of the getter functions can be improved (for a large amount of registered item ids) via the use of a hashtable or Bribe's [Snippet] New Table. This should reduce the time complexity of the function from O(N) to O(1).

  • It appears that the system does not automatically register all preplaced items. Perhaps you can provide that functionality within the system itself and not in an external trigger?

  • It would be appreciated if documentation regarding the API of the system (at least for public functions) would be provided either for the provision of additional context, clarification of intent, proper use of parameters and so on.

  • From what I understand of the scope of this system, items created at runtime (a la CreateItem) do not appear to be registered to the system, which should not be the case.
 
Last edited:
Level 25
Joined
Feb 2, 2006
Messages
1,667
thx I am planning to update this system with some more API functions as well for itempools etc.

edit:
Update 1.1 (see ChangeLog) and regarding your points:

  • The initialization is now in a module.
  • Listed all usable functions in the first comment yes RespawnAllItems should be a small helper function if you want all items to respawn immediately. For example, there could be a custom spell in your map which allows to respawn all items or some reset functionality.
  • The system uses indices for the different respawned items similar to struct IDs. I did not want to use too much vJass overhead and keep the API more JASS-like.
  • You can remove the item respawns now and check if they are valid. The next free index will be used and you can access the maximum counter to go through all item respawns by index.
  • I disagree a bit about TriggerConditionRespawnItem since it is faster than immediately calling the action and since retrieving the index is now pretty fast it should not be an issue.
  • Removed the GUI generated functions.
  • Improved the performance by using the hashtable and a hook to flush the index on removing the item and it is automatically flushed when the item dies.
  • There is a constant now which is true by default and it registers all preplaced items automatically.
  • I have listed the usable functions and documented some. Many of them are explained by their name I guess but I can add more documentation.-
  • Created items during runtime should not always be registered as respawnable items? Imagine you create a unique quest item via triggers, it should NEVER respawn. The same goes for sold items etc. etc. I think the user should have the control over which items will respawn. However, I could more helper functionality like the one for the preplaced items. I am open for suggestions.
 
Last edited:
thx I am planning to update this system with some more API functions as well for itempools etc.

edit:
Update 1.1 (see ChangeLog) and regarding your points:

  • The initialization is now in a module.
  • Listed all usable functions in the first comment yes RespawnAllItems should be a small helper function if you want all items to respawn immediately. For example, there could be a custom spell in your map which allows to respawn all items or some reset functionality.
  • The system uses indices for the different respawned items similar to struct IDs. I did not want to use too much vJass overhead and keep the API more JASS-like.
  • You can remove the item respawns now and check if they are valid. The next free index will be used and you can access the maximum counter to go through all item respawns by index.
  • I disagree a bit about TriggerConditionRespawnItem since it is faster than immediately calling the action and since retrieving the index is now pretty fast it should not be an issue.
  • Removed the GUI generated functions.
  • Improved the performance by using the hashtable and a hook to flush the index on removing the item and it is automatically flushed when the item dies.
  • There is a constant now which is true by default and it registers all preplaced items automatically.
  • I have listed the usable functions and documented some. Many of them are explained by their name I guess but I can add more documentation.-
  • Created items during runtime should not always be registered as respawnable items? Imagine you create a unique quest item via triggers, it should NEVER respawn. The same goes for sold items etc. etc. I think the user should have the control over which items will respawn. However, I could more helper functionality like the one for the preplaced items. I am open for suggestions.
All of these changes are appreciated. That said, I'd like to bring up the following points:
  • Going back to my previous post, I'd like to clarify the thing about merging TriggerActionRespawnItem and TriggerConditionRespawnItem. What I wanted to convey with that point is the following snippet:

    JASS:
    local integer index = GetItemRespawnIndex(GetManipulatedItem())
    if IsRespawnItemValid(index) and IsRespawnItemEnabled(index) then
        // From the TriggerActionRespawnItem block
        call StartItemRespawn(index)
    endif

    That way, you only need to call the functions GetItemRespawnIndex and GetManipulatedItem once and operate on the given index. Yes, I agree on the part where TriggerConditionRespawnItem would be faster by virtue of it being the designated function for the triggercondition, but it shouldn't only be restricted to returning boolean arguments since it can achieve most of the things a triggeraction can do (barring a few, such as TriggerSleepAction).

    Nevertheless, it's a relatively minor thing to change and shouldn't have too much of an impact on the approval state of this system.

  • As for created items not being registered to the system at runtime, I admit I didn't consider that line of thought when writing up the review. Perhaps some users may want to create an automatically respawning item, and I think a wrapper function around CreateItem (not a hooked function) should suffice.

  • For multiple line comments, you can enclose them with the paired /* */ symbols if you want.
Since the system runs quite smoothly in testing, this has now been approved.

Status:

  • Approved

Reviewed Version:

  • v.1.1

 
Top