• 🏆 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] Spawn System

This is a System similar to the one Blizzard used in Warchasers
It will spawn units at an enemys building / unit per interval when enemys are near
This checks if enemys are in range and if the max. amoun of spawns isnt exceeded

This System uses vJass and requires the Jass New Gen Pack. Get it here.

JASS:
        local unit    hut           = gg_unit_ngnh_0005  // Thats the gnoll hut Placed on the map where units should spawn
        local player  p             = Player(11)         // Units spawn for this Player  (Player 12, Brown)
        local integer SpawnType     = 'nban'             // The Unittype which spawns (Burglars)
        local real    facing        = 300                // The facing of the spawn (Faces a bit in the direction where the heroes will come from)
        local real    EnemyRange    = 400                // Does only spawn with any enemy in rangee of 400 near the hut
        local real    SpawnInterval = 3.25               // If enemys are near every 3.25 seconds a unit Spawns
        local integer MaxEnemys     = 5                  // Spawn Stops while there are 5 spawns 
        local real    CountRange    = 500                // Max amount of spawns is counted in this range near the hut
        local string  SpawnEffect   = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" // Effect while a unit spawns
    
        //Actually calls the function with the values set above which initializes the library for the hut
        call AddSpawnToHut(hut,p,SpawnType,facing,EnemyRange,SpawnInterval,MaxEnemys,CountRange,SpawnEffect)
        // Sure this can be inlined but to add any comments I used variables

JASS:
library SL initializer init

globals
    private constant real TimerPeriod = 0.25 
    // The Interval all checks and spawns are executed
    // Its also the min. Step of Spawn Intervals
endglobals

function AddSpawnToHut takes unit hut, player Owner, integer Spawn, real Facing, real EnemyRange, real SpawnInterval, integer MaxUnits, real CountRange, string SpawnEffect returns nothing
    // This is the main Function of this system to be used
    // It initializes the spawn of the hut
    // Fo detailed information what each variable stands for look in the struct
    call SL.create(hut,Owner,Spawn,Facing,EnemyRange,SpawnInterval,MaxUnits,CountRange,SpawnEffect)
endfunction

/////////////////////////////////////////////System Script////////////////////////////////////////

globals 
    // Systems Variables
    private timer t = CreateTimer()
    private group g = CreateGroup()
    private boolexpr ufilter = null
endglobals

private function UnitFilter takes nothing returns boolean
    // Any Units counted in range of the hut (enemy/Spawns) have to match this condition
    return  (GetWidgetLife(GetFilterUnit()) > 0.405)
endfunction

private function CountUnitsInRangeOfType takes unit hut, real Range, integer UnitType, boolean Enemy returns integer 
    // This functions counts all units in range 
    // If the boolean Enemys == false it counts all units of the unittype in range
    // If the boolean Enemys == true it counts every Enemy unit in range
    
    local integer i = 0
    local unit u
    
    call GroupEnumUnitsInRange(g, GetUnitX(hut), GetUnitY(hut),Range, ufilter)
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g,u)
        
        //Condition for counting, set up as described above
        if (GetUnitTypeId(u) == UnitType and GetOwningPlayer(u) == GetOwningPlayer(hut) and Enemy == false ) or ( IsPlayerEnemy(GetOwningPlayer(u),GetOwningPlayer(hut)) == true and Enemy == true ) then
            set i = i + 1
        endif
        
    endloop
    set u = null
    return i 
endfunction

