System Unit Decaying

Nestharus

o-o
Reaction score
84
Corpse Manager

Ok, because a lot of people see absolutely no use in this, I guess I'll put up some demonstrations on actual applicable uses rather than a little peasant who gets remade every time he decays, rofl : p.

JASS:
constant real bj_CORPSE_MAX_DEATH_TIME=8.00
native UnitSuspendDecay takes unit whichUnit, boolean suspend returns nothing //stops working at the limit: 8

The way to control death

What will this make way for?
Cool units that base their abilities off of decay time and have various auras and what not to make the decay time go faster.
Cool units with damage based on the decay time of a unit while the unit is alive
Cool units with damage based on the remaining decay time of units in range

JASS:

native UnitAlive takes unit id returns boolean

library CorpseManager initializer Initialization uses PlayerTracker, Recycle, GenericData
/*Information
//===================================================================
Name: Unit Decaying
Version: 7.2
Author: Nestharus

Settings:
*///===================================================================
globals
    private constant real UNIT_DECAY = 90
endglobals

//! textmacro CorpseManager_EXTRA_PLAYERS
    //call TriggerRegisterPlayerUnitEvent(decay, GetPlayer(15), EVENT_PLAYER_UNIT_DEATH, startDecay)
//! endtextmacro

//! textmacro CorpseManager_DECAY
    return not IsUnitType(u, UNIT_TYPE_HERO)
