UGX-Mods

Call of Duty: Black Ops 3 => Tutorial Desk => Scripting => Topic started by: qwerty195 on September 17, 2018, 08:48:07 pm

Title: Abnormal202 Scripting Tutorial 7: While Loops
Post by: qwerty195 on September 17, 2018, 08:48:07 pm
ABNORMAL202 SCRIPTING TUTORIAL 7: WHILE LOOPS
See ALL Tutorials (https://www.ugx-mods.com/forum/scripting/91/abnormal202-scripting-tutorials-master/16746/)

DESCRIPTION

While Loops are the first type of loops we'll be looking at. Loops essentially allow you to repeat the same code over & over again multiple times, or even an infinite amount of time so long as the game is running.

I will also talk about notifies, endons, and waittills, which are all a form of loop manipulation, however they can be used outside of loops as well.

CREATING A WHILE LOOP

A while loop looks like this:

while(condition)
{
   IPrintLnBold("Hello");
   wait(0.05);
}
notice:
  • the word while
  • the ()
  • the condition. You insert a boolean in between the (), so just like in an if statement it will check if it's true or false. If the condition is true the loop continues; if it is false the loop stops and the code below it is run.
  • the {}. Similar to a function or if statement, you should put all code you want to be in the while in between these two {}.
  • the wait. ALL WHILE LOOPS NEED A WAIT OR WAITTILL INSIDE THEM. The smallest amount of time you can wait is 0.05 seconds, which is often used in while loops. If you forget to put a wait inside your while loop, launcher will not give you an error. Instead you will find that in-game when the code begins to read the while loop without a wait, the game will freeze and give a "Connection Interrupted" error, and you will have to force quit to get out usually.
So how can we use While Loops? We can use them to repeat code over and over as long as the condition inside the () remains true. Or if we just want it to always repeat, we can literally input true into the condition, or 1, since as we remember 1 = true, 0 = false:
while(1)
{
   IPrintLnBold("Are we there yet?");
   wait(2);
}
In this example, the line "Are we there yet?" will be printed to the screen every 2 seconds once this while loop is initiated, and will never stop. Just like those damn children.
Perhaps we don't want it go infinitely though? Here's an example of how one can use a While Loop for a set amount of times:
times = 0;
while(times < 10)
{
   if(times == 1)
   {
      IPrintLnBold(times + " minute has passed"); //account for pluralization
   }
   else
   {
      IPrintLnBold(times + " minutes have passed");
   }

   times ++;
   wait(60);
}
In the above case the code will run 10 times before it stops, and the code below it can begin. It should be noted that this specific example could probably be better done using a for loop, but we'll talk about that later.

NOTIFIES

Notifies send, well, a notify on a specific entity to the when they are used. These notifies are picked up by endons and waitills, which I will talk about in a moment.
A standard notify might look like this:
steve notify("stop_eating_my_sandwich");
assuming steve is an already defined variable.
notice: 
  • the word notify
  • the ()
  • the string inside the (). This string should be unique, as it specifies what you are notifying the entity of, so the correct endons and waitills who share that string will go off
just like calling functions, notifies can also pass arguments, to be picked up by waittills. For example:
door = GetEnt("specific_magical_door","targetname");

level notify("magic_door_opened", door, (0,0,50));
notice how you can also use that level variable on notifies, waittills, and endons.
There are a lot of very useful Treyarch notifies that you can use in your code, that notify when a specific event occurs:
level notify( "end_of_round" ); //used when round ends
level notify( "start_of_round" ); //used when next round starts
level notify( "all_players_connected" ); //used when all players have connected into the game
player notify( "bled_out" ); //used when a player bleeds out, on a specific player
player notify( "player_revived" ); //used when a player is revived, on the revived player
entity notify("death"); //used when some character, such as a player or zombie, dies
entity notify("movedone"); //used when an entity is done moving after being give some sort of move command
player notify("weapon_fired", weapon); //used when a player fires a weapon. also passes the weapon entity
entity notify( "damage", amount, attacker, direction_vec, point, type, tagName, ModelName, Partname, weapon ); //used when an entity takes damage. Passes a whole bunch of useful arguments. Note that you can use this on more than just players/zombies, so long as you use the function SetCanDamage() on the entity first.

trigger notify("trigger", player); //used when a player activates a trigger. Also passes the player who activated it as an argument. VERY USEFUL
There are definitely more Treyarch notifies than these that you can use, you'll just have to look for them.

WAITTILLS

Waittills are exactly how they sound: they wait until a notify happens before they allow the code below them to continue.
for example:
steve waittill("stop_eating_my_sandwich");
IPrintLnBold("oh, sorry");
waittills can also accept those useful arguments you may have passed in the notify:
level waittill("magic_door_opened", entity, vector);
entity MoveTo(entity.origin + vector, 5);
but perhaps one of the most used waittills is for waiting until a use_trigger is triggered:
trig = GetEnt("button_trig","targetname");
trig SetHintString( "Press and Hold ^3[{+activate}]^7 to Press Button [Cost: 500 ]");
trig.activated = false;
while(trig.activated == false)
{
   trig waittill("trigger", player);
   if(player.score >= 500)
   {
      player zm_score::minus_to_player_score( 500 );
      trig.activated = true;
   }
   else
   {
      IPrintLnBold("You need some more cash");
   }
}
IPrintLnBold("Button Activated");
The code above is a good example of how while loops and waittills can work together, in this case in what is known as a purchase loop.

ENDONS

Endons will basically break the code below them once the notify they are waiting for is passed. This is very useful for getting out of while loops.
level endon("intermission");
player endon("death");
while(1)
{
   if(player IsTouching(trigger))
   {
      player zm_score::add_to_player_score( 10 );
      wait(0.95);
   }
   wait(0.05);
}
In the example above, I have two different endons, placed above my while loop. for the first one, the while loop will break when game ends, and the level variable is given the "intermission" notify. For the second one, if the player is given the notify "death" (which should automatically happen when a player dies), the while loop will also break. 
If either of these notifies happen, the while loop will "end".
See ALL Tutorials (https://www.ugx-mods.com/forum/scripting/91/abnormal202-scripting-tutorials-master/16746/)