Unit Loss

Caedin88

New Member
Reaction score
1
I have a trigger that basically says the following...

A Unit Dies

Wait 60 seconds

Revive unit at place of dying units death.



I know that using Dying Unit after a 60 second wait is a bad idea so I replaced the reference of Dying unit to a local unit variable.

Even when using a local unit variable only about half of the dying units are being revived.

This is the custom text of the trigger...

JASS:

function Trig_Respawn_Copy_Func003Func002C takes nothing returns boolean
    if ( ( GetOwningPlayer(GetDyingUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) ) ) then
        return true
    endif
    if ( ( GetOwningPlayer(GetDyingUnit()) == Player(PLAYER_NEUTRAL_PASSIVE) ) ) then
        return true
    endif
    return false
endfunction

function Trig_Respawn_Copy_Func003Func003C takes nothing returns boolean
    if ( not ( GetHeroLevel(GetDyingUnit()) <= 4 ) ) then
        return false
    endif
    if ( not ( GetRandomInt(1, 8) == 1 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Respawn_Copy_Func003Func004C takes nothing returns boolean
    if ( not ( GetHeroLevel(GetDyingUnit()) <= 8 ) ) then
        return false
    endif
    if ( not ( GetHeroLevel(GetDyingUnit()) > 4 ) ) then
        return false
    endif
    if ( not ( GetRandomInt(1, 8) == 1 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Respawn_Copy_Func003Func005C takes nothing returns boolean
    if ( not ( GetHeroLevel(GetDyingUnit()) <= 15 ) ) then
        return false
    endif
    if ( not ( GetHeroLevel(GetDyingUnit()) > 8 ) ) then
        return false
    endif
    if ( not ( GetRandomInt(1, 8) == 1 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Respawn_Copy_Func003Func006C takes nothing returns boolean
    if ( not ( GetHeroLevel(GetDyingUnit()) <= 25 ) ) then
        return false
    endif
    if ( not ( GetHeroLevel(GetDyingUnit()) > 15 ) ) then
        return false
    endif
    if ( not ( GetRandomInt(1, 8) == 1 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Respawn_Copy_Func003Func007C takes nothing returns boolean
    if ( not ( GetHeroLevel(GetDyingUnit()) > 25 ) ) then
        return false
    endif
    if ( not ( GetRandomInt(1, 8) == 1 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Respawn_Copy_Func003Func016C takes nothing returns boolean
    if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_HERO) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_Respawn_Copy_Func003C takes nothing returns boolean
    if ( not Trig_Respawn_Copy_Func003Func002C() ) then
        return false
    endif
    if ( not ( GetUnitTypeId(GetDyingUnit()) != 'H009' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Respawn_Copy_Actions takes nothing returns nothing
    local unit DIED
    set DIED = GetDyingUnit()
    if ( Trig_Respawn_Copy_Func003C() ) then
        set DIED = GetDyingUnit()
        if ( Trig_Respawn_Copy_Func003Func003C() ) then
            call CreateItemLoc( ChooseRandomItemExBJ(1, ITEM_TYPE_ANY), GetUnitLoc(GetDyingUnit()) )
        else
        endif
        if ( Trig_Respawn_Copy_Func003Func004C() ) then
            call CreateItemLoc( ChooseRandomItemExBJ(2, ITEM_TYPE_ANY), GetUnitLoc(GetDyingUnit()) )
        else
        endif
        if ( Trig_Respawn_Copy_Func003Func005C() ) then
            call CreateItemLoc( ChooseRandomItemExBJ(3, ITEM_TYPE_ANY), GetUnitLoc(GetDyingUnit()) )
        else
        endif
        if ( Trig_Respawn_Copy_Func003Func006C() ) then
            call CreateItemLoc( ChooseRandomItemExBJ(4, ITEM_TYPE_ANY), GetUnitLoc(GetDyingUnit()) )
        else
        endif
        if ( Trig_Respawn_Copy_Func003Func007C() ) then
            call CreateItemLoc( ChooseRandomItemExBJ(GetRandomInt(5, 8), ITEM_TYPE_ANY), GetUnitLoc(GetDyingUnit()) )
        else
        endif
        set udg_Bounty = ( GetRandomInt(1, 2) * ( GetHeroLevel(GetDyingUnit()) * GetHeroLevel(GetKillingUnitBJ()) ) )
        call AdjustPlayerStateBJ( udg_Bounty, GetOwningPlayer(GetKillingUnitBJ()), PLAYER_STATE_RESOURCE_GOLD )
        call CreateTextTagLocBJ( ( I2S(udg_Bounty) + "!" ), GetUnitLoc(GetDyingUnit()), 0, 10, 100.00, 100, 0.00, 0.00 )
        call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 64, 90 )
        call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
        call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 4 )
        call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 5 )
        call TriggerSleepAction( 90.00 )
        if ( Trig_Respawn_Copy_Func003Func016C() ) then
            call ReviveHeroLoc( DIED, GetUnitLoc(DIED), false  )
            call SetHeroLevelBJ( DIED, ( udg_AvgLevel[2] / udg_AvgLevel[1] ),false)
        else
            call CreateNUnitsAtLoc( 1, GetUnitTypeId(DIED), GetOwningPlayer(DIED), GetUnitLoc(DIED), GetUnitFacing(DIED))
            call RemoveUnit( DIED)
        endif
    else
    endif
    set DIED = null
endfunction
 

Caedin88

New Member
Reaction score
1
Bump.... This trigger is almost an exact copy of what is found here...
http://world-editor-tutorials.thehelper.net/revive.php

In that example they use local variables and a wait and a revive...
I can't figure out why only about half of my dying heroes are being revived.

Worth mentioning... If I remove the wait entirely all units revive perfectly with no lost units. Any help would be appreciated.
 

trb92

Throwing science at the wall to see what sticks
Reaction score
142
GetUnitLoc(DIED)

That location might not exist after the wait, since the unit is gone and no location is found for that. Try saving that location in a variable at the start of the trigger, then revive at the variable.
 

Caedin88

New Member
Reaction score
1
I have added the following variable

local location DIEDLOC
set DIEDLOC = GetUnitLoc(DIED)

and replaced

call ReviveHeroLoc( DIED, GetUnitLoc(DIED), false )

with

call ReviveHeroLoc( DIED, DIEDLOC, false )


Still doesn't work... same response on my test, I start with 53 heroes then run a kill all units trigger wait 90 seconds and recount and I come up with about 30 everytime.


UPDATE: I tested replacing

call ReviveHeroLoc( DIED, GetUnitLoc(DIED), false )

with

call ReviveHeroLoc( DIED,GetRectCenter(GetPlayableMapRect()), false )

after the test I still recieved only 30 units when I started with 53. Its worth noting that the units who revive and the units who do not are always the same when I Test using World Editor.

This leads me to believe the problem isn't with GetUnitLoc(DIED) not returning a value.

UPDATE:

Okay so I think I've found the problem... it lies with my conditional

JASS:
function Trig_Respawn_Func005Func016C takes nothing returns boolean
    if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_HERO) == true ) ) then
        return false
    endif
    return true
endfunction


I need to rewrite this conditional but I keep getting compile errors, this is what im trying...

JASS:
function Trig_Respawn_Func005Func016C takes nothing returns boolean
    if ( not ( IsUnitType(DIED, UNIT_TYPE_HERO) == true ) ) then
        return false
    endif
    return true
endfunction


Where as DIED is my local variable... but I don't know how to do this in GUI so I tried to do it in JASS but It is giving me a long list of errors.

I believe this is because, I read somewhere that local variables are only accessable within the function they are declared, so how do I pass my local unit variable DIED to the conditional function?

Thanks in advance! NOTE: I bypassed this conditional and still lost units, so this isn't the problem :(

UPDATE: I re-tested with zero wait between death and respawn and I still lost units... from 52 to 50 not nearly as many as with the 90 second wait which resulted in 52 to 30.

UPDATE: Okay I have narrowed down the problem to within this set of code... but I can't find it.

JASS:
function Trig_Respawn_test_Actions takes nothing returns nothing
    local unit DIED
    local location DIEDLOC
    set DIED = GetDyingUnit()
    set DIEDLOC =  GetUnitLoc(DIED)
    call ReviveHeroLoc( DIED,DIEDLOC, false  )
    set DIED = null
    set DIEDLOC = null
endfunction

//===========================================================================
function InitTrig_Respawn_test takes nothing returns nothing
    set gg_trg_Respawn_test = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Respawn_test, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddAction( gg_trg_Respawn_test, function Trig_Respawn_test_Actions )
endfunction


For some reason if 52 heroes die at the same time only 50 respawn with this trigger, leaving 2 lost from the game. I don't see why...

In testing i've found the following

no wait between death and revive = 52 die 50 revive
1 second wait between death and revive = 52 die 52 revive
90 second wait between death and revive = 52 die 29 revive

It seems almost lacking a pattern and I can't figure it out.
 
Reaction score
456
Do you still have the GUI version somewhere, because reading that text is like pain in the ass?

JASS:
function Trig_Respawn_Copy_Actions takes nothing returns nothing
    local unit DIED = GetDyingUnit()
    
    if (GetOwningPlayer(DIED) == 12 and GetOwningPlayer(DIED) == 15) and (GetUnitTypeId(DIED) == 'H009') then
        set udg_Bounty = (GetRandomInt(1, 2) * (GetHeroLevel(DIED) * GetHeroLevel(GetKillingUnit())))
        call AdjustPlayerStateBJ(udg_Bounty, GetOwningPlayer(GetKillingUnit()), PLAYER_STATE_RESOURCE_GOLD )
        call CreateTextTagLocBJ((I2S(udg_Bounty) + "!" ), GetUnitLoc(DIED), 0, 10, 100.00, 100, 0.00, 0.00 )
        call SetTextTagVelocityBJ(bj_lastCreatedTextTag, 64, 90)
        call SetTextTagPermanentBJ(bj_lastCreatedTextTag, false)
        call SetTextTagFadepointBJ(bj_lastCreatedTextTag, 4)
        call SetTextTagLifespanBJ(bj_lastCreatedTextTag, 5)
        
        call TriggerSleepAction(90.00)
        
        if IsUnitType(DIED, UNIT_TYPE_HERO) then
            call ReviveHeroLoc(DIED, GetUnitLoc(DIED), false )
            call SetHeroLevelBJ(DIED, (udg_AvgLevel[2] / udg_AvgLevel[1]), false)
        else
            call CreateNUnitsAtLoc(1, GetUnitTypeId(DIED), GetOwningPlayer(DIED), GetUnitLoc(DIED), GetUnitFacing(DIED))
            call RemoveUnit(DIED)
        endif
    endif
    
    set DIED = null
endfunction


Does this work better? I removed the item drop part for a while..
 

Caedin88

New Member
Reaction score
1
Code:
Respawn
    Events
        Unit - A unit Dies
    Conditions
    Actions
        Custom script:   local unit DIED
        Custom script:   local location DIEDLOC
        Custom script:   set DIED = GetDyingUnit()
        Custom script:   set DIEDLOC =  GetUnitLoc(DIED)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                Or - Any (Conditions) are true
                    Conditions
                        (Owner of (Dying unit)) Equal to Neutral Hostile
                        (Owner of (Dying unit)) Equal to Neutral Passive
                (Unit-type of (Dying unit)) Not equal to Shadow
            Then - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Hero level of (Dying unit)) Less than or equal to 4
                        (Random integer number between 1 and 8) Equal to 1
                    Then - Actions
                        Item - Create (Random level 1 Any Class item-type) at (Position of (Dying unit))
                    Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Hero level of (Dying unit)) Less than or equal to 8
                        (Hero level of (Dying unit)) Greater than 4
                        (Random integer number between 1 and 8) Equal to 1
                    Then - Actions
                        Item - Create (Random level 2 Any Class item-type) at (Position of (Dying unit))
                    Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Hero level of (Dying unit)) Less than or equal to 15
                        (Hero level of (Dying unit)) Greater than 8
                        (Random integer number between 1 and 8) Equal to 1
                    Then - Actions
                        Item - Create (Random level 3 Any Class item-type) at (Position of (Dying unit))
                    Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Hero level of (Dying unit)) Less than or equal to 25
                        (Hero level of (Dying unit)) Greater than 15
                        (Random integer number between 1 and 8) Equal to 1
                    Then - Actions
                        Item - Create (Random level 4 Any Class item-type) at (Position of (Dying unit))
                    Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Hero level of (Dying unit)) Greater than 25
                        (Random integer number between 1 and 8) Equal to 1
                    Then - Actions
                        Item - Create (Random level (Random integer number between 5 and 8) Any Class item-type) at (Position of (Dying unit))
                    Else - Actions
                Set Bounty = ((Random integer number between 1 and 2) x ((Hero level of (Dying unit)) x (Hero level of (Killing unit))))
                Player - Add Bounty to (Owner of (Killing unit)) Current gold
                Floating Text - Create floating text that reads ((String(Bounty)) + !) at (Position of (Dying unit)) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 0.00%), and 0.00% transparency
                Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
                Floating Text - Change (Last created floating text): Disable permanence
                Floating Text - Change the fading age of (Last created floating text) to 4.00 seconds
                Floating Text - Change the lifespan of (Last created floating text) to 5.00 seconds
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        ((Dying unit) is A Hero) Equal to True
                    Then - Actions
                        Wait 90.00 seconds
                        Custom script:   call ReviveHeroLoc( DIED,DIEDLOC, false  )
                        Custom script:   call SetHeroLevelBJ( DIED, ( udg_AvgLevel[2] / udg_AvgLevel[1] ),false)
                    Else - Actions
                        Wait 90.00 seconds
                        Custom script:   call CreateNUnitsAtLoc( 1, GetUnitTypeId(DIED), GetOwningPlayer(DIED), DIEDLOC, GetUnitFacing(DIED))
                        Custom script:   call RemoveUnit( DIED)
            Else - Actions
        Custom script:   set DIED = null
        Custom script:   set DIEDLOC = null