//! endtextmacro
/*//===================================================================

Description:
    What does it do-
        This allows you to do things when a unit decays. The normal
        UnitSuspendDecay function does not work properly as it is
        capped out at 8 seconds. This one works to any amount you want.
        It can also change whether or not units and unit types do or don't
        decay in real time.

Requirements: PlayerTracker- hiveworkshop.com/forums/jass-functions-413/system-pt-player-tracking-142554/
              Recycle- thehelper.net/forums/showthread.php?t=136087
              GenericData- thehelper.net/forums/showthread.php?t=141695

Installation: Advanced -> Gameplay Constants -> Corpse Decay Times -> 9999999

Settings:
------------------------------------------------------------------
UNIT_DECAY
    Refers to the global decay time for all units. This is only used
    if a unit does not have a set decay time.

CorpseManager_EXTRA_PLAYERS-
    Refers to other players that this system runs for. Does not go
    through a loop. Players 0-11 are automatically registered.

CorpseManager_DECAY-
    Will check this for decay. Heroes do not decay in a normal game,
    so they are automatically included.

API:
------------------------------------------------------------------
All Decay Events Evaluate The Triggers. Use TriggerAddCondition() instead
of TriggerAddAction() if you want your stuff to run.

-SetUnitDecay(unit, time)
    Will set the decay time of a specific unit. Setting the time to
    0 will make it default to the unitType time.

-SetUnitTypeDecay(unitType, time)
    Will set the decay time of a unit type. Setting the time to 0
    will make it default to the global decay time.

-SetUnitDecayFlag(unit, doesDecay)
    This will make it so that the unit's flag will override the unit
    type flag if enabled is true.

-SetUnitTypeDecayFlag(unit, doesDecay)
    This will change the decay flag for all units of a type

-TriggerRegisterDecayEvent(trigger) returns integer
    Will fire whenever a unit decays. The integer returned is
    an id that can be used to unregister the trigger when desired.

-TriggerRegisterUnitDecayEvent(trigger, unit) returns integer
    Will fire when the specific unit decays. The integer returned
    is an id that can be used to unregister the trigger when desired.
    After the unit decays, all triggers registered with the unit are
    automatically unregistered, so there are no leaks.

-TriggerRegisterPlayerDecayEvent(trigger, playerId) returns integer
    Will fire whenever a unit owned by player decays. The integer returned is
    an id that can be used to unregister the trigger when desired.

-TriggerRegisterUnitTypeDecayEvent(trigger, unitType) returns integer
    Will fire whenever a unit of unitType decays. The integer returned is
    an id that can be used to unregister the trigger when desired.

-TriggerRegisterPlayerUnitTypeDecayEvent(trigger, playerId, unitType) returns integer
    Will fire whenever a unit of unitType owned by player decays. The integer returned
    is an id that can be used to unregister the trigger when desired.

-TriggerRemoveDecayEvent(id)
    Will unregister the trigger associated with the id from the system.

-TriggerRemoveUnitDecayEvent(id, unit)
    Will unregister the trigger associated with the id from the system.
    Requires unit as the trigger was registered only for a specific
    unit.

-TriggerRemovePlayerDecayEvent(id, playerId)
    Will unregister the trigger associated with the id from the system.
    Requires playerId as the trigger was registered only for a specific
    player.

-TriggerRemovePlayerUnitTypeDecayEvent(id, playerId, unitTypeId)
    Will unregister the trigger associated with the id from the system.
    Requires playerId and unitTypeId.

-TriggerRemoveUnitTypeDecayEvent(id, unitTypeId)
    Will unregister the trigger associated with the id from the system.
    Reguires a unit type id as the trigger was registered only for a
    specific unit type.

-GetLastDecayedUnit()
    Will return the last decaying unit

-GetUnitRemainingDecayTime(unit)
    Returns the remaining decay time of a unit. Will return 0
    if that unit is alive. Only works on units that do decay.

-GetUnitElapsedDecayTime(unit)
    Returns the elapsed decay time of a unit. Will return 0 if that
    unit is alive. Only works on units that do decay.

-GetUnitDecayMaxTime(unit)
    Returns the decay time of a unit. If the decay time is 0, will
    return the decay time of the unit's type id. If that is 0, it
    will return UNIT_DECAY.

-SetUnitRemainingDecay(unit, time)
    Will set the remaining decay of a unit. A time of 0 will work here.

-CreateUnitCorpse(player, unitTypeId, x, y, facing, time)
    Will create a decaying corpse. If the time is 0, it will default
    to unitTypeId values. If those are 0, it will default to UNIT_DECAY.
------------------------------------------------------------------*/
    private keyword CorpseUnit

    private struct CorpseTimer extends array
        implement PermanentId
        public CorpseUnit decayUnit
        public timer decayTimer
    endstruct

    private struct CorpseUnitType extends array
        implement PermanentId
        public real decay
        public boolean flag
    endstruct

    private struct CorpseUnit extends array
        implement DynamicId
        public CorpseTimer decayTimer
        public unit decayUnit
        public real decay
        public boolean flag
        public integer decayHandleId
    endstruct

    private struct EventPlayerUnit
        public static integer count = 0
        public static hashtable decayEvent = InitHashtable()
    endstruct

    private struct EventPlayerType
        public static integer array count[16]
        public static hashtable decayEvent = InitHashtable()
    endstruct

    private struct EventUnit
        public static integer count = 0
        public static hashtable decayEvent = InitHashtable()
    endstruct

    private struct EventUnitType
        public static integer count = 0
        public static hashtable decayEvent = InitHashtable()
    endstruct

    private struct EventDecay
        public static integer count = 0
        public static trigger array decayEvent
    endstruct

    globals
        private trigger decayTrig = CreateTrigger()

        //Event Vars
        private unit lastDecayedUnit = null

        private boolexpr boolFunc
        private CorpseTimer curTimer
        private CorpseUnitType curUnitType
        private CorpseUnit curUnit
        private integer handleId
        private timer runTimer
        private unit runUnit
        private real decayTime
        private integer runUnitType
        private integer runIndex
        private integer runPlayerId
    endglobals

    private function DoesDecay takes unit u returns boolean
        //! runtextmacro CorpseManager_DECAY()
    endfunction

    function SetUnitDecayFlag takes unit u, boolean flag returns nothing
        set CorpseUnit(CorpseUnit[GetHandleId(u)]).flag = not flag
    endfunction
    
    function SetUnitTypeDecayFlag takes integer unitTypeId, boolean flag returns nothing
        set CorpseUnitType(CorpseUnitType[unitTypeId]).flag = not flag
    endfunction

    function GetUnitRemainingDecayTime takes unit u returns real
        if DoesDecay(u) and not UnitAlive(u) then
            return TimerGetRemaining(CorpseUnit(CorpseUnit[GetHandleId(u)]).decayTimer.decayTimer)
        endif
        return 0.
    endfunction

    function GetUnitElapsedDecayTime takes unit u returns real
        if DoesDecay(u) and not UnitAlive(u) then
            return TimerGetElapsed(CorpseUnit(CorpseUnit[GetHandleId(u)]).decayTimer.decayTimer)
        endif
        return 0.
    endfunction

    function GetUnitDecayMaxTime takes unit u returns real
        if DoesDecay(u) then
            set curUnit = CorpseUnit[GetHandleId(u)]
            set curUnitType = CorpseUnitType[GetUnitTypeId(u)]
            if not (curUnit.flag and curUnitType.flag) then
                if curUnit.decay > 0 then
                    return curUnit.decay
                elseif curUnitType.decay > 0 then
                    return curUnitType.decay
                endif
                return UNIT_DECAY
            endif
        endif
        return 0.
    endfunction

    function SetUnitDecay takes unit u, real decayTime returns nothing
        set handleId = GetHandleId(u)
        set curUnit = CorpseUnit[handleId]
        set curUnit.decayHandleId = handleId
        set curUnit.decay = decayTime
    endfunction

    function SetUnitTypeDecay takes integer unitTypeId, real decayTime returns nothing
        set CorpseUnitType(CorpseUnitType[unitTypeId]).decay = decayTime
    endfunction

    constant function GetLastDecayedUnit takes nothing returns unit
        return lastDecayedUnit
    endfunction

    function TriggerRegisterUnitDecayEvent takes trigger t, unit u returns integer
        call SaveTriggerHandle(EventUnit.decayEvent, GetHandleId(u), EventUnit.count, t)
        set EventUnit.count = EventUnit.count + 1
        return EventUnit.count
    endfunction

    function TriggerRegisterDecayEvent takes trigger t returns integer
        set EventDecay.decayEvent[EventDecay.count] = t
        set EventDecay.count = EventDecay.count + 1
        return EventDecay.count
    endfunction

    function TriggerRegisterPlayerDecayEvent takes trigger t, integer playerId returns integer
        call SaveTriggerHandle(EventPlayerUnit.decayEvent, playerId, EventPlayerUnit.count, t)
        set EventPlayerUnit.count = EventPlayerUnit.count + 1
        return EventPlayerUnit.count
    endfunction

    function TriggerRegisterUnitTypeDecayEvent takes trigger t, integer unitTypeId returns integer
        call SaveTriggerHandle(EventUnitType.decayEvent, unitTypeId, EventUnitType.count, t)
        set EventUnitType.count = EventUnitType.count + 1
        return EventUnitType.count
    endfunction

    function TriggerRegisterPlayerUnitTypeDecayEvent takes trigger t, integer playerId, integer unitTypeId returns integer
        call SaveTriggerHandle(EventPlayerType.decayEvent, unitTypeId, playerId+16*EventPlayerType.count[playerId], t)
        set EventPlayerType.count[playerId] = EventPlayerType.count[playerId] + 1
        return EventUnitType.count
    endfunction

    function TriggerRemoveUnitDecayEvent takes integer id, unit u returns nothing
        set EventUnit.count = EventUnit.count - 1
        set handleId = GetHandleId(u)
        call SaveTriggerHandle(EventUnit.decayEvent, handleId, id, LoadTriggerHandle(EventUnit.decayEvent, handleId, EventUnit.count))
    endfunction

    function TriggerRemoveDecayEvent takes integer id returns nothing
        set EventDecay.count = EventDecay.count + -1
        set EventDecay.decayEvent[id] = EventDecay.decayEvent[EventDecay.count]
    endfunction

    function TriggerRemovePlayerDecayEvent takes integer id, integer playerId returns nothing
        set EventPlayerUnit.count = EventPlayerUnit.count - 1
        call SaveTriggerHandle(EventPlayerUnit.decayEvent, playerId, id, LoadTriggerHandle(EventPlayerUnit.decayEvent, playerId, EventPlayerUnit.count))
    endfunction

    function TriggerRemoveUnitTypeDecayEvent takes integer id, integer unitTypeId returns nothing
        set EventUnitType.count = EventUnitType.count - 1
        call SaveTriggerHandle(EventUnitType.decayEvent, unitTypeId, id, LoadTriggerHandle(EventUnitType.decayEvent, unitTypeId, EventUnitType.count))
    endfunction

    function TriggerRemovePlayerUnitTypeDecayEvent takes integer id, integer playerId, integer unitTypeId returns nothing
        set EventPlayerType.count[playerId] = EventPlayerType.count[playerId] - 1
        call SaveTriggerHandle(EventPlayerType.decayEvent, unitTypeId, playerId+16*id, LoadTriggerHandle(EventPlayerType.decayEvent, unitTypeId, playerId+16*EventPlayerType.count[playerId]))
    endfunction

    private function EndDecay takes nothing returns nothing
        set runTimer = GetExpiredTimer()
        set curTimer = CorpseTimer[GetHandleId(runTimer)]
        set curUnit = curTimer.decayUnit
        set runUnitType = GetUnitTypeId(curUnit.decayUnit)
        if runUnitType > 0 and not UnitAlive(curUnit.decayUnit) and not (curUnit.flag and curUnitType.flag) then
            set lastDecayedUnit = curUnit.decayUnit
            //all
            set runIndex = EventDecay.count
            loop
                exitwhen runIndex == 0
                set runIndex = runIndex - 1
                call TriggerEvaluate(EventDecay.decayEvent[runIndex])
            endloop
            //unit
            set runIndex = EventUnit.count
            set handleId = GetHandleId(curUnit.decayUnit)
            loop
                exitwhen runIndex == 0
                set runIndex = runIndex - 1
                call TriggerEvaluate(LoadTriggerHandle(EventUnit.decayEvent, handleId, runIndex))
            endloop
            call FlushChildHashtable(EventUnit.decayEvent, handleId)
            set EventUnit.count = 0
            //unit type
            set runIndex = EventUnitType.count
            loop
                exitwhen runIndex == 0
                set runIndex = runIndex - 1
                call TriggerEvaluate(LoadTriggerHandle(EventUnitType.decayEvent, runUnitType, runIndex))
            endloop
            //player unit
            set runPlayerId = GetPlayerId(GetOwningPlayer(curUnit.decayUnit))
            set runIndex = EventPlayerUnit.count
            loop
                exitwhen runIndex == 0
                set runIndex = runIndex - 1
                call TriggerEvaluate(LoadTriggerHandle(EventPlayerUnit.decayEvent, runPlayerId, runIndex))
            endloop
            //player unit type
            set runIndex = EventPlayerType.count[runPlayerId]
            loop
                exitwhen runIndex == 0
                set runIndex = runIndex - 1
                call TriggerEvaluate(LoadTriggerHandle(EventPlayerType.decayEvent, runPlayerId+16*runIndex, runIndex))
            endloop
            call RemoveUnit(lastDecayedUnit)
        endif
        set curUnit.decayTimer = 0
        set curUnit.decay = 0
        set curUnit.flag = false
        call CorpseUnit.release(curUnit.decayHandleId)
    endfunction

    function SetUnitRemainingDecay takes unit u, real time returns nothing
        if DoesDecay(u) and not UnitAlive(u) then
            call TimerStart(CorpseUnit(CorpseUnit[GetHandleId(u)]).decayTimer.decayTimer, time, false, function EndDecay)
        endif
    endfunction

    function CreateUnitCorpse takes player p, integer unitTypeId, real x, real y, real facing, real time returns unit
        set runTimer = Timer.get()
        set curTimer = CorpseTimer[GetHandleId(runTimer)]
        set curTimer.decayTimer = runTimer
        set runUnit = CreateCorpse(p, unitTypeId, x, y, facing)
        set handleId = GetHandleId(runUnit)
        set curUnit = CorpseUnit[handleId]
        set curUnit.decayUnit = runUnit
        set curTimer.decayUnit = curUnit
        set curUnit.decayTimer = curTimer
        set curUnit.decayHandleId = handleId
        if time > 0 then
            set curUnit.decay = time
            call TimerStart(runTimer, curUnit.decay, false, function EndDecay)
        elseif not curUnitType.flag then
            set curUnitType = CorpseUnitType[GetUnitTypeId(runUnit)]
            if curUnitType.decay > 0 then
                call TimerStart(runTimer, curUnitType.decay, false, function EndDecay)
            else
                call TimerStart(runTimer, UNIT_DECAY, false, function EndDecay)
            endif
        debug else
            debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Made a unit that does not decay!")
        endif
        return runUnit
    endfunction

    private function StartDecay takes nothing returns boolean
        set runUnit = GetTriggerUnit()
        if DoesDecay(runUnit) then
            set handleId = GetHandleId(runUnit)
            set curUnit = CorpseUnit[handleId]
            set curUnit.decayHandleId = handleId
            set curUnitType = CorpseUnitType[GetUnitTypeId(runUnit)]
            if not (curUnit.flag and curUnitType.flag) then
                if curUnit.decay > 0 then
                    set decayTime = curUnit.decay
                elseif curUnitType.decay > 0 then
                    set decayTime = curUnitType.decay
                else
                    set decayTime = UNIT_DECAY
                endif
                if curUnit.decayTimer == 0 then
                    set runTimer = Timer.get()
                    set curTimer = CorpseTimer[GetHandleId(runTimer)]
                    set curTimer.decayUnit = curUnit
                    set curTimer.decayTimer = runTimer
                    set curUnit.decayTimer = curTimer
                    set curUnit.decayUnit = runUnit
                endif
                call TimerStart(curUnit.decayTimer.decayTimer, decayTime, false, function EndDecay)
            endif
        endif
        return false
    endfunction

    private function Initialization takes nothing returns nothing
        local integer x = 11
        set boolFunc = Condition(function StartDecay)
        call TriggerAddCondition(decayTrig, boolFunc)
        loop
            set x = x - 1
            call TriggerRegisterPlayerUnitEvent(decayTrig, GetPlayer(x), EVENT_PLAYER_UNIT_DEATH, null)
            exitwhen x == 0
        endloop
        //! runtextmacro CorpseManager_EXTRA_PLAYERS()
    endfunction
