Recent Posts

broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
CF51's Groups
CF51's Contact & Social Links
Last post by CF51 - 10 hours ago
Ah I see. Well, here's to hoping that whatever you work on next will be excellent as well. Besides, I enjoy these custom zombie maps for how creative they can become. Weapons, bosses, and objectives galore!
broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
Xspicious's Groups
Xspicious's Contact & Social Links
Last post by Xspicious - 13 hours ago
Thanks, I appreciate it. No spoilers, but there is more maps to come. WaW and BO3. Also I wouldn't say this was my first map ever made. I have been using the tools for a long time. Around 5ish years just never released any of the maps I have made before. They where just box maps or a few rooms. I didn't think they were good enough to release. I also quit messing with the tools for over a year, but I am glad to have come back.
broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
IamTIMMEHHH's Groups
IamTIMMEHHH's Contact & Social Links
Last post by IamTIMMEHHH - 15 hours ago
Now I can't change my topic I am going to place it here for now...
Beta download

First person to find the EE gets a free cookie! 
broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
CounterfitCookie's Contact & Social Links
Last post by CounterfitCookie - 19 hours ago
Everyone quiet for a sec....THIS MAP IS AMAZING MY DUDE
broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
CF51's Groups
CF51's Contact & Social Links
Last post by CF51 - 20 hours ago
This is a pretty good map for a 1st attempt. While it's not too populated with anything crazy, it does make me appreciate each weapon where it is. Seriously, that Type 100 saved me. At least until I actidentally cornered myself. A solid first map that reminds me of the terror of the OG maps.
broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
qwerty195's Groups
qwerty195's Contact & Social Links
Last post by qwerty195 - 1 day ago
ABNORMAL202 SCRIPTING TUTORIAL 8: ARRAYS
See ALL Tutorials

DESCRIPTION

Arrays are an essential part to programming, and for me, they were one of the biggest hurdles for scripting. So take this tutorial slowly, read it over multiple times if you have to, but I will try to do my best to explain them.

CREATING AN ARRAY

Arrays are basically a way of storing multiple entities inside one variable. You can define an array multiple ways:

defining it like this:
watermelons = [];
and then adding the respective elements to the arrays like this:
melon_0 = GetEnt("watelon","targetname");
watermelons[0] = melon_0;
OR
by using array functions that return/create arrays for you:
melon_phrases = array( "green & red, big as my head","round and plump, give me some","hard yet soft, let me crunch");
watermelon_triggers = GetEntArray("melon_trigger","targetname");
Don't worry about understanding all of the above just yet; just wanted to show how there are multiple correct ways to create an array and you may encounter all of these.

PARTS OF AN ARRAY

One of the most common ways arrays are used is for grabbing multiple ents with a common targetname using GetEntArray().
For example, if I had script_model with the targetname: "watermelon", I could grab it using:
melon = GetEnt("watermelon", "targetname");
Now I have that one model stored in the variable I called "melon". But what if I wanted to grab more than one watermelon with that targetname? GetEnt() will not work if more than one entity has the targetname it's looking for, because it doesn't know which ent you want.
So instead I can use:
melons = GetEntArray("watermelon", "targetname");
this will find all entities with the targetname "watermelon" and store them in an array, which is stored in the variable "melons". Notice how I pluralized this variable as opposed to just calling it melon like the above. This is because I want to think of it as multiple entities instead of one.
Let's say in this example there were 3 models with the targetname "watermelon". That means there are 3 entities in the array and we can access each one like this:
melon_0 = melons[0];
melon_1 = melons[1];
melon_2 = melons[2];
notice:
  • an array counts starting at 0, not 1. So even though there are 3 entities, they're essentially labeled 0,1,2.
  • the [ ]
  • the number inside the [ ]. This number is known as the index. the index goes as high as the size of the array, minus one (due to starting at 0). When using GetEntArray() each melon entity is stored at a certain index. One model will be index 0, a different one will be index 1, and so on. Due to not knowing how the computer decides which script_model goes first, then next, etc. the entities and their respective indexes will essentially be random using GetEntArray(), however there are other situations in which you can decide which index an entity will be under.
