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

[System] Supermarker (Unit marker)

Level 7
Joined
Apr 5, 2011
Messages
245
There is a lot of unit indexers, but no markers found :/
Few words about this:
- Marker does not really register units, but only marks them
- Use GetUnitUserData to get unit state:
>0 - alive
=0 - dead
<0 - decaying)
- Marker recycles dead units periodically (each dead unit has minimum of RECYCLE_TIME before gets recycled)

JASS:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//-=-=-=-] Supermarker [-=-=-=-
//-=-=-=-=-= v0.900 -=-=-=-=-=-

/*******************************************************
* function InitSupermarker takes nothing returns nothing
*     (Starts supermarker wonderwork)
*******************************************************/

library Supermarker requires Support
//-=-=-=- Settings -=-=-=-
globals
    private constant real RECYCLE_TIME = 20
//-=-=-=-==-=-=-=-=-=-=-=-
    private trigger EnterTrigger = CreateTrigger()
    private trigger DeathTrigger = CreateTrigger()
    private integer IndexCount = 0
    private integer FreeindexCount = 0
    private integer array Freeindex
    private group Bathroom = CreateGroup()
endglobals

    private function Mark takes nothing returns boolean
        set Support.workUnit = GetFilterUnit()
        if FreeindexCount == 0 then
            set IndexCount = IndexCount + 1
            call SetUnitUserData(Support.workUnit, IndexCount)
        else
            set FreeindexCount = FreeindexCount - 1
            call SetUnitUserData(Support.workUnit, Freeindex[FreeindexCount])
        endif
        return false
    endfunction

    private function Wash takes nothing returns boolean
        call GroupAddUnit(Bathroom, GetTriggerUnit())
        return false
    endfunction
   
    private function Grab takes nothing returns nothing
        loop
            set Support.workUnit = FirstOfGroup(Bathroom)
            exitwhen Support.workUnit == null
            set Support.workInteger = GetUnitUserData(Support.workUnit)
            if Support.workInteger > 0 then
                call SetUnitUserData(Support.workUnit, -Support.workInteger)
            else
                call GroupRemoveUnit(Bathroom, Support.workUnit)
                set Support.workInteger = -Support.workInteger
                if Support.workInteger == IndexCount then
                    set IndexCount = IndexCount - 1
                endif
                set Freeindex[FreeindexCount] = Support.workInteger
                set FreeindexCount = FreeindexCount + 1
            endif
        endloop
    endfunction

    function InitSupermarker takes nothing returns nothing
        local region R = CreateRegion()
        set Support.workRect = GetWorldBounds()
        call RegionAddRect(R, Support.workRect)
        call GroupEnumUnitsInRect(Support.workGroup, Support.workRect, Condition(function Mark))
        call TriggerRegisterEnterRegion(EnterTrigger, R, Condition(function Mark))
        set R = null
        //! runtextmacro TriggerRegisterAnyUnitEvent("DeathTrigger")
        call TriggerAddCondition(DeathTrigger, Condition(function Wash))
        call TimerStart(CreateTimer(), RECYCLE_TIME, true, function Grab)
    endfunction
endlibrary
 
Last edited:
This won't get approved since you modify the unit's user data. That is reserved for unit indexers.

Instead, you should use a unit indexer and attach the data to it. e.g.:
JASS:
set marker[GetUnitUserData(u)] = 0 // or some value < 0 or > 0, depending on state

Although, there may be other means of doing this:
e.g. GetWidgetLife(u) > 0.405 [alive]
IsUnitType(u, UNIT_TYPE_DEAD) and GetHandleId(u) != 0 [decaying or just died]
IsUnitType(u, UNIT_TYPE_DEAD) and GetHandleId(u) == 0 [dead/fully decayed]

If I'm not mistaken. I could be wrong though, so feel free to correct me.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
If a unit type is dead and it's unit type id isn't 0, then it may be decaying (some units are permanent, others are not).

If a unit is alive (UnitAlive), then it's alive... lol

I don't really know why you'd want to see if a unit is decaying, nor do I know of any good way to check for unit decay instantly, unless you only care whether a unit is dead or not (dead/existence).

There is ofc a way to check when a unit decays =). See UnitEvent
 
Level 7
Joined
Apr 5, 2011
Messages
245
This won't get approved since you modify the unit's user data. That is reserved for unit indexers.
This is designed to people who do not use (!) unit indexers. That's why I tried to post a pack last time, because this may be not clear. :O
Personally I am not using unit array, only bool fields for generic unit states / buffs
(Invented by myself :ogre_hurrhurr:)
IsUnitType(u, UNIT_TYPE_DEAD) and GetHandleId(u) != 0 [decaying or just died]
IsUnitType(u, UNIT_TYPE_DEAD) and GetHandleId(u) == 0 [dead/fully decayed]
Sure, but GetUnitUserData is a bit faster.

Edit:
I don't really know why you'd want to see if a unit is decaying, nor do I know of any good way to check for unit decay instantly, unless you only care whether a unit is dead or not (dead/existence).
Custom special effects attached to corpses / spells based on decaying units
(Every decaying unit within AoE from the hero spreads Death Aura damaging all enemies around)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Rather than trying to invent all of your own stuff, just adopt the standards on THW, because likely, your attempts at making new standards will never get approved :\.

Something is only approved if it has some clear advantage over currently approved resources, given that the two do the same thing or collide. That's just one thing.

Can you clearly state why this resource holds some serious advantage over already approved resources? Why it has a serious advantage over natives?
 
But this should be in theory compatible with unit indexers... because people can use this with it...

now if you're gonna force users that want this to not use a unit indexer, then I'd rather just use other methods...

personally I don't see the need for this... more so when it conflicts with a super useful script (used by a lot of other scripts)...

And yeah, it is a THW standard to reserve UnitUserData for Unit indexer script... so better abide by that...
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Well, there are some exceptions to the rule, when you can use SetUnitUserData. To use SetUnitUserData, the unit being set must not interact with the map in any way, they must be completely internal to the system. Furthermore, to purposefully disable a unit indexer so that unit user data isn't set, the same rule applies, the unit can't interact with the map in any way.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Any use of SetUnitUserData will make it so that this can't be approved, conditional or not. There are many unit indexers out there, so just checking for the existence of one is no good. There may also be custom ones that u can't check for.

Using SetUnitUserData is banned unless it's for a unit indexer.

If you are that against them. you can always use a table.
 
Top