endlibrary


JASS:

scope Test initializer Initialization
    globals
        private constant integer unitTypeId = 'hpea'
        private constant real unitTypeDecayTime = 1

        private trigger tStart = CreateTrigger()
        private event e = TriggerRegisterTimerEvent(tStart, 0, false)
        private trigger t = CreateTrigger()
        private real x
        private real y
    endglobals

    private function Test takes nothing returns boolean
        local unit u = CreateUnit(Player(0), unitTypeId, GetUnitX(GetLastDecayedUnit()), GetUnitY(GetLastDecayedUnit()), 0)
        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetUnitName(GetLastDecayedUnit()) + " has decayed")
        call KillUnit(u)
        set u = null
        return false
    endfunction
    
    private function Start takes nothing returns boolean
        local unit u 
        set x = GetRectCenterX(bj_mapInitialPlayableArea)
        set y = GetRectCenterY(bj_mapInitialPlayableArea)
        set u = CreateUnit(Player(0), unitTypeId, x, y, 0)
        set u = CreateUnit(Player(0), unitTypeId, x, y, 0)
        call TriggerAddCondition(t, Condition(function Test))
        call PanCameraTo(x, y)
        call SetUnitTypeDecay(unitTypeId, unitTypeDecayTime)
        call KillUnit(u)
        set u = null
        call TriggerRegisterUnitTypeDecayEvent(t, unitTypeId)
        return false
    endfunction

    private function Initialization takes nothing returns nothing
        call TriggerAddCondition(tStart, Condition(function Start))
    endfunction