this concept of the index is important to understand, because it's essentially the only way we can interact with the actual entities in the array. 
For example this would Not do anything:
melons MoveZ(50, 2);
but this will:
melons[0] MoveZ(50, 2);
A very handy thing to know: Arrays always have a property stored on them called size, that is how big it is, or how many entities are stored inside it. You can access it like this:
amount_of_melons = melons.size;
this is very neat because the size of the current array will always be what the next index value would be if another entity were to be added to it. In our example with the 3 melons, the size of the array would be 3, and the already used indexes are 0,1, and 2 - so the next value of the index would be 3, same as our size.

FOR LOOPS

For loops can be used for many things, but they're mostly used in conjunction with arrays, which is why I have waited until now to talk about them. A For loop is basically a while loop that automatically stops after a certain amount of times, by checking a variable.
This is what a common For Loop might look like:
for(i=0; i<10; i++)
{
   
}
Notice:
  • the word for
  • the ()
  • the init. In this example it is i = 0. This is where we define a variable and set it to something, typically a number, and often 0. Usually people call the variable "i", but it could be anything.
  • the condition. In this example it is i < 10. This is where we put a condition that has to be true in order for the For Loop to loop again. In this case it will keep looping as long as i is less than 10, but if it were to say, equal 10 or something higher, the loop would stop running and the code below it would activate.
  • the increment. In this example it is i ++. This code will occur at the end of every loop of the For Loop. So in this case, i will start as 0, then for the next loop it will equal 1, then 2, etc. However when i = 9 the next loop will not occur because adding 1 to i would make it equal to 10, which is not < 10, ending the For Loop.
  • the ; in between the init & condition, and in between the condition & increment.
  • the {}. In between these is where, similar to while loop, the code we want to loop occurs.
Using the concept of a For Loop, we can easily perform actions to all entities in an array at once. For example:
for(i=0; i<melons.size; i++)
{
   melons MoveZ(50, 2);
}
Notice:
  • I'm using melons.size as what I want i to always be less than in order to keep looping. Because the .size will always be one more than the last index of the array, this means the for loop will run once for every entity in the array.
  • for the index I'm using i. Every time the code inside the for loop is run it will substitute the current value for i inside there. so the first loop around it will be melons[0] than melons[1] etc.
  • I don't need to have a wait in my For Loop. This is because it is not being run infinitely unlike the while loops, so it will not freeze the computer from me trying to run it without rest.
This above array will successfully move all script_models part of the melons array 50 units higher in 2 seconds. While it may seem like it took a lot of code just to do that, the great thing about it is the flexibility. This code will work no matter how many models I have with the targetname: "watermelon" on them in radiant. This makes it so much more efficient and professional than:
melon_0 = GetEnt("watermelon_0", "targetname");
melon_0 MoveZ( 50, 2);
melon_1 = GetEnt("watermelon_1", "targetname");
melon_1 MoveZ( 50, 2);
melon_2 = GetEnt("watermelon_2", "targetname");
melon_2 MoveZ( 50, 2);

FOREACH LOOPS

Whereas For Loops can have use outside of arrays, Foreach loops are designed specifically for arrays. Though a for loop can accomplish anything a Foreach loop can (and not vice versa), foreach can be a great alternative, which will save a lot of typing and look nicer.
Here is a foreach loop that accomplishes the exact same thing as the above For Loop:
foreach(melon in melons)
{
   melon MoveZ( 50, 2);
}
Notice:
  • the word foreach (don't forget it's all one word)
  • the ()
  • the 1st word, melon. We can call this whatever we want, but this will represent each item in the array. We must use the same word we set for it inside the () as inside the {} to reference the entity in the array.
  • the word in.
  • the 2nd word, melons. This must be an already defined array, and it will be the array that foreach will loop every entity inside of through the code in the {} below.
The foreach code is much cleaner, easier to remember, and less likely to screw up when typing. However, there are certain limitations with this format, as there is no longer any sort of variable being incremented with each loop. This means that if we, say, wanted to do something special when the 2nd melon is moved we would have to use a For Loop:
for(i=0; i<melons.size; i++)
{
   if(i == 1)
   {
      IPrintLnBold("I'm a special Melon, who must be higher than the others");
      melons MoveZ(70, 2);
   }
   else
   {
      melons MoveZ(50, 2);
   }
}
Because there is no variable "i" we can check with foreach loops.

