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

UnitSpawn

Status
Not open for further replies.
Level 7
Joined
Apr 17, 2017
Messages
316
JASS:
scope UnitSpawn initializer init

   globals
       private timer t
       private group neutralGroup
       private group playerGroup
       private integer counter = 20
   endglobals

   private function callback takes nothing returns nothing
       local real x
       local real y
       local real ang
       local real dist = 100.00
       local integer array unitID
       local integer attackOrder = 851983
       local unit tempUnit = GetEnumUnit()
       local unit tempUnit2
  
       if tempunit == null then
           call DestroyGroup(playerGroup)
       endif
       set unitID[1] = 'hfoo'
       set unitID[2] = 'hrif'
       set x = GetUnitX(tempUnit)
       set y = GetUnitY(tempUnit)
       set ang = Atan2(y,x)+bj_PI
       set x = x+dist*Cos(ang)
       set y = y+dist*Sin(ang)
       set tempUnit2 = CreateUnit(GetOwningPlayer(tempUnit), unitID[GetRandomInt(1,2)], x, y,ang)
       call IssuePointOrderById(tempUnit2, attackOrder, 0, 0)
       set tempUnit2 = null
       set tempUnit = null
   endfunction
  

   private function onloop takes nothing returns nothing  
       call ForGroup(playerGroup, function callback)      
   endfunction

   private function conditions takes nothing returns boolean
       local group tempGroup = CreateGroup()
       local unit tempUnit
      
       if IsUnitInGroup(GetTriggerUnit(), playerGroup) == true then
       call GroupRemoveUnit(playerGroup, GetTriggerUnit())
       elseif IsUnitInGroup(GetTriggerUnit(), neutralGroup) == true then
       call GroupRemoveUnit(neutralGroup, GetTriggerUnit())
       set counter = counter - 1  
           if counter == 0 then
           call GroupEnumUnitsInRange(tempGroup, 0, 0, 5000, null)
           loop
               set tempUnit = FirstOfGroup(tempGroup)
               exitwhen tempUnit == null
               call SetUnitExploded(tempUnit, true)
               call KillUnit(tempUnit)
               call GroupRemoveUnit(tempGroup, tempUnit)
               set tempUnit = null
           endloop
           call BJDebugMsg("You won!")
           call PauseTimer(t)
           call DestroyTimer(t)
           endif
       endif
       call DestroyGroup(tempGroup)
       set tempGroup = null
       set tempUnit = null
       return false
   endfunction

   private function init takes nothing returns nothing
       local trigger tr = CreateTrigger()
       local integer i = 0
       local integer n = 0
       local unit temp
       local unit temp2
       local real dist = 3000.00
       local real ang
       local real x
       local real y
  
       set playerGroup = CreateGroup()
       set neutralGroup = CreateGroup()
       set t = CreateTimer()
       loop
           exitwhen i > 20
           set temp = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(1,10)), 0, 0, 0)
           call GroupAddUnit(neutralGroup, temp)
           set temp = null
           set i = i+1
       endloop
       set i = 0
       set n = 0
      
       loop
           exitwhen i > 3
           loop
               exitwhen n > 3
               call SetPlayerAlliance(Player(i), Player(n), ALLIANCE_PASSIVE, true)
               call SetPlayerAlliance(Player(i), Player(n), ALLIANCE_SHARED_VISION, true)
               set n = n+1
           endloop
           set n = 0
           set i = i+1
       endloop
      
       set i = 0
      
       loop
           exitwhen i > 3
           set ang = (45+(90*i))*bj_PI/180
           set x = 0+dist*Cos(ang)
           set y = 0+dist*Sin(ang)
           set temp2 = CreateUnit(Player(i), 'hbar', x, y, (ang*180/bj_PI)+180)
           call GroupAddUnit(playerGroup, temp2)
           set temp2 = null
           set i = i+1
       endloop
      
       call TriggerRegisterAnyUnitEventBJ(tr, EVENT_PLAYER_UNIT_DEATH)
       call TriggerAddCondition(tr, Condition(function conditions))
       call TimerStart(t, 2.50, true, function onloop)
       set tr = null
      
   endfunction
  