endscope
 
Reaction score
91
JASS:

        private constant string SYSTEM = "Udn"
        private constant string VERSION = "1.0"
        private constant string AUTHOR = "Nestharus"
        private constant string HELPERS = "None"
        private constant string TEXTURE_PATH = "ReplaceableTextures\\CommandButtons\\BTNAnimateDead.blp"
        private constant string DESCRIPTION = "Unit Decaying"

Remove this, it does nothing. Totally useless.
Such information should be put in a comment block.


Pretty interesting idea, although I seem to understand why nobody has created such thing before - it serves no purpose. Can you point a few uses of this? Besides, the interface of this system is totally awful... :(
 

RaiJin

New Member
Reaction score
40
JASS:
local unit triggerUnit = Udn_UdnSuspend_suspendedUnits[Udn_UdnSuspend_decayed]


at least make a wrapper function for these stuff T_T

graveyard? D:
 

Sevion

The DIY Ninja
Reaction score
413
Wow, Aaron, people absolutely HATE Mfn, huh? XD

@Tyrande

How is that "Totally useless."?

It creates the credit interface in the quests.

Read before commenting, plox.

Dunno why everyone says it's useless.

Though, I would like some enlightenment on why you'd want to access units that decayed for longer than 8 seconds. What is there to do?
 
Reaction score
91
> Read before commenting, plox.
I have, mostly the part where it was used:

JASS:

call Mfn_createCredit1(SYSTEM, VERSION, AUTHOR, HELPERS, TEXTURE_PATH, DESCRIPTION)


As I said, totally useless and pointless. Personally I'd never want some system to spam my F9 menu with useless texts which I would most likely put in a single Credits section with all the users credited.
 

Sevion

The DIY Ninja
Reaction score
413
Good luck keeping it nicely organized. I'd rather have this method of quest credits than what you suggested.
 

Sevion

The DIY Ninja
Reaction score
413
Doesn't mean it always has to.

Anywho, we're getting a bit off topic.

Aaron, I'm (we're) still waiting for an explanation on how this can be useful :-/
 

