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

Basics - Unit Groups

Status
Not open for further replies.
Level 2
Joined
Jul 12, 2018
Messages
17

Tasks

Code

Changes



Create 200 footmen on the map at random locations. (but within playable map area)
Loop through all units on map, and kill them if they are in range of 1000 towards the center of the map.


Create a trigger that runs when a player presses the 'Esc' button (Skip Cinematic).
When the trigger runs, the amount of alive footmen should be printed on screen.
For solving this part, the "FoG Enumeration" tequnique must be used.



JASS:
native UnitAlive takes unit whichUnit returns boolean
scope Part1n2 initializer init
    globals
        group Group = CreateGroup()
    endglobals
   
    private function esc takes nothing returns nothing
        local integer count = 0
        local unit fog
       
        call GroupEnumUnitsInRect(Group, bj_mapInitialPlayableArea, null)
        loop
            set fog = FirstOfGroup(Group)
            exitwhen fog == null
           
            if UnitAlive(fog) then
                set count = count + 1
            endif
           
            call GroupRemoveUnit(Group, fog)
        endloop
        call GroupClear(Group)
       
        call BJDebugMsg(I2S(count) + " unit(s) left")
    endfunction
    private function init takes nothing returns nothing
        local trigger escTrig = CreateTrigger()
        local integer i = 200
        local real x
        local real y
        local real preCalc
        local unit fog
       
        loop
            exitwhen i <= 0
           
            set x = GetRandomReal(GetRectMinX(bj_mapInitialPlayableArea), GetRectMaxX(bj_mapInitialPlayableArea))
            set y = GetRandomReal(GetRectMinY(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea))
            call CreateUnit(Player(0), 'hfoo', x, y, 0)
           
            set i = i - 1
        endloop
       
        set preCalc = Pow(1000,2)
        call GroupEnumUnitsInRect(Group, bj_mapInitialPlayableArea, null)
        loop
            set fog = FirstOfGroup(Group)
            exitwhen fog == null
           
            if GetUnitX(fog)*GetUnitX(fog) + GetUnitY(fog)*GetUnitY(fog) <= preCalc then
                call KillUnit(fog)
            endif
           
            call GroupRemoveUnit(Group, fog)
        endloop
        call GroupClear(Group)
       
        call TriggerRegisterPlayerEvent(escTrig, Player(0), EVENT_PLAYER_END_CINEMATIC)
        call TriggerAddAction(escTrig, function esc)
    endfunction
endscope



-submission


-instead IsUnitType, now uses UnitAlive
-removed SquareRoot(GetUnitX(fog)*GetUnitX(fog) + GetUnitY(fog)*GetUnitY(fog)) <= 1000,
added real preCalc = Pow(1000, 2), GetUnitX(fog)*GetUnitX(fog) + GetUnitY(fog)*GetUnitY(fog) <= preCalc

[tab=Changes][/tab]
 

Attachments

  • [Crash Course] Basics - Unit Groups.w3m
    24.2 KB · Views: 78
Last edited:

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
The condition
JASS:
SquareRoot(GetUnitX(fog)*GetUnitX(fog) + GetUnitY(fog)*GetUnitY(fog)) <= 1000
can be changed to
JASS:
GetUnitX(fog)*GetUnitX(fog) + GetUnitY(fog)*GetUnitY(fog) <= 1000000

You basically square both sides of the inequality getting rid of the expensive square root.
It's only a minor improvement, but it can make a difference, considering it is repeated 200 times.
 
Level 2
Joined
Jul 12, 2018
Messages
17
Noted


-instead IsUnitType, now uses UnitAlive
-removed SquareRoot(GetUnitX(fog)*GetUnitX(fog) + GetUnitY(fog)*GetUnitY(fog)) <= 1000,
added real preCalc = Pow(1000, 2), GetUnitX(fog)*GetUnitX(fog) + GetUnitY(fog)*GetUnitY(fog) <= preCalc
 
Status
Not open for further replies.
Top