endscope
Since using hashtables is not mentioned I managed to keep it as simple as possible. But If it's a must I can change it.
 

Attachments

  • UnitSpawn - Mission.w3m
    18.9 KB · Views: 60
  • Winning the game does not work for me. Have you tested it?
  • In the code it says to explode all units after the win. The missions says to explode all riflemen/footmen.

    Others:

  • Hashtable feels preferable and more suited for such problems, but using group looks very fine, too, as it's not explicitly stated.
  • ChooseRandomCreep can take -1 as parameter as random creep-
  • As we already talked, nulling trigger may be fine, but then other agents could be nulled, too.
  • 180/bj_PI -> bj_DEGTORAD.
  • At the if-statement, there could be proper indention.
  • Nulling the unit inside a FoG loop is not necessary, as it will be nulled automatically with setting the variable always = FirstOfGroup()
 
Level 7
Joined
Apr 17, 2017
Messages
316
  • Winning the game does not work for me. Have you tested it?
  • In the code it says to explode all units after the win. The missions says to explode all riflemen/footmen.

    Others:

  • Hashtable feels preferable and more suited for such problems, but using group looks very fine, too, as it's not explicitly stated.
  • ChooseRandomCreep can take -1 as parameter as random creep-
  • As we already talked, nulling trigger may be fine, but then other agents could be nulled, too.
  • 180/bj_PI -> bj_DEGTORAD.
  • At the if-statement, there could be proper indention.
  • Nulling the unit inside a FoG loop is not necessary, as it will be nulled automatically with setting the variable always = FirstOfGroup()
  • It was a small calculation mistake. I tested it. It doesn't work so I fixed it.
  • fixed the group filter for exploding and killing units
  • changed ChooseRandomCreep(GetRandomInt(1, 10)) to ChooseRandomCreep(-1)
  • I personally like 180/bj_PI as typing bj_DEGTORAD or bj_RADTOD takes a bit more time :D. But if you prefer that for readability, fair enough.
  • Fixed the indentation (I hope so)
  • I didn't know that thanks!!!