Jesus4Lyf

Good Idea™
Reaction score
397
I'm pretty sure AIDS's AIDS_onDestroy method would make this redundant? (If available, I mean it's a stupid assumption to assume everyone has AIDS. :p)

On a different note, I don't think I've ever seen such an ugly interface released on TheHelper. Write wrappers. Oh, and this looks like it should use Event.

/Insert standard Mfn hate comment.
 

Nestharus

o-o
Reaction score
84
Ok, I just woke up, so sorry for the delays ^^

1. I know the interface is ugly. Here's what I can do for everyone-

GetLastDecayingUnit() or GetLastTriggerUnit()
call TriggerRegisterPlayerUnitDecayEvent
call TriggerRegisterUnitDecayEvent

That will make the interface pretty ; p.


Next, more updates-
1.1 will support different decay times for dif unit types and dif units and a global decay time. If there is no unit decay time, it'll use unit type, and if that doesn't exit it'll use global.

There is current a bug for when units are revived etc. If they die before decay time, you'll see the bug.

Also, I'll add in something so that you can support all players on the map. Currently it only supports playing players, not playing computers or non playing players or anything above player 11.

And finally, it's use.

Well, I'm using it for a spell that spawns units when a unit decays. It makes it so raise has priority of the spells, but keeps the spell effects permanent while the unit is being revived/killed ^^. It'd also be interesting for reincarnation that doesn't work instantly, but works when your corpse decays ;p.

Those are just some uses ; ).
 

