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

Unit Spawn - Submission

Status
Not open for further replies.

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
JASS:
scope UnitSpawn initializer Init

    globals
        private group barracks
        private integer counter
        private integer creepCount
    endglobals

    private function CreepSpawn takes nothing returns nothing
        if(GetOwningPlayer(GetTriggerUnit()) == Player( PLAYER_NEUTRAL_AGGRESSIVE ) ) then
            set creepCount = creepCount + 1
        endif
    endfunction
   
    private function CreepDeath takes nothing returns nothing
        local group g
        local unit u
        local boolean noCreeps = TRUE
       
        set creepCount = creepCount -1
       
        if(creepCount == 0) then
            call GroupClear( barracks )
            set g = CreateGroup()
            call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
            loop
                set  u = FirstOfGroup(g)
                exitwhen u == null
                call GroupRemoveUnit(g, u)
                if(GetUnitTypeId(u)=='hfoo' or GetUnitTypeId(u)=='hrif') then
                    call SetUnitExploded(u, true)
                    call KillUnit(u)
                endif
            endloop
            call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, "You won!")
            call DestroyGroup(g)
        endif

        set u = null
        set g = null
    endfunction
   
    private function Group takes nothing returns nothing
        local unit u = GetEnumUnit()
        local unit spawn
        local integer spawntype
        set counter = counter + 1
       
        if(GetRandomInt(0,1)==0) then
            set spawntype = 'hfoo'
        else
            set spawntype = 'hrif'
        endif
       
        if(GetWidgetLife(u)<0.405) then
            call GroupRemoveUnit(barracks, u)
        else
            set spawn = CreateUnit(GetOwningPlayer(u), spawntype, GetUnitX(u), GetUnitY(u), 0)
            call IssuePointOrder(spawn, "attack", 0, 0)
        endif
       
        set u = null
    endfunction
   
    private function Periodic takes nothing returns nothing
        local timer t = GetExpiredTimer()
        set counter = 0
        call ForGroup(barracks, function Group)
        if( counter == 0 ) then
            call PauseTimer(t)
            call DestroyTimer(t)
        endif
        set t = null
    endfunction
   
    private function Init takes nothing returns nothing
        local integer i = 0
        local real x = 0
        local real y = 0
        local timer t
        local trigger trg = CreateTrigger()
        local region r = CreateRegion()
        call TriggerRegisterPlayerUnitEvent(trg, Player( PLAYER_NEUTRAL_AGGRESSIVE ), EVENT_PLAYER_UNIT_DEATH, null)
        call TriggerAddAction(trg, function CreepDeath)
        set trg = CreateTrigger()
        call RegionAddRect(r, bj_mapInitialPlayableArea)
        call TriggerRegisterEnterRegion(trg, r, null)
        call TriggerAddAction(trg, function CreepSpawn)
       
        loop
            exitwhen i>=20
            call CreateUnit(Player( PLAYER_NEUTRAL_AGGRESSIVE ), ChooseRandomCreep(-1), x, y, 0)
            set i = i + 1
        endloop
       
        set creepCount = 0
       
        set barracks = CreateGroup()
       
        set x = 3000
        call GroupAddUnit( barracks, CreateUnit(Player(0), 'hbar', x, y, 0))
        set x = - 3000
        call GroupAddUnit( barracks, CreateUnit(Player(2), 'hbar', x, y, 0))
        set y = - 3000
        set x = 0
        call GroupAddUnit( barracks, CreateUnit(Player(1), 'hbar', x, y, 0))
        set y = 3000
        call GroupAddUnit( barracks, CreateUnit(Player(3), 'hbar', x, y, 0))
       
        set t = CreateTimer()
        call TimerStart(t, 2.5, TRUE, function Periodic)
   
    endfunction
endscope

Took longer than expected, because I had to track the amount of living enemy units, because of reincarnation.
 

Attachments

  • JASS Class Mission 3.w3m
    25.2 KB · Views: 38
You seem to copied my error from my 1. Unit Submission :), Square is
e567883ec27edc4c21b255015d497496_square-clip-art-clipart-square_425-392.jpeg
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Well it's still a square if you rotate it. :D
Thanks for pointing that out. Here is the update.

