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

[JASS] Respawn Unit system

Status
Not open for further replies.
Level 19
Joined
Oct 29, 2007
Messages
1,184
I am creating a respawn system for neutral passive controlled units. This is the code I have:

JASS:
scope Initialization initializer InitInit

    function InitInit takes nothing returns nothing
        local rect r = bj_mapInitialPlayableArea
        local location l
        local integer i = 0
        local real x
        local real y
        local integer random
    
        loop
            set x = GetRandomReal(GetRectMinX(r), GetRectMaxX(r))
            set y = GetRandomReal(GetRectMinY(r), GetRectMaxY(r))
            set l = Location(x,y)
            set random = GetRandomInt(0, 4)
            if random == 0  then
                call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvlk',x,y,0)
            elseif random == 1 then
                call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvk2',x,y,0)
            elseif random == 2 then
                call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvlw',x,y,0)
            elseif random == 3 then
                call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvl2',x,y,0)
            elseif random == 4 then
                call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvil',x,y,0)
            endif
            set udg_Citizen[i] = bj_lastCreatedUnit
            set udg_CitizenStartLocX[i] = x
            set udg_CitizenStartLocY[i] = y
            call SetUnitUserData(udg_Citizen[i], i )
        
            set i = i + 1
            exitwhen i == 199
        endloop

    call RemoveLocation(l)
    endfunction

endscope


scope Citizendies initializer InitCitizendies
    
    function respawncitizen takes nothing returns nothing
        
        local unit u = GetDyingUnit()
        local integer i = GetUnitUserData(u)
        
        call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), GetUnitTypeId(u), -1600,2000, 0)
        call RemoveUnit(u)
        set u = bj_lastCreatedUnit
        call IssuePointOrder(u, "move" , udg_CitizenStartLocX[i], udg_CitizenStartLocY[i])
        call SetUnitUserData(u, i )
        call fade(u)
        set u = null
        
    endfunction


    function InitCitizendies takes nothing returns nothing

    local trigger t = CreateTrigger()
    
    call TriggerRegisterPlayerUnitEvent(t, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_DEATH, null)

    call TriggerAddAction(t, function respawncitizen)
    set t = null
    endfunction

endscope

Why does bj_lastCreatedUnit seem to refer to a unit I created earlier using GUI, and not the units I am creating within this code?
 
Level 19
Joined
Oct 29, 2007
Messages
1,184
I've gotten a little further. Everything works fine, exept it seems as if udg_CitizenStartLocX and udg_CitizenStartLocY aren't stored by the first function. The spawning units are all moving to origo. How do I store these values?

JASS:
scope Initialization initializer Init

    function Init takes nothing returns nothing
        local rect r = bj_mapInitialPlayableArea
        local integer i = 0
        local real x
        local real y
        local integer random
        local real randomdeg
        local unit u
    
        loop
            set x = GetRandomReal(GetRectMinX(r), GetRectMaxX(r))
            set y = GetRandomReal(GetRectMinY(r), GetRectMaxY(r))
            set random = GetRandomInt(0, 4)
            set randomdeg = GetRandomReal(0,359.99)
            if random == 0  then
                set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvlk',x,y,randomdeg)
            elseif random == 1 then
                set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvk2',x,y,randomdeg)
            elseif random == 2 then
                set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvlw',x,y,randomdeg)
            elseif random == 3 then
                set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvl2',x,y,randomdeg)
            elseif random == 4 then
                set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nvil',x,y,0)
            endif
            set udg_Citizen[i] = u
            set udg_CitizenStartLocX[i] = x
            set udg_CitizenStartLocY[i] = y
            call SetUnitUserData(u, i )
        
            set i = i + 1
            exitwhen i == 199
        endloop


    set u = null
    endfunction

endscope


scope Citizendies initializer InitCitizendies
    
    function respawncitizen takes nothing returns nothing
        local unit dyingunit = GetTriggerUnit()
        local unit u 
        local integer i = GetUnitUserData(dyingunit)
        
        
        set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), GetUnitTypeId(dyingunit), -1600,2000, 0)
        call RemoveUnit(dyingunit)
        
        call IssuePointOrder(u, "move" , udg_CitizenStartLocX[i], udg_CitizenStartLocY[i])
        call SetUnitUserData(u, i )
        call fade(u)
        
        set u = null
        set dyingunit = null
    endfunction


    function InitCitizendies takes nothing returns nothing

    local trigger t = CreateTrigger()
    
    call TriggerRegisterPlayerUnitEvent(t, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_DEATH, null)

    call TriggerAddAction(t, function respawncitizen)
    set t = null
    endfunction

endscope
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
its working for me, I disabled the call fade(u) coz idk what is that...
btw, I suggest you put your random in an arrayed integer variable and your rect leaks...

JASS:
scope Initialization initializer Init
    globals
       private integer array uType
    endglobals

    function Init takes nothing returns nothing
        local rect r = bj_mapInitialPlayableArea
        local integer i = 0
        local real x
        local real y
        local integer random
        local unit u
        set uType[0] = 'nvlk'
        set uType[1] = 'nvk2'
        set uType[2] = 'nvlw'
        set uType[3] = 'nvl2'
        set uType[4] = 'nvil'
    
        loop
            set x = GetRandomReal(GetRectMinX(r), GetRectMaxX(r))
            set y = GetRandomReal(GetRectMinY(r), GetRectMaxY(r))
            set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), uType[GetRandomInt(0,4)],x,y,GetRandomReal(0,6.2)*bj_RADTODEG)
            set udg_Citizen[i] = u
            set udg_CitizenStartLocX[i] = x
            set udg_CitizenStartLocY[i] = y
            call SetUnitUserData(u, i )
        
            set i = i + 1
            exitwhen i == 199
        endloop


    set u = null
    set r = null
    endfunction