Nestharus

o-o
Reaction score
84
How is it not useful if you want to do something when a unit decays?

The unit decay event JASS gives is trash. It has a limit of 8 seconds even tho decay can go to w/e.
 

Nestharus

o-o
Reaction score
84
So? Use undefend to detect things that finish decaying.

(I think that works, anyway. )

???

No idea what you are talking about : D

oh and-
I'm pretty sure AIDS's AIDS_onDestroy method would make this redundant? (If available, I mean it's a stupid assumption to assume everyone has AIDS. )

On a different note, I don't think I've ever seen such an ugly interface released on TheHelper. Write wrappers. Oh, and this looks like it should use Event.

/Insert standard Mfn hate comment.

My question is does the unit on the map still exist? If AIDS was designed sensibly, and I know it was because it was designed by you, then it would run the destruction methods when the unit no longer existed on the map : ).

Now, if AIDS called the stuff right before the unit was permanently removed, then hm... makes me want to use this to design something... and now I get why someone asked me to design unit indexing and recycling with this so that they'd have access to a unit and decide whether or not to remove it as it was being destroyed : o.

Hmmmmmm... interesting ideas ^^

And I know you have lock struct and what not, but does that keep a unit from actually being removed from the map? : o.

Interesting thoughts ^^
 

Switch33

