Unit Spawn

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 41
Joined
Jun 9, 2011
Messages
13,239
JASS:
//! zinc
    library UnitSpawn {
   
        hashtable hash = InitHashtable();
   
        force f = CreateForce();
   
        integer toSpawn[], count;
       
        integer enemyCount = 20;
       
        function ForceActions() {
            player p = GetEnumPlayer();
            integer id = GetPlayerId(p);
            unit base = LoadUnitHandle(hash, id, 0);
            unit temp;
            if(GetUnitState(base, UNIT_STATE_LIFE) > 0) {
                temp = CreateUnit(p, toSpawn[GetRandomInt(0, count)], GetUnitX(base), GetUnitY(base), 0);
                IssuePointOrder(temp, "attack", 0, 0);
                SetUnitExploded(temp, true);
            } else {
                ForceRemovePlayer(f, p);
            }
            temp = null;
            base = null;
        }
   
        function onInit() {
            trigger tr = CreateTrigger();
            integer i = 0;
            real angle = bj_PI / 4;
            real dist = 3000;
            real x, y;
            timer t = CreateTimer();
            unit u;
           
            TriggerRegisterPlayerUnitEventSimple(tr, Player(PLAYER_NEUTRAL_AGGRESSIVE), EVENT_PLAYER_UNIT_DEATH);
            TriggerAddAction(tr, function() {
                enemyCount -= 1;
                if(enemyCount == 0) {
                    DisplayTextToForce(GetPlayersAll(), "You won!");
                }
            });
           
            toSpawn[0] = 'hfoo';
            toSpawn[1] = 'hrif';
            count = 2;
           
            while(i < enemyCount) {
                CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(1,7)), 0, 0, 0);
                i += 1;
            }
           
            i = 0;
           
            while(i < 4) {
                x = dist * Cos(angle);
                y = dist * Sin(angle);
                SaveUnitHandle(hash, GetPlayerId(Player(i)), 0, CreateUnit(Player(i), 'hbar', x, y, 0));
                angle += bj_PI / 2;
                ForceAddPlayer(f, Player(i));
                i += 1;
            }
           
            TimerStart(t, 2.5, true, function(){
                ForForce(f, function ForceActions);
            });
           
            u = null;
            t = null;
        }
    }
//! endzinc
 

Attachments

  • 3 UnitSpawn.w3x
    17.9 KB · Views: 50
Level 16
Joined
Mar 25, 2016
Messages
1,327
I think your victory trigger does not work, if the creeps can summon additional units. As far as I could see it, there was no function to increase enemyCount, when a creep is summoned.

The mission description reads:
Furthermore a message "You won!" must be printed on screen for all players, and all alive footmen and riflemen must be exploded on death.
I interpreted it like this:
all units should immediately explode on death(being killed) , once victory has been achieved and not that they should generally explode on death.
I can definitely see why you did it different, because the description is very ambiguous and your interpretation is probably closer to the description than mine.
However I got the mission completed, so my solution should be correct. Maybe @IcemanBo can enlighten us, what exactly was meant.
 
"The periodic calls to create units at the barracks must stop once there's no enemy alive anymore."
I believe it makes sense to consider the current amount of living hostile units, as then it's ensured then to match the condition that none of them is alive.

0.405 is used as life cap, but could also use the native native UnitAlive takes unit u returns boolean instead.

Your count is 2, which is wrong.

I have similar "issue" with hashables then mentioned here:
"ave you read the crash course? -- I mean where the differences between array and hashtables are; you're not 'really' using the hashtable power at the moment, and could just use an array variable for the barracks."
--
I believe I will change the mission for making 4 bases for 1 player when I'm at home.

I'm just confused why Player is used (array would work, too), then group is used (we already use hashtable as powerful data structure which should be used)...
 

Chaosy

Tutorial Reviewer
Level 41
Joined
Jun 9, 2011
Messages
13,239
Because an hashtable is sorta needed.
I was thinking of other methods of saving the barracks such as just as using FirstOf for each player, but that only works if the player has one barrack which I am not sure if you like. If that is okay I will gladly remove hashtable usage.

Updated a bit though
JASS:
 native UnitAlive takes unit id returns boolean
//! zinc
    library UnitSpawn {
 
        hashtable hash = InitHashtable();
 
        force f = CreateForce();
 
        integer toSpawn[], count;
     
        integer enemyCount = 20;
     
        function ForceActions() {
            player p = GetEnumPlayer();
            integer id = GetPlayerId(p);
            unit base = LoadUnitHandle(hash, id, 0);
            unit temp;
            if(UnitAlive(base)) {
                temp = CreateUnit(p, toSpawn[GetRandomInt(0, count - 1)], GetUnitX(base), GetUnitY(base), 0);
                IssuePointOrder(temp, "attack", 0, 0);
                SetUnitExploded(temp, true);
            } else {
                ForceRemovePlayer(f, p);
            }
            temp = null;
            base = null;
        }
 
        function onInit() {
            trigger tr = CreateTrigger();
            integer i = 0;
            real angle = bj_PI / 4;
            real dist = 3000;
            real x, y;
            timer t = CreateTimer();
            unit u;
         
            TriggerRegisterPlayerUnitEventSimple(tr, Player(PLAYER_NEUTRAL_AGGRESSIVE), EVENT_PLAYER_UNIT_DEATH);
            TriggerAddAction(tr, function() {
                enemyCount -= 1;
                if(enemyCount == 0) {
                    DisplayTextToForce(GetPlayersAll(), "You won!");
                    ForceClear(f);
                }
            });
         
            toSpawn[0] = 'hfoo';
            toSpawn[1] = 'hrif';
            count = 2;
         
            while(i < enemyCount) {
                CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), ChooseRandomCreep(GetRandomInt(1,7)), 0, 0, 0);
                i += 1;
            }
         
            i = 0;
         
            while(i < 4) {
                x = dist * Cos(angle);
                y = dist * Sin(angle);
                SaveUnitHandle(hash, GetPlayerId(Player(i)), 0, CreateUnit(Player(i), 'hbar', x, y, 0));
                angle += bj_PI / 2;
                ForceAddPlayer(f, Player(i));
                i += 1;
            }
         
            TimerStart(t, 2.5, true, function(){
                if(CountPlayersInForceBJ(f) > 0) {
                    ForForce(f, function ForceActions);
                } else {
                    DestroyForce(f);
                    DestroyTimer(GetExpiredTimer());
                }
            });
         
            u = null;
            t = null;
        }
    }
//! endzinc
 
Last edited:
"The periodic calls to create units at the barracks must stop once there's no enemy alive anymore."
I believe it makes sense to consider the current amount of living hostile units, as then it's ensured then to match the condition that none of them is alive.

=======

I was thinking of other methods of saving the barracks such as just as using FirstOf for each player, but that only works if the player has one barrack which I am not sure if you like.
What do you mean exactly? :
I'm just confused why Player is used (array would work, too), then group is used (we already use hashtable as powerful data structure which should be used)...
All the player/force logics seems not needed.
 
Status
Not open for further replies.
Top