ADDING TO/REMOVING FROM AN ARRAY

Thankfully, our arrays are not set in stone once we create them. We are always able to add values to them or remove values from them using the below functions:
ArrayInsert(, , );
ArrayRemoveIndex(,,[preserve_keys]);
ArrayRemoveValue(,,[preserve_keys]);
Note that using ArrayRemoveValue() will remove any of the value you put that is in the array, no matter the index, meaning it can remove more than one item from the array at once if they are the same value.
There are even more useful array functions, and since a lot of them are engine functions, you can find them in the Modme ScriptDocs. I feel the above functions are pretty self-explanatory, so I won't spend any more time on them.

NON-ENTITY ARRAYS

Though probably most of my use of arrays comes the function GetEntArray(), there are plenty of useful ways to use arrays that aren't necessarily of objects in radiant.
For example we might want to create an array of strings, and we can't use GetEntArray() to accomplish that, so instead we use:
melon_phrases = array( "green &amp; red, big as my head","round and plump, give me some","hard yet soft, let me crunch");
note that this will preserve the order the strings were put in, so the "green & red" phrase will be at index 0, the "round and plump" phrase will be at index 1, and the "hard yet soft" phrase will be at index 2.
This means if I were to use a For or Foreach Loop, I would know exactly what order these strings would be run in:
foreach(phrase in melon_phrases)
{
   IPrintLnBold(phrase);
   wait(4);
}
If I wanted to randomize the order however, I could use a handy function from array_shared.gsc (#namespace array) called randomize():
randomized_array = array::randomize( original_array );
Speaking of random, what if I wanted to just use one random value from an array, instead of all of them in a random order? Since indexes are always integers, I can use:
integer = RandomInt();
like this:
random_integer = RandomInt(melon_phrases.size);
IPrintLnBold(melon_phrases[random_integer]);
While RandomInt() definitely has uses outside of arrays, I feel it is important to point out as I commonly use it with arrays. It will always return a value from 0 to the number you put in minus 1, so it feels designed for putting an array's size in there, because as I have mentioned before an array's size will always be 1 more than the last used index in the array.
There are still plenty more cool things you can do with arrays, and I can't point out all of them, so you'll just have to find them yourselves. I know arrays can be confusing, but they are an absolute must to understand if you wish to create more efficient code.
See ALL Tutorials

broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
qwerty195's Groups
qwerty195's Contact & Social Links
Last post by qwerty195 - 1 day ago
ABNORMAL202 SCRIPTING TUTORIAL 7: WHILE LOOPS
See ALL Tutorials

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

broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
qwerty195's Groups
qwerty195's Contact & Social Links
Last post by qwerty195 - 1 day ago
ABNORMAL202 SCRIPTING TUTORIAL 6: PROPERTIES
See ALL Tutorials

DESCRIPTION

Properties are very similar to variables, and I probably would've talked about them in the variables tutorial, however I thought that one was long enough and didn't want to overwhelm.

Properties are just more ways we can store information into a variable, and you'll see them quite a lot.


CREATING A PROPERTY

You can create a property on a variable simply by putting a "." at the end of it and then adding the name to your property, and finally defining it.

andrew = GetEnt("andrew","targetname");

andrew.gender = "male";
In the above example, I made a variable andrew (with some ent in radiant stored in it), and then gave it the property of "gender", which I defined as "male".
Just like with variables, properties can store numbers, strings, booleans, and even entities.
andrew.clip = GetEnt("andrew_clip","targetname");
We can do all the same things we can do with variables with properties. For example using in functions:
andrew.clip Delete();
It's important to note if this code was executed, the entity in radiant with targetname: "andrew_clip" would be deleted, not the entity with targetname: "andrew", because the property is being sent to the Delete() function, not the actual andrew variable.
Properties are also often used to check for certain conditions in If Statements:
if(isdefined(andrew.gender) &amp;&amp; andrew.gender == "male")
{
   IPrintLnBold("By golly, you're a man!");
}
Really the sky is limit. You can even make properties of properties:
andrew = GetEnt("andrew","targetname");
andrew.clothing = "on";
andrew.clothing.top = "t_shirt";
andrew.clothing.top.color = "red";
It should be noted that passing a variable that has properties on it will retain all properties on it in the function it is being passed to.
for example:
   andrew = GetEnt("andrew","targetname");
   andrew.clothing = "on";
   andrew.clothing.top = "t_shirt";
   andrew.clothing.top.color = "red";
   andrew thread clothing_appraisal();
}
function clothing_appraisal()
{
   if(isdefined(self.clothing) &amp;&amp; self.clothing == "on")
   {
      if(isdefined(self.clothing.top) &amp;&amp; self.clothing.top == "t_shirt")
      {
         if(isdefined(self.clothing.top.color) &amp;&amp; self.clothing.top.color == "red")
         {
            IPrintLnBold("I think red looks rather nice on you");
         }
      }
   }
}