New Member
Reaction score
12
So? Use undefend to detect things that finish decaying.

(I think that works, anyway. )
Jesus4Lyf is talking about this:
http://www.wc3c.net/showthread.php?t=102588

Basically it's a bug that an unit with an dummy defend ability that is set on is issued undefend when they die, finish decaying,is reanimated, removed, ressurected etc.

As for keeping corpses this isn't all that helpful. Since corpses seem to take up more CPU power which would mean less units and less combat action most likely. Although it might be useful for some maps. It's not great for maps that are overly excessive in creating large armies i'd say.
 

Jesus4Lyf

Good Idea™
Reaction score
397
AIDS_onDestroy fires after the unit no longer exists, as you described.

And yes, that's what I was talking about. This system is actually redundant.

Unless you want to scrap everything in it and make it a tiny snippet based on undefend. :p

Be sure to use the object merger. AutoIndex even has the ability you probably need (a dummy defend) already in object merger syntax. You may like to take a look.
 

Nestharus

o-o
Reaction score
84
AIDS_onDestroy fires after the unit no longer exists, as you described.

And yes, that's what I was talking about. This system is actually redundant.

Unless you want to scrap everything in it and make it a tiny snippet based on undefend.

Be sure to use the object merger. AutoIndex even has the ability you probably need (a dummy defend) already in object merger syntax. You may like to take a look.

This gives a working EVENT_PLAYER_UNIT_DECAY, so AIDS is irrelevant, because AIDS doesn't work off of decay but off of removal. It's like comparing apples and oranges. If I want an event to fire off during decay and not removal, it better fire off during decay = ).

Jesus4Lyf is talking about this:
http://www.wc3c.net/showthread.php?t=102588

Basically it's a bug that an unit with an dummy defend ability that is set on is issued undefend when they die, finish decaying,is reanimated, removed, ressurected etc.

As for keeping corpses this isn't all that helpful. Since corpses seem to take up more CPU power which would mean less units and less combat action most likely. Although it might be useful for some maps. It's not great for maps that are overly excessive in creating large armies i'd say.

Again, irrelevant. You can't even get when a unit finishes decaying with plain JASS =).

Also, keeping corpses? So you're saying you do this?
Set gamplay decay constants all to 0
or​
call RemoveUnit() on death

???

Last time I checked, every combat map I've played has had corpses ; ). It's wc3 default.

And, I used this in a map that usually had 1000+ units in play at a time. It's even had 6k in play, constant dying etc.

I fail to see your point ^^
 

Jesus4Lyf

Good Idea™
Reaction score
397
>Again, irrelevant. You can't even get when a unit finishes decaying with plain JASS =).
We're telling you to use undefend to detect that. That's also what the entirety of my post was about except for the first line. (Not about AIDS.)

That's about as far from irrelevant as you can get, isn't it? :(
 

Nestharus

o-o
Reaction score
84
We're telling you to use undefend to detect that. That's also what the entirety of my post was about except for the first line. (Not about AIDS.)

That's about as far from irrelevant as you can get, isn't it?

You'd lose the unit : (, and at that point you might as well use AIDS because it'd do the same thing /cry.

It'd also bug on things like RemoveUnit() =(

If I want an event to fire off during decay and not removal, it better fire off during decay = ).
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top