And I tried yours and no luck :(
 
Reaction score
456
JASS:
function Trig_Respawn_Copy_Actions takes nothing returns nothing
    local unit DIED = GetDyingUnit()
    
    if (GetOwningPlayer(DIED) == 12 or GetOwningPlayer(DIED) == 15) and (GetUnitTypeId(DIED) != 'H009') then
        set udg_Bounty = (GetRandomInt(1, 2) * (GetHeroLevel(DIED) * GetHeroLevel(GetKillingUnit())))
        call AdjustPlayerStateBJ(udg_Bounty, GetOwningPlayer(GetKillingUnit()), PLAYER_STATE_RESOURCE_GOLD )
        call CreateTextTagLocBJ((I2S(udg_Bounty) + "!" ), GetUnitLoc(DIED), 0, 10, 100.00, 100, 0.00, 0.00 )
        call SetTextTagVelocityBJ(bj_lastCreatedTextTag, 64, 90)
        call SetTextTagPermanentBJ(bj_lastCreatedTextTag, false)
        call SetTextTagFadepointBJ(bj_lastCreatedTextTag, 4)
        call SetTextTagLifespanBJ(bj_lastCreatedTextTag, 5)
        
        call TriggerSleepAction(90.00)
        
        if IsUnitType(DIED, UNIT_TYPE_HERO) then
            call ReviveHeroLoc(DIED, GetUnitLoc(DIED), false )
            call SetHeroLevelBJ(DIED, (udg_AvgLevel[2] / udg_AvgLevel[1]), false)
        else
            call CreateNUnitsAtLoc(1, GetUnitTypeId(DIED), GetOwningPlayer(DIED), GetUnitLoc(DIED), GetUnitFacing(DIED))
            call RemoveUnit(DIED)
        endif
    endif
    
    set DIED = null
endfunction


Try it like that. I had messed the conditions.
 

Caedin88

New Member
Reaction score
1
I've solved the problem by giving all Neutral Hostile and Neutral Passive units in my game a reincarnation spell with 0 cooldown and 90 second delay to revive.
 

Caedin88

New Member
Reaction score
1
I've solved the problem by giving all Neutral Hostile and Neutral Passive units in my game a reincarnation spell with 0 cooldown and 90 second delay to revive.

Nevermind, it seems if you kill a unit with reincarnation up it doesn't count as a kill, thus I earn no exp and get no gold. Looking for another solution... :(
 
Reaction score
456
That function really should revive hostile and passive units that are not 'Shadow's. And I am not sure if you even tried that, because it should give syntax errors.

JASS:
function Trig_Respawn_Copy_Actions takes nothing returns nothing
    local unit DIED = GetDyingUnit()
    local boolean isHero = IsUnitType(DIED, UNIT_TYPE_HERO)
    local player owner = GetOwningPlayer(DIED)
    local integer typeId = GetUnitTypeId(DIED)
    local location loc = GetUnitLoc(DIED)
    
    if (owner == Player(12) or owner == Player(15)) and (typeId != 'H009') then
        set udg_Bounty = (GetRandomInt(1, 2) * (GetHeroLevel(DIED) * GetHeroLevel(GetKillingUnit())))
        call AdjustPlayerStateBJ(udg_Bounty, GetOwningPlayer(GetKillingUnit()), PLAYER_STATE_RESOURCE_GOLD )
        call CreateTextTagLocBJ((I2S(udg_Bounty) + "!" ), loc, 0, 10, 100.00, 100, 0.00, 0.00 )
        call SetTextTagVelocityBJ(bj_lastCreatedTextTag, 64, 90)
        call SetTextTagPermanentBJ(bj_lastCreatedTextTag, false)
        call SetTextTagFadepointBJ(bj_lastCreatedTextTag, 4)
        call SetTextTagLifespanBJ(bj_lastCreatedTextTag, 5)
        
        call TriggerSleepAction(90.00)
        
        if isHero then
            call ReviveHeroLoc(DIED, loc, false)
            call SetHeroLevelBJ(DIED, (udg_AvgLevel[2] / udg_AvgLevel[1]), false)
            call BJDebugMsg("Hero " + GetUnitName(DIED))
        else
            call CreateNUnitsAtLoc(1, typeId, owner, loc, GetUnitFacing(DIED))
            call RemoveUnit(DIED)
            call BJDebugMsg("Normal " + GetUnitName(DIED))
        endif
    endif
    
    call RemoveLocation(loc)
    set loc = null
    set DIED = null
endfunction

That's my last try, if it doesn't work I have no idea what's wrong.

Try these:

1. Kill hostile unit (non-hero) - should display "Normal" plus it's name. (after 90 seconds)
2. Kill hostile unit (hero) - should display "Hero" plus it's name. (after 90 seconds)
3. Kill a 'Shadow' - shouldn't display anything.
4. Try those with passive units too.
 

Caedin88

New Member
Reaction score
1
No Luck, I killed heroes and normals for both neutral hostile and neutral passive. No messages or respawns. And as far as the syntax, I removed the part of the conditional pertaining to shadow's because it didn't really apply and thats where the syntax error was, then tested it.

Thanks for your help, + rep for the effort.

I have found a semi-solution using reincarnation and an array of other triggers to simulate what would normally happen when you kill a unit. Such as EXP and gold increase. I have tried everything on this, even copied Ryoko's Hero Revival system untouched and put it into my map and it still missed the same exact units on revive as my triggers... I think its some kind of leak or somthing I don't know.

I have uploaded the map in the exact order in which I tested it, my other system of revival has been turned off and this trigger added to the custom script code, run the map, turn on whosyourdaddy to kill some stuff quickly and easily and test it yourself if you wish.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top