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

Vjass/ Jass Creep Respawn System

Status
Not open for further replies.
Level 6
Joined
Dec 6, 2009
Messages
168
Hello! I have been looking around for a jass/ vjass creep respawn system but I haven't found anyone without bugs/ the features I want.

So this is what I want the system to do:

  • It should spawn neutral hostile units after x amount of time.
  • I want to be able to set custom spawn timers for certain units (bosses).
  • I want to be able to add/remove units that should spawn, so for example after it has died 5 times I can make it stop spawn with custom scripts or something.
  • I want the spawned unit to have the same facing angle as the old one.

I currently got Table by bribe, World Bounds, RegisterPlayUnitEvent, Unit Indexer, Linked List, Alloc, Event and ErrorMessage in my map so plz use them if it makes it easier or add new ones.

+rep to anyone helping and alot of thanks for anyone who makes this system and ofc credit in my map :grin:
 
Sure, give me a moment.

It's not the best but here you go (TimerUtils).

JASS:
library Respawn initializer onInit requires TimerUtils, Table, UnitIndexer

    globals
        private constant player  PLAYER      = Player(PLAYER_NEUTRAL_AGGRESSIVE)
        private constant real    DURATION    = 30 // default respawn time
        private constant boolean SHOW_EFFECT = true
        private constant string  EFFECT      = "effect.mdx"
        
        private Table RespawnTime
        private Table BlackList
    endglobals
    
    // custom respawn times
    //! textmacro RESPAWN_DEFINE_TYPES
        set RespawnTime['nmrl'] = 5
    //! endtextmacro
    
    private function UnitFilter takes nothing returns boolean
        return true
    endfunction

    private struct info
        real startX
        real startY
        real facing
    endstruct
    
    private struct data
        timer timer
        integer id
        integer type
        unit u
        real x
        real y
        real f
        real duration
        boolean dead
        
        method destroy takes nothing returns nothing
            set this.u = null
            set this.duration = 0
            call ReleaseTimer(this.timer)
            call this.deallocate()
        endmethod
    endstruct
    
    private function onRevive takes nothing returns nothing
        local data this = GetTimerData(GetExpiredTimer())
        
        if (IsHeroUnitId(this.type)) then
            call ReviveHero(this.u, this.x, this.y, SHOW_EFFECT)
        else
            call CreateUnit(PLAYER, this.type, this.x, this.y, info(GetUnitId(this.u)).facing)
            call RemoveUnit(this.u)
            call DestroyEffect(AddSpecialEffect(EFFECT, this.x, this.y))
        endif
        
        call this.destroy()
    endfunction
    
    private function onDeath takes nothing returns boolean
        local unit u     = GetTriggerUnit()
        local integer i  = GetUnitTypeId(u)
        local integer h  = GetHandleId(u)
        local info n     = GetUnitId(u)
        local data this
        
        if (BlackList[i] == 1 or BlackList[h] == 1) then
            set u = null
            return false
        endif
        
        set this         = data.create()
        set this.u       = u
        set this.timer   = NewTimerEx(this)
        set this.id      = h
        set this.type    = i
        set this.x       = n.startX
        set this.y       = n.startY
        set this.f       = GetUnitFacing(this.u)
        set this.dead    = true
        
        set i = RespawnTime[this.type]
        
        if (i != 0) then
            set this.duration = i
        else
            set this.duration = DURATION
        endif
        
        call TimerStart(this.timer, this.duration, false, function onRevive)
        
        set u = null
        return false
    endfunction
    
    function UnitEnableRevive takes unit id, boolean flag returns nothing
        if (flag) then
            set BlackList[GetHandleId(id)] = 0
        else
            set BlackList[GetHandleId(id)] = 1
        endif
    endfunction
    
    function SetUnitReviveTime takes unit u, real duration returns nothing
        local integer i = GetHandleId(u)
        local data this = data(RespawnTime[i])
        if (this.u != null) then
            set this.duration = duration
            if (this.dead) then
                call TimerStart(this.timer, this.duration - TimerGetElapsed(this.timer), false, function onDeath)
            endif
        endif
    endfunction
    
    function SetUnitReviveTimeById takes integer id, real duration returns nothing
        set RespawnTime[id] = R2I(duration)
    endfunction
    
    function UnitEnableReviveById takes integer id, boolean flag returns nothing
        if (flag) then
            set BlackList[id] = 0
        else
            set BlackList[id] = 1
        endif
    endfunction
    
    private function onIndex takes nothing returns boolean
        local unit u = GetIndexedUnit()
        local info i = GetUnitId(u)
        
        set i.startX = GetUnitX(u)
        set i.startY = GetUnitY(u)
        set i.facing = GetUnitFacing(u)
        
        return false
    endfunction
    
    //===========================================================================
    private function onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterPlayerUnitEvent(t, PLAYER, EVENT_PLAYER_UNIT_DEATH, Filter(function UnitFilter))
        call TriggerAddCondition(t, Filter(function onDeath))
        
        set t = CreateTrigger()
        call RegisterUnitIndexEvent(Filter(function onIndex), UnitIndexer.INDEX)
        
        set RespawnTime=Table.create()
        set BlackList=Table.create()
        //! runtextmacro RESPAWN_DEFINE_TYPES()
    endfunction
    
endlibrary

Public Functions
  • function UnitEnableRevive takes unit id, boolean flag returns nothing
  • function UnitEnableReviveById takes integer id, boolean flag returns nothing
  • function SetUnitReviveTime takes unit u, real duration returns nothing
  • function SetUnitReviveTimeById takes integer id, real duration returns nothing
 
Last edited:
Status
Not open for further replies.
Top