LEVEL PROPERTIES

Remember that variable I talked about earlier, that can be accessed from anywhere and is the same entity according to all scripts? that variable is called level, and there's a reason Sublime highlights it in purple.
Because it's the same everywhere, setting properties on the level variable makes it easy to access said properties wherever, from any script/function/you name it. Using level properties is the quick & easy solution to passing data, without having to call, thread, or pass arguments.
However there's a reason I've introduced this a bit late, in tutorial #6, because I see a lot of novice scripters overuse to death the level properties, myself included. Because of how easy it was to use, I used it for a bunch of things that using self, or arguments would have done fine for, and that led to me not knowing how to pass data in other ways than level properties.
Other than that, Why shouldn't you use level properties?
- You don't want to accidentally create a property that has the same name as one already defined in Treyarch scripts, as you could really break stuff by overriding a Treyarch property, or having yours overridden. (though this is also a problem with setting properties on players, or any common entity that's going to be in the game regardless of the map)
- Setting tons of level properties (for things that don't need it) can make your scripts a lot harder to follow, for other people or yourself later. 
See ALL Tutorials

broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
qwerty195's Groups
qwerty195's Contact & Social Links
Last post by qwerty195 - 1 day ago
ABNORMAL202 SCRIPTING TUTORIAL 5: SCRIPT-RADIANT RELATION
See ALL Tutorials

DESCRIPTION

We've done a lot of talking about script theory, but how can we actually apply this to our maps? There are a lot of cool tricks as well as simple essentials to know about how we can use radiant and our GSC together.


KVPS

You've no doubt heard of or used KVPs before, for example for making zombie_door's or setting up your zones. A KVP is a very simple but very powerful tool. It's simply two peices of data paired together: a key and a value.

These can be set in radiant on pretty much everything. You can access an entity's KVPs by pressing "n" while having it selected. 

It should be noted that if you want to use a model in script, in radiant it should be a script_model, and if you want to use a brushmodel in script, in radiant it should be a script_brushmodel.

When you make something a script_model or script_brushmodel, you'll notice it already starts out with some KVPs:



We can access these KVP's in script. But first we must grab the entity in script.

The most common way to grab an entity in script is to give it a custom value for the targetname (in radiant) and then use GetEnt() (in script):


function joseph()
{
   my_main_man = GetEnt("joseph","targetname");
}
there are other keys that also work with GetEnt, such as script_noteworthy, target, classname, or script_string. Not all keys work with GetEnt() however. But that doesn't mean we can't use our custom keys in script.

PROPERTIES

When we get an entity from radiant in script, it stores all the values on that entity into properties based on the keys of the KVPs it has. For example, if I set a custom KVP in radiant such as:

the value is stored just like this, automatically in script:
my_main_man.gender = male;
this is great for If Statements. We could use it like this:
my_main_man = GetEnt("joseph","targetname");
if(my_main_man.gender == "male")
{
   IPrintLnBold("Joseph... is a man");
}
or another common usage, storing vectors:

my_main_man = GetEnt("joseph","targetname");
my_main_man MoveTo( my_main_man.origin + my_main_man.script_vector, 5);

ORIGINS/ANGLES

All entities start out with an origin key and angles key. While they aren't particularly special, they are used quite a lot so I wanted to make a quick section about them.
The origin is the XYZ coordinates of where the entity's origin is located in the map. You'll notice as you move the object in radiant, the value for origin changes automatically in the KVPs.
it's important to note it is specifically the entity's origin. You can see each entity's origin as a hollow blue cube in the 3D view:

For the most part, the origin is located somewhere in the middle of the object, or where it would touch the ground.
The angles are the Roll, Pitch, and Yaw rotation of the entity that will change as you rotate the entity.
the roll changes as you rotate around the X-Axis, the pitch if you rotate around the Y-Axis, and the Yaw if you rotate around the Z-Axis.
Knowing the object's angles/origin is often important for using functions such as:
moveto(,,[acceleration time],[deceleration time]);
rotateto(,,[acceleration time],[deceleration time]);
which are very commonly used.

RADIANT'S AUTO-TARGETING SYSTEM

You may have noticed in making zombie_doors that you can have certain entities "target" other entities, by giving the targeting entity the key "target" with the value of that key being the targetname of the entity being targeted.


As you can see, when an entity is targeting another, a red line appears between the two with the arrow pointing towards the entity being targeted.
this makes accessing the targeted entity simple in script if you already have the targeting entity:
headless_soldier = GetEnt("dead_soldier","targetname");
joseph = GetEnt(headless_soldier.target,"targetname");
notice I only typed in one actual targetname, "dead_soldier". The other targetname was gathered through using the target of the other entity.
This brings me to Radiant's automatic targeting system. If you select two entities then press "w" it will make the first entity target the second, assigning an auto-targetname for the targeted entity that looks like this:

the number will change each time you do it, so no two entities using the auto-target system share the same targetname.
Other things to note:
  • you can chain targets: an entity can target another entity which targets another entity and so on
  • an entity can target multiple entities if they all share the same targetname
  • multiple entities can target the same entity if they share the same target

TRIGGERS

Triggers are very useful in script, and I will go into more detail on them later. Triggers can be placed in radiant and there are several different types of triggers.
Here are some of the most common ones I use:
  • trigger_use : You can give it a hintstring. Is "triggered" when a player presses their interact button while looking at it.
  • trigger_multiple : "triggered" by a player touching the trigger_multiple. Also useful to use the IsTouching() function with.
  • trigger_damage : "triggered" by something dealing damage inside it.
  • trigger_hurt : hurts players while they are touching it.
  • trigger_radius : creates a perfect sphere around it, that is "triggered" when a player enters it. Also useful to use the IsTouching() function with.
When a trigger is "triggered", it passes the "trigger" notify on itself in script. Meaning if we use a waittill, we can make the code effectively wait until the trigger is triggered, before doing something:
trig = GetEnt("my_trigger","targetname");
trig waittill("trigger");
IPrintLnBold("TRIGGERD");
See ALL Tutorials

broken avatar :(
×
broken avatar :(
User
Date Registered: N/A
Last active: N/A
Posts
N/A
Respect
0
Primary Group
Member
×
qwerty195's Groups
qwerty195's Contact & Social Links
Last post by qwerty195 - 1 day ago
ABNORMAL202 SCRIPTING TUTORIAL 4: IF STATEMENTS
See ALL Tutorials

DESCRIPTION

If Statements after very important in coding. They let you check if a certain condition is met, and then do something. Or if that something is not met, do another something. OR if that something is not met but this something is do this something....

If Statements are pretty easy to get the hang of, and are very powerful. So let's hop in:

CREATING AN IF STATEMENT

In order to create an if statement, you first have to have something that you will be checking for if it's true or not. Remember earlier when I talked about booleans? basically we'll need some sort of variable that can store true or false (or 1 or 0).

so let's set a simple variable to a boolean:
im_a_good_student = true;
and make an if statement checking if that is indeed true:
if(im_a_good_student)
{
   IPrintLnBold("Good for you. What, you want a cookie or something?");
}
notice:
  • the word if
  • the ()
  • where you put what you're checking is true (inside the ())
  • there is no ; 
  • the {}
so if the variable im_a_good_student is in fact equal to true, the code inside the {} of the if statement will be run, and this case print that string to the screen. If it is not true, the if statement will simply be skipped over.
It's important to note you don't always have to directly set and check a variable to be true. you can actually call functions inside an if statement, provided they will return a boolean.
lot of different Engine functions (and I mean a lot) return booleans. for example pretty much anything function that starts with the word "is" returns a boolean, such as: IsMeleeing(), IsPlayer(), IsWeapon(), etc.
so instead of doing it the long way like this:
weapon = GetWeapon("smg_fastfire");

this_is_a_weapon = IsWeapon(weapon);
if(this_is_a_weapon)
{
   IPrintLnBold("that's a weapon alright");
}
we can take the shortcut:
weapon = GetWeapon("smg_fastfire");

if(IsWeapon(weapon))
{
   IPrintLnBold("that's a weapon alright");
}

ELSE

Sometimes if a certain condition in our if statement is not met, we don't just want to skip over the code, but do something else entirely...
lucky for you that can be accomplished pretty easily:
if(im_a_good_student)
{
   IPrintLnBold("Good for you. What, you want a cookie or something?");
}
else
{
   IPrintLnBold("I expected better from you");
}
notice:
  • the word else
  • there is no condition I'm checking for is true or not inside the else statement. This is because the code in the else statement is only activated it the if statement above is not true
  • the {}
  • you must have an if statement before you have an else.

ELSE IF

So far these all make pretty logical sense if we look at them English-wise. if something, do something. else do this other thing. now let's keep that going with the hybrid baby of if and else, the else if().
just like the else, there must be an if statement before you can have an else if. the else if is similar to the if statement, as it checks if a condition is met, and will be skipped over if it isn't. 
if(im_a_good_student)
{
   IPrintLnBold("Good for you. What, you want a cookie or something?");
}
else if(math_is_hard)
{
   IPrintLnBold("okay I'll give you that. But that's no excuse");
}
else
{
   IPrintLnBold("I expected better from you");
}
in this case first it will check if im_a_good_student is true. if it is, it will execute the code inside the first if statement, and nothing else.
if im_a_good_student is not true, it will then move to the else if statement and check if math_is_hard is true. If it is, then it will execute the code inside the else if statement, and nothing else.
finally if neither the if statment or any else if's are met, than the else code will activate.
note that you can have as many else if's in a chain as you want, just remember it needs to start with an if statement:
if(im_a_good_student)
{
   IPrintLnBold("Good for you. What, you want a cookie or something?");
}
else if(math_is_hard)
{
   IPrintLnBold("okay I'll give you that. But that's no excuse");
}
else if(life_is_hard)
{
   IPrintLnBold("let me play the world's tiniest violin for you");
}
else if(im_a_victim_of_circumstance)
{
   IPrintLnBold("uh huh...");
}
else
{
   IPrintLnBold("I expected better from you");
}

AND'S/OR'S

We can also check for more than one condition to be met inside an if statement before the if code is executed.
in GSC language:
and = &&
or = ||
note that for or those are not lowercase L's or capital i's, but the vertical line which you can make by holding shift and pressing the "\" button on your keyboard.
so as you might expect, having an and means all conditions must be met, and having an or means just one of the conditions has to be met:
if(the_month_is_may &amp;&amp; the_day_is_the_twenty_ninth)
{
   IPrintLnBold("HAPPY BIRTHDAY!!!!");
}
if(the_month_is_may || the_day_is_the_twenty_ninth)
{
   IPrintLnBold("what? I'm not celebrating your birthday. it's 3 months away...");
}
 in the above case, the first code with the and in the if statement will only get activated once a year.
for the bottom case with the or in it, it would get run on the 29th of every month, and on every day in the month of may, because just one of those conditions has to be met.
it should be noted you can chain more than one and or or in the same if statement:
if(you_brought_the_cake &amp;&amp; I_brought_the_balloons &amp;&amp; she_brought_the_drinks)
{
   IPrintLnBold("what a fun party...");
}
if(you_provide_gas || you_provide_grass || you_provide_ass )
{
   IPrintLnBold("come on in");
}
See ALL Tutorials

Loading ...