JASS:
scope UnitSpawn initializer init

   globals
       private timer t
       private group neutralGroup
       private group playerGroup
       private integer counter = 20
   endglobals

   private function callback takes nothing returns nothing
       local real x
       local real y
       local real ang
       local real dist = 100.00
       local integer array unitID
       local integer attackOrder = 851983
       local unit tempunit = GetEnumUnit()
       local unit tempunit2
   
       set unitID[1] = 'hfoo'
       set unitID[2] = 'hrif'
       set x = GetUnitX(tempunit)
       set y = GetUnitY(tempunit)
       set ang = Atan2(y,x)+bj_PI
       set x = x+dist*Cos(ang)
       set y = y+dist*Sin(ang)
       set tempunit2 = CreateUnit(GetOwningPlayer(tempunit), unitID[GetRandomInt(1,2)], x, y,ang)
       call IssuePointOrderById(tempunit2, attackOrder, 0, 0)
       set tempunit2 = null
   endfunction
   

   private function onloop takes nothing returns nothing   
       call ForGroup(playerGroup, function callback)       
   endfunction

   private function conditions takes nothing returns boolean
       local group tempGroup = CreateGroup()
       local unit tempUnit
       local integer rifleman = 'hrif'
       local integer footman = 'hfoo'
       local integer unitID
       
       if IsUnitInGroup(GetTriggerUnit(), playerGroup) == true then
           call GroupRemoveUnit(playerGroup, GetTriggerUnit())
       elseif IsUnitInGroup(GetTriggerUnit(), neutralGroup) == true then
           call GroupRemoveUnit(neutralGroup, GetTriggerUnit())
           set counter = counter - 1   
           if counter == 0 then
               call GroupEnumUnitsInRange(tempGroup, 0, 0, 5000, null)
               loop
                   set tempUnit = FirstOfGroup(tempGroup)
                   set unitID = GetUnitTypeId(tempUnit)
                   exitwhen tempUnit == null
                   if unitID == rifleman or unitID == footman then
                       call SetUnitExploded(tempUnit, true)
                       call KillUnit(tempUnit)
                   endif
                   call GroupRemoveUnit(tempGroup, tempUnit)
               endloop
               call BJDebugMsg("You won!")
               call PauseTimer(t)
               call DestroyTimer(t)
               call DestroyGroup(playerGroup)
               call DestroyGroup(neutralGroup)
           endif
       endif
       call DestroyGroup(tempGroup)
       set tempGroup = null
       set tempUnit = null
       return false
   endfunction

   private function init takes nothing returns nothing
       local trigger tr = CreateTrigger()
       local integer i = 0
       local integer n = 0
       local unit temp
       local unit temp2
       local real dist = 3000.00
       local real ang
       local real x
       local real y
   
       set playerGroup = CreateGroup()
       set neutralGroup = CreateGroup()
       set t = CreateTimer()
       
       loop
           exitwhen i == 20
           set temp = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(-1), 0, 0, 0)
           call GroupAddUnit(neutralGroup, temp)
           set temp = null
           set i = i+1
       endloop
       set i = 0
       set n = 0
       
       loop
           exitwhen i > 3
           loop
               exitwhen n > 3
               call SetPlayerAlliance(Player(i), Player(n), ALLIANCE_PASSIVE, true)
               call SetPlayerAlliance(Player(i), Player(n), ALLIANCE_SHARED_VISION, true)
               set n = n+1
           endloop
           set n = 0
           set i = i+1
       endloop
       
       set i = 0
       
       loop
           exitwhen i > 3
           set ang = (45+(90*i))*bj_DEGTORAD
           set x = 0+dist*Cos(ang)
           set y = 0+dist*Sin(ang)
           set temp2 = CreateUnit(Player(i), 'hbar', x, y, (ang*bj_RADTODEG)+180)
           call GroupAddUnit(playerGroup, temp2)
           set temp2 = null
           set i = i+1
       endloop
       
       call TriggerRegisterAnyUnitEventBJ(tr, EVENT_PLAYER_UNIT_DEATH)
       call TriggerAddCondition(tr, Condition(function conditions))
       call TimerStart(t, 2.50, true, function onloop)
       set tr = null
       
   endfunction
endscope
 

Attachments

  • UnitSpawn - Mission.w3m
    18.9 KB · Views: 65
Mission solved, good job.

Don't let critique demotivate you, I just point out all random points that come in mind.
  • The attached demo-map still contains debug-only messages. ;p
  • Functionally "Picking All Units of 5000" might work well in the map, but technically really all footmen and riflemen on map are asked for to be exploded.
  • exitwhen i == 20
    better would be
    exitwhen i == counter
  • Variables that never change, like counter, may be delcared as constant. ( constants name conventions IS_LIKE_THIS )
  • Still not all agents are nulled.
  • JASS:
    local unit temp
    local unit temp2
    ^One unit variable would be enough for the init function. Also, "temp" is not a really good unit name.
  • "Passive" != "Allies" hehe
  • IsUnitInGroup(GetTriggerUnit(), playerGroup) == true
    ->
    the == true is not required. It can be:

    IsUnitInGroup(GetTriggerUnit(), playerGroup)

    ..which is the very same. It like saying "Is it rainy?" vs. "Is it rainy == true?".
 