endscope

EDIT:
lastly, you should not set the user's custom data manually as this may affect systems like
UnitIndexer, use UnitIndexer systems instead to do this...
 
Level 8
Joined
Dec 30, 2011
Messages
134
I made THIS system for you :)

0% LEAKS - LAG - BUG - DESYNC - ETC.
100% READABLE AND EASY TO USE

JASS:
/**************************************************************************************************************
            I made this system for 'Megafyr'
            His user: "http://www.hiveworkshop.com/forums/members/megafyr/"
            
            This is a basic respawn system, you can use it with two differents functions.
            
            FOR EXAMPLE:
            EVENT
                UNIT DIES
            CONDITIONS
                IS UNIT TYPE PEASANT
            ACTIONS
            
                call Respawn_Instantly(DIE UNIT, RESPAWN AT STARTING POINT)
                ||
                \/
                call Respawn_Timed(unit, boolean)
                
                or
                
                call Respawn_Timed(DIE UNIT, RESPAWN AT STARTING POINT, TIME)
                ||
                \/
                call Respawn_Timed(unit, boolean, real)
                
**************************************************************************************************************/
library Respawn initializer Init requires PUI

globals
    private constant integer array UNIT_TYPE
    private constant real array UNIT_X
    private constant real array UNIT_XEnd
    private constant real array UNIT_Y
    private constant real array UNIT_YEnd
    private constant real array UNIT_ANGLE
    private constant real array UNIT_ANGLEEnd
    private constant group UNIT_GROUP = CreateGroup()
endglobals

private function PickUnits takes nothing returns nothing
    local unit picked
    local integer index
    call GroupEnumUnitsInRect(bj_lastCreatedGroup, bj_mapInitialPlayableArea, null)
    loop
        set picked = FirstOfGroup(bj_lastCreatedGroup)
    exitwhen picked == null
        call GroupRemoveUnit(bj_lastCreatedGroup, picked)
        set index = GetUnitIndex(picked)
        set UNIT_TYPE[index] = GetUnitTypeId(picked)
        set UNIT_X[index] = GetUnitX(picked)
        set UNIT_Y[index] = GetUnitY(picked)
        set UNIT_XEnd[index] = GetUnitX(picked)
        set UNIT_YEnd[index] = GetUnitY(picked)
        set UNIT_ANGLE[index] = GetUnitFacing(picked)
        set UNIT_ANGLEEnd[index] = GetUnitFacing(picked)
        if not IsUnitInGroup(picked, UNIT_GROUP) then
            call GroupAddUnit(UNIT_GROUP, picked)
        endif
    endloop
endfunction

private function UnitDies takes nothing returns nothing
    local unit dead = GetTriggerUnit()
    local integer index = GetUnitIndex(dead)
    set UNIT_XEnd[index] = GetUnitX(dead)
    set UNIT_YEnd[index] = GetUnitY(dead)
    set UNIT_ANGLEEnd[index] = GetUnitFacing(dead)
    set dead = null
endfunction

private function UnitEnters takes nothing returns nothing
    local unit enter = GetTriggerUnit()
    local integer index
    if not IsUnitInGroup(enter, UNIT_GROUP) then
        set index = GetUnitIndex(enter)
        call GroupAddUnit(UNIT_GROUP, enter)
        set UNIT_TYPE[index] = GetUnitTypeId(enter)
        set UNIT_X[index] = GetUnitX(enter)
        set UNIT_Y[index] = GetUnitY(enter)
        set UNIT_XEnd[index] = GetUnitX(enter)
        set UNIT_YEnd[index] = GetUnitY(enter)
        set UNIT_ANGLE[index] = GetUnitFacing(enter)
        set UNIT_ANGLEEnd[index] = GetUnitFacing(enter)
    endif
endfunction

public function Instantly takes unit u, boolean b returns nothing
    local integer index = GetUnitIndex(u)
    if b then
        call CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), UNIT_X[index], UNIT_Y[index], UNIT_ANGLE[index])
    else
        call CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), UNIT_XEnd[index], UNIT_YEnd[index], UNIT_ANGLEEnd[index])
    endif
endfunction

public function Timed takes unit u, boolean b, real t returns nothing
    local integer index = GetUnitIndex(u)
    call TriggerSleepAction(t)
    if b then
        call CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), UNIT_X[index], UNIT_Y[index], UNIT_ANGLE[index])
    else
        call CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), UNIT_XEnd[index], UNIT_YEnd[index], UNIT_ANGLEEnd[index])
    endif
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddAction(t, function UnitDies)
    set t = CreateTrigger()
    call TriggerRegisterEnterRectSimple(t, bj_mapInitialPlayableArea)
    call TriggerAddAction(t, function UnitEnters)
    call PickUnits()
    set t = null
endfunction

endlibrary
 

Attachments

  • RespawnSystem.w3x
    15.4 KB · Views: 144
Status
Not open for further replies.
Top