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

[JASS] Creep Respawn system

Status
Not open for further replies.
Level 3
Joined
Mar 20, 2008
Messages
27
Okay so i've been trying to create a respawn system that goes like:
Each creep has its own spawn region, each region and creep is assigned to an array, where the region index is equal to the creep index. it looks like this:
JASS:
function Trig_BaseUnitRespawn_Actions takes nothing returns nothing
    local unit m = GetDyingUnit()
    local integer ml = GetUnitLevel(m)
    local unittype mt = GetUnitTypeId(m)
    local player p = GetOwningPlayer(m)
    local integer i = 0
    local integer c = 0
    
    local real t = I2R(ml)+10.
    local real f = 0.
    local real x = 0.
    local real y = 0.

    loop
        exitwhen c == 1
        if IsUnit(m, udg_UnA_Lvl1[i]) then
            set c = 1
            set f = GetUnitFacing(m)
            set x = GetRectCenterX(udg_ReA_Lvl1[i])
            set y = GetRectCenterY(udg_ReA_Lvl1[i])
            call TriggerSleepAction(t)
            call CreateUnit(p, mt, x, y, f)
        endif
        set i = i+1
    endloop
    set m = null
    set p = null
endfunction

//==== Init Trigger BaseUnitRespawn ====
function InitTrig_BaseUnitRespawn takes nothing returns nothing
    local trigger BaseUnitRespawn = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(BaseUnitRespawn, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddAction(BaseUnitRespawn, function Trig_BaseUnitRespawn_Actions)
endfunction
The problem is, i'm new at jass, and i can't tell what fails in this script :p
So please help a newbie there thanks in advance :wink:
 
Last edited:
Level 4
Joined
Mar 14, 2009
Messages
98
Maybe you meant "set udg_UnA_Lvl1 = CreateUnit(p, mt, x, y, f)"? I dunno, maybe you have that somewhere else. And have the creeps been initialized into that array? If they haven't it would lead to an infinite loop. (Which warcraft 3 will terminate anyway.)
 
Level 5
Joined
Dec 18, 2007
Messages
205
hi once again

so first of all it is an infinite loop if a unit dies that is not in that array. tzo fix it just do the following:

JASS:
exitwhen set c = 1 or udg_UnA_Lvl1[i]==null

this requires of course that there is no empty array value, but i don't think that you have one empty array value. the problem would be that if the unit is dead, an it's corspe is .. eer dead (don't know the word atm xD) the unit array will probably be empty. so i suggest to create a dummy at the position of the dying unit (which has no model and the locust ability) and then set the array to the dummy, so the unit array won't be empty while the creep ot his corpse are not found. after the wait action, ust create the unit as usual and set the array again to that value as peetoon told you.

and one little thing to imrpove: triggers leak, but you cannot destroy them, toherwise your function could not be called, so just null them and you have one small leak less:

JASS:
set BaseUnitRespawn=null

one more thing:
instead of using a unittype use an integer, even the funciton says getunittypeid()
JASS:
local integer mt = GetUnitTypeId(m)

good luck
 
Level 3
Joined
Mar 20, 2008
Messages
27
I did what you said breathless and it now works completely fine :D i will give you rep for that :thumbs_up: the script looks like this now
JASS:
function Trig_BaseUnitRespawn_Actions takes nothing returns nothing
    local unit m = GetDyingUnit()
    local integer ml = GetUnitLevel(m)
    local integer mid = GetUnitTypeId(m)
    local player p = GetOwningPlayer(m)
    local integer i = 0
    local integer c = 0

    local real t = I2R(ml)+10.
    local real f = 0.
    local real x = 0.
    local real y = 0.

    loop
        exitwhen c == 1 or udg_UnA_Lvl1[i] == null
        if IsUnit(m, udg_UnA_Lvl1[i]) then
            set c = 1
            set f = GetUnitFacing(m)
set x = GetRectCenterX(udg_ReA_Lvl1[i])
            set y = GetRectCenterY(udg_ReA_Lvl1[i])
            call TriggerSleepAction(t)
            call CreateUnit(p, mid, x, y, f)
        endif
        set i = i+1
    endloop
    set m = null
    set p = null
endfunction

//==== Init Trigger BaseUnitRespawn ====
function InitTrig_BaseUnitRespawn takes nothing returns nothing
    local trigger BaseUnitRespawn = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(BaseUnitRespawn, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddAction(BaseUnitRespawn, function Trig_BaseUnitRespawn_Actions)
    set BaseUnitRespawn = null
endfunction
I might come with more scripts to solve soon time will show that, see you later here at the Hive :csmile:
 
Level 5
Joined
Dec 18, 2007
Messages
205
yeah ok, but could you try just one more thing?
set the decay of the corpse (this is the word i looke for i think :D ) to a very small amount (like 5 seconds) OR remove the unit from the game 5 seconds after it is killed and set the triggersleepaction to more than 5 seconds (~7seconds)
does the script still work, even if you kill multiple creeps?
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
Well, though this might work, you still got some rects, A.K.A. Regions,,
I assume you created the units in WE, and not during the game (through triggers)
cause then you could use something like Paladons Creep Revive System,,
though this uses vJass, and might be unefficient, due to me making this xD
JASS:
scope CreepRevival initializer Init
    globals
        private group Revivables = CreateGroup()
    endglobals
    private struct Revive
        real x
        real y
        integer Id
        real f
        player own
    private function Revive takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local unit n
        local Revive dat = GetUnitUserData(u)
        call TriggerSleepAction(5)
        set n = CreateUnit(dat.own, dat.Id, dat.x, dat.y, dat.f)
        call SetUnitUserData(n, dat)
        set u = null
        set n = null
    endfunction
    private function Conditions takes nothing returns boolean
       return true // set your condition here
    private function Set takes nothing returns nothing
        local Revive dat = Revive.allocate()
        local unit u = GetEnumUnit()
        set dat.x = GetUnitX(u)
        set dat.y = GetUnitY(u)
        set dat.f = GetUnitFacing(u)
        set dat.Id = GetUnitTypeId(u)
        set dat.own = GetOwningPlayer(u)
        set u = null
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        loop
            exitwhen i > 15
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_DEATH)
            set i = i + 1
        endloop
        set Revivables = GroupEnumUnitsInRect(Revivables, bj_mapInitialPlayableArea, Condition(function Conditions))
        call ForGroup(Revivables, function Set)
        call TriggerAddAction(t, function Revive)
    endfunction
endscope
 
Last edited:
Level 3
Joined
Mar 20, 2008
Messages
27
I would think so to, but i just experienced a flaw, the units will only respawn 1 time, since they are not assigned again to the same array index :( and i tried putting something like this in at the end of the if.
JASS:
set udg_UnA_Lvl1[i] = GetLastCreatedUnit()
and i tried this
JASS:
Set udg_UnA_Lvl1[i] = bj_lastCreatedUnit
but neither of them works so i checked automated generated function by the WE and it looks like this:
JASS:
function InitGlobals takes nothing returns nothing
    local integer i = 0
    set i = 0
    loop
        exitwhen (i > 5)
        set udg_UnA_Lvl1[i] = null
        set i = i + 1
    endloop

    set i = 0
    loop
        exitwhen (i > 5)
        set udg_ReA_Lvl1[i] = null
        set i = i + 1
    endloop

endfunction
Could this have something to do with it ? Or am i making a mistake (again) here?
 
Level 4
Joined
Mar 14, 2009
Messages
98
Instead of "call CreateUnit(p, mt, x, y, f)", use "set udg_UnA_Lvl1 = CreateUnit(p, mt, x, y, f)"

CreateUnit returns a unit, so you're allowed to do that. Of course, since you ignored my earlier post, I had assumed that you have some sort of trigger somewhere that detects when a unit was created and added that to an array automatically.

P.S. Handle variables don't get nulled automatically when the handle is removed, hence your array won't have holes even when the unit has died unless you explicitly null the variables as the unit dies. Nothing was wrong with your original code except that you forgot to add the newly created units to the array and the unittype leaking, but someone already pointed that out. (Unless you didn't initialize the variables elsewhere.)
 
Last edited:
Level 3
Joined
Mar 20, 2008
Messages
27
Okay so instead of
JASS:
call CreateUnit(p, mid, x, y, f)
i do this
JASS:
set udg_UnA_Lvl1[i] =CreateUnit(p, mid, x, y, f)
Thanks at first it seems confusing, but now it seems more logical :D
Edit:
Yixx its great that you try to help, but i prefer to make my own triggers (with help from others ofc) :D but thanks anyway
 
Status
Not open for further replies.
Top