Level 7
Joined
Apr 17, 2017
Messages
316
Updated
JASS:
scope UnitSpawn initializer init

   globals
       private timer t = CreateTimer()
       private group neutralGroup = CreateGroup()
       private group playerGroup = CreateGroup()
       private group unitGroup = CreateGroup()
       private integer counter = 20
       private constant integer HOSTILE_COUNTER = 20
   endglobals
  
   private function explode takes nothing returns nothing
       local unit u = GetEnumUnit()
      
       call SetUnitExploded(u, true)
       call KillUnit(u)
       set u = null
   endfunction

   private function callback takes nothing returns nothing
       local real x
       local real y
       local real ang
       local real dist = 100.00
       local integer array unitID
       local integer attackOrder = 851983
       local unit enumUnit = GetEnumUnit()
       local unit units
  
       set unitID[1] = 'hfoo'
       set unitID[2] = 'hrif'
       set x = GetUnitX(enumUnit)
       set y = GetUnitY(enumUnit)
       set ang = Atan2(y,x)+bj_PI
       set x = x+dist*Cos(ang)
       set y = y+dist*Sin(ang)
       set units = CreateUnit(GetOwningPlayer(enumUnit), unitID[GetRandomInt(1,2)], x, y,ang)
       call GroupAddUnit(unitGroup, units)
       call IssuePointOrderById(units, attackOrder, 0, 0)
       set units = null
   endfunction
  

   private function onloop takes nothing returns nothing  
       call ForGroup(playerGroup, function callback)      
   endfunction

   private function conditions takes nothing returns boolean
      
       if IsUnitInGroup(GetTriggerUnit(), playerGroup) then
           call GroupRemoveUnit(playerGroup, GetTriggerUnit())
       elseif IsUnitInGroup(GetTriggerUnit(), unitGroup) then
           call GroupRemoveUnit(unitGroup, GetTriggerUnit())
       elseif IsUnitInGroup(GetTriggerUnit(), neutralGroup) then
           call GroupRemoveUnit(neutralGroup, GetTriggerUnit())
       set counter = counter - 1  
           if counter == 0 then
               call ForGroup(unitGroup, function explode)
               call BJDebugMsg("You won!")
               call DestroyGroup(playerGroup)
               call DestroyGroup(neutralGroup)
               call DestroyGroup(unitGroup)
               call PauseTimer(t)
               call DestroyTimer(t)
           endif
       endif
       return false
   endfunction

   private function init takes nothing returns nothing
       local trigger tr = CreateTrigger()
       local integer i = 0
       local integer n = 0
       local unit someUnit
       local real dist = 3000.00
       local real ang
       local real x
       local real y
  
      
       loop
           exitwhen i == HOSTILE_COUNTER
           set someUnit = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(-1), 0, 0, 0)
           call GroupAddUnit(neutralGroup, someUnit)
           set someUnit = null
           set i = i+1
       endloop
       set i = 0
       set n = 0
      
       loop
           exitwhen i > 3
           loop
               exitwhen n > 3
               call SetPlayerAlliance(Player(i), Player(n), ALLIANCE_PASSIVE, true)
               call SetPlayerAlliance(Player(i), Player(n), ALLIANCE_SHARED_VISION, true)
               set n = n+1
           endloop
           set n = 0
           set i = i+1
       endloop
      
       set i = 0
      
       loop
           exitwhen i > 3
           set ang = (45+(90*i))*bj_DEGTORAD
           set x = 0+dist*Cos(ang)
           set y = 0+dist*Sin(ang)
           set someUnit = CreateUnit(Player(i), 'hbar', x, y, (ang*bj_RADTODEG)+180)
           call GroupAddUnit(playerGroup, someUnit)
           set someUnit = null
           set i = i+1
       endloop
      
       call TriggerRegisterAnyUnitEventBJ(tr, EVENT_PLAYER_UNIT_DEATH)
       call TriggerAddCondition(tr, Condition(function conditions))
       call TimerStart(t, 2.50, true, function onloop)
       set tr = null
      
   endfunction
endscope
 

Attachments

  • UnitSpawn - Mission(1).w3m
    18.8 KB · Views: 67
Status
Not open for further replies.
Top