private function Callback takes nothing returns nothing

    local integer i = 0
    local unit u
    local SL d
    
    loop
    
        //Looping through all structs
        exitwhen i >= SL.Index
        set d = SL.Data[i]
        
        //Sure the hut or unit where all spawns are created shouldnt be dead
        if GetWidgetLife(d.hut) >= 0.405 then
            set d.Counter = d.Counter + TimerPeriod
            //Checks if enemys are near to spawn and if the max. amount of spawns isn reached
            if CountUnitsInRangeOfType(d.hut,d.CountRange, d.SpawnType,false) < d.MaxUnits and CountUnitsInRangeOfType(d.hut,d.EnemyRange, d.SpawnType,true) != 0 then
                
                if d.Counter >= d.SpawnInterval then
                    set d.Counter = d.Counter - d.SpawnInterval
                    //Spawning the unit
                    set u = CreateUnit(d.Owner,d.SpawnType,GetUnitX(d.hut),GetUnitY(d.hut),d.Facing)
                    call DestroyEffect(AddSpecialEffect(d.SpawnEffect,GetUnitX(u),GetUnitY(u)))
                endif
            else
                // Even if no enemys are near or the max amout of units is reached the hut "prepares" to spawn 
                // that if the conditions above are true and a unit should be spawned it is spaned directly
                // because i think it useless if you get near a hut in range and then after the spawn interval the first unit spawns
                if d.Counter >= d.SpawnInterval then
                    set d.Counter = d.SpawnInterval - TimerPeriod
                endif

            endif 

            set i = i + 1
        else
        // Hut is destroeyed, struct gets removed        
            set d.hut = null
            set d.Owner = null
            call SL.destroy(d)
            set SL.Index = SL.Index - 1
            set SL.Data[i] = SL.Data[SL.Index]
        endif
    endloop
    
    if SL.Index == 0 then
         call PauseTimer(t)
    endif
    set u = null
endfunction

struct SL
    static integer       Index = 0
    static SL      array Data
    
    unit    hut            // Main building or unit where all spawns are created
    player  Owner          // The owner of the Spawns (should be the owner of the Hut)
    integer SpawnType      // The units which Spawn
    real    Facing         // Units Facing when spawning
    real    EnemyRange     // Units do only Spawn if an enemy is in this range
    real    SpawnInterval  // IThe interval in which units Spawn if enemys are near
    integer MaxUnits       // Maximum units spawned at the same time
    real    CountRange     // Max. Amount of units near the hut is counted in this range
    string  SpawnEffect    // Special Effect created when a unit Spawns
    
    real    Counter        // Current Counter of the Spawn
    
    static method create takes unit hut, player Owner, integer Spawn, real Facing, real EnemyRange, real SpawnInterval, integer MaxUnits, real CountRange, string SpawnEffect returns SL

        local SL d          = SL.allocate()
        
        // Setting all Variables
        set d.hut           = hut
        set d.Owner         = Owner
        set d.SpawnType     = Spawn
        set d.EnemyRange    = EnemyRange
        set d.SpawnInterval = SpawnInterval
        set d.MaxUnits      = MaxUnits
        set d.CountRange    = CountRange
        set d.SpawnEffect   = SpawnEffect
        set d.Facing        = d.Facing
        set d.Counter       = SpawnInterval - TimerPeriod
        
        set SL.Data[SL.Index] = d
        
        //Starting the timer if it isnt already
        if d.Index == 0 then
            call TimerStart(t, TimerPeriod, true, function Callback)
        endif
        
        set d.Index = d.Index + 1
        return d
        
    endmethod


endstruct

private function init takes nothing returns nothing
    //Setting up the unit filter
    set ufilter = Filter(function UnitFilter)
endfunction

endlibrary

Please give Credits when using :)


Keywords:
Spawn, System, Library, War, Chasers, Warchasers, Creeps, Hut, Gnoll, Creation, -JonNny
Contents

Noch eine WARCRAFT-III-Karte (Map)

Reviews
15:23, 30th Dec 2009 TriggerHappy: Useful and the coding was fine. Your unit filter could use UnitAlive. FirstOfGroups loops are slow, it would be wiser to use a different method. I'd prefer you use a TimerAttachment system, these O(n)...

Moderator

M

Moderator

15:23, 30th Dec 2009
TriggerHappy:

Useful and the coding was fine.

  • Your unit filter could use UnitAlive.
  • FirstOfGroups loops are slow, it would be wiser to use a different method.
  • I'd prefer you use a TimerAttachment system, these O(n) searches bug me.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Same question than Modafoka. I'd like to place some (invisible) spawn points in a wood, setting the maximum spawn number to "Number of Heroes x 2", and Spawning units in random level between X and Y..., and in a random point withing 800 of SpawnPoint towards random degrees. Also units owned by Neutral Hostile...

In other words: Could you help me implementing this to my map? xD
 
Top