JASS:
scope UnitSpawn initializer Init

    globals
        private group barracks
        private integer counter
        private integer creepCount
    endglobals

    private function CreepSpawn takes nothing returns nothing
        if(GetOwningPlayer(GetTriggerUnit()) == Player( PLAYER_NEUTRAL_AGGRESSIVE ) ) then
            set creepCount = creepCount + 1
        endif
    endfunction
  
    private function CreepDeath takes nothing returns nothing
        local group g
        local unit u
        local boolean noCreeps = TRUE
      
        set creepCount = creepCount -1
      
        if(creepCount == 0) then
            call GroupClear( barracks )
            set g = CreateGroup()
            call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
            loop
                set  u = FirstOfGroup(g)
                exitwhen u == null
                call GroupRemoveUnit(g, u)
                if(GetUnitTypeId(u)=='hfoo' or GetUnitTypeId(u)=='hrif') then
                    call SetUnitExploded(u, true)
                    call KillUnit(u)
                endif
            endloop
            call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, "You won!")
            call DestroyGroup(g)
        endif

        set u = null
        set g = null
    endfunction
  
    private function Group takes nothing returns nothing
        local unit u = GetEnumUnit()
        local unit spawn
        local integer spawntype
        set counter = counter + 1
      
        if(GetRandomInt(0,1)==0) then
            set spawntype = 'hfoo'
        else
            set spawntype = 'hrif'
        endif
      
        if(GetWidgetLife(u)<0.405) then
            call GroupRemoveUnit(barracks, u)
        else
            set spawn = CreateUnit(GetOwningPlayer(u), spawntype, GetUnitX(u), GetUnitY(u), 0)
            call IssuePointOrder(spawn, "attack", 0, 0)
        endif
      
        set u = null
    endfunction
  
    private function Periodic takes nothing returns nothing
        local timer t = GetExpiredTimer()
        set counter = 0
        call ForGroup(barracks, function Group)
        if( counter == 0 ) then
            call PauseTimer(t)
            call DestroyTimer(t)
        endif
        set t = null
    endfunction
  
    private function Init takes nothing returns nothing
        local integer i = 0
        local real x = 0
        local real y = 0
        local real dist = 3000/ SquareRoot(2)
        local timer t
        local trigger trg = CreateTrigger()
        local region r = CreateRegion()
        call TriggerRegisterPlayerUnitEvent(trg, Player( PLAYER_NEUTRAL_AGGRESSIVE ), EVENT_PLAYER_UNIT_DEATH, null)
        call TriggerAddAction(trg, function CreepDeath)
        set trg = CreateTrigger()
        call RegionAddRect(r, bj_mapInitialPlayableArea)
        call TriggerRegisterEnterRegion(trg, r, null)
        call TriggerAddAction(trg, function CreepSpawn)
      
        loop
            exitwhen i>=20
            call CreateUnit(Player( PLAYER_NEUTRAL_AGGRESSIVE ), ChooseRandomCreep(-1), x, y, 0)
            set i = i + 1
        endloop
      
        set creepCount = 0
      
        set barracks = CreateGroup()
      
      
      
        set x = dist
        set y = dist
        call GroupAddUnit( barracks, CreateUnit(Player(0), 'hbar', x, y, 0))
        set x = dist
        set y = -dist
        call GroupAddUnit( barracks, CreateUnit(Player(2), 'hbar', x, y, 0))
        set x = -dist
        set y = -dist
        call GroupAddUnit( barracks, CreateUnit(Player(1), 'hbar', x, y, 0))
        set x = -dist
        set y = dist
        call GroupAddUnit( barracks, CreateUnit(Player(3), 'hbar', x, y, 0))
      
        set t = CreateTimer()
        call TimerStart(t, 2.5, TRUE, function Periodic)
  
    endfunction
endscope
 

Attachments

  • JASS Class Mission 3.w3m
    25.2 KB · Views: 48
I would have prefered to attach one barracks to one timer, because they can spawn and die independantly, but grouping results in same, of course. But also with combination with the global counter for the barracks it seems less elegant.

The counter for spawned creep counting is clever, though, so you avoid periodical enums of enemy units.

The barracks group could be destroyed when not needed anymore, just as note.

I guess it's completed, but will test today later.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Please also include alliance logics, I might have added this point after you started the thread.
I am pretty sure, that was not part in the descrption when I read it. I was already wondering.

Anyway that's the alliance code (in the Init function):
JASS:
//alliance
        loop
            exitwhen i>3
            set j = 0
            loop
                exitwhen j>3
                if(i!=j) then
                    call SetPlayerAllianceStateBJ( Player(i), Player(j), bj_ALLIANCE_ALLIED )
                endif
                set j = j + 1
            endloop
            set i = i + 1
        endloop

Do you need the full code and a map update?
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
I think it's not a problem, because it only runs once at the beginning of the map.

I think if a function calls a lot of other functions, it's worth to use it instead of the natives.
Would be 8 more lines to accomplish this in natives.
It makes the code easier to read and also easier to edit.
Otherwise every self written function would be bad.
 
Status
Not open for further replies.
Top