1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Choose the best Old Gods themed skin at the Texturing Contest #29 - Poll!
    Dismiss Notice
  3. Melee Mapping Contest #2 - Poll is up! Vote for the best competitive 1v1 map!
    Dismiss Notice
  4. Please help test custom maps and more on the latest PTR!
    Dismiss Notice
  5. Evolution complete! Make Darwin proud and go vote in the Techtree Contest #12 - Poll.
    Dismiss Notice
  6. Icon Contest #17 - Results are out! Step by to congratulate our winners!
    Dismiss Notice
  7. We've created the Staff Job Openings thread. We're currently in need of icon, video production, and social/multimedia positions to be filled. Thank you!
    Dismiss Notice

[vJass] Spawn System

Submitted by -JonNny
This bundle is marked as approved. It works and satisfies the submission rules.
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.

Example Usage
Code (vJASS):

        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

 


Spawn Library
Code (vJASS):
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
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)...
  1. 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.
     
  2. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    I skimmed the code... well it's -JonNny made so it's well-made :)
    Good job!
     
  3. Aspard

    Aspard

    Joined:
    Jul 2, 2008
    Messages:
    595
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Useful thing, great!
     
  4. f0rsAk3n

    f0rsAk3n

    Joined:
    Nov 2, 2008
    Messages:
    536
    Resources:
    10
    Spells:
    9
    Template:
    1
    Resources:
    10
    I've always hoped someone' will make this. Thanks :) +rep
     
  5. hell gate

    hell gate

    Joined:
    Nov 23, 2008
    Messages:
    477
    Resources:
    10
    Models:
    1
    Spells:
    9
    Resources:
    10
    yes, i also waited for something like this.
    i like it +REP
     
    Last edited: Aug 3, 2009
  6. Kam

    Kam

    Blizzard Associate Producer

    Joined:
    Aug 3, 2004
    Messages:
    2,591
    Resources:
    22
    Models:
    8
    Icons:
    2
    Maps:
    12
    Resources:
    22
    Very nice, but is this going to work with 1.24?
     
  7. -JonNny

    -JonNny

    Joined:
    Jan 31, 2007
    Messages:
    486
    Resources:
    12
    Icons:
    3
    Maps:
    4
    Spells:
    4
    Tutorials:
    1
    Resources:
    12
    sure it does
     
  8. Kam

    Kam

    Blizzard Associate Producer

    Joined:
    Aug 3, 2004
    Messages:
    2,591
    Resources:
    22
    Models:
    8
    Icons:
    2
    Maps:
    12
    Resources:
    22
    I only ask as it requires newgen and I don't think it's clear that that will function.
     
  9. Mooglefrooglian

    Mooglefrooglian

    Joined:
    Nov 28, 2008
    Messages:
    701
    Resources:
    0
    Resources:
    0
    Nothing is changing really but the H2I() function will be buggy, JNGP should work finr with 1.24.
     
  10. Spet

    Spet

    Joined:
    Jun 3, 2009
    Messages:
    455
    Resources:
    0
    Resources:
    0
    Very cool ;)
    +rep
     
  11. Ice Snake

    Ice Snake

    Joined:
    Oct 13, 2009
    Messages:
    28
    Resources:
    0
    Resources:
    0
    Good job!

    +rep
     
  12. modafoka

    modafoka

    Joined:
    Aug 30, 2005
    Messages:
    162
    Resources:
    0
    Resources:
    0
    What if i want to set a unit type variable with random levels of creeps, how can i do that?
     
  13. Spartipilo

    Spartipilo

    Joined:
    Jul 14, 2011
    Messages:
    3,190
    Resources:
    0
    Resources:
    0
    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