Alex "Y_Less" Cole's n00b guide to coding.Its finally here: Part 2: Using Threads and Labels.
In this tutorial I will be exploring how to use threads, labels and ifs to check for conditions being met in order for more things to be done.
1. Labels.A label names a small section of code so it can be called at any time, e.g.
| CODE |
:Label0B0910 00D6: if 0? 00DF: actor 18576?? driving 004D: jump_if_false £Label0B0925 03E2: actor 18576?? exit_car |
This is just a random bit of code I got from the main.scm, but anytime you put
| CODE |
| 0002: jump £Label0B0910 |
it will run that piece of code, and any bits linked to it by it, e.g. all the bits of code under £label0B0925 (and al the bits under that), (which happens to be just this):
| CODE |
:Label0B0925 0002: jump £Label0B0942 |
2. Threads.A thread is a label, or collection or labels, that runs continuously to see if the player is doing something, every mission has a thread to check if the previous mission has been competed, and if it has, to check if the player is in the spot that triggers the mission (i.e. the contact point), and if those are both true, runs the mission. Threads are used to run all the things that happen in the game, they don't do them, generally, but will check conditions and run the associated mission if all the conditions are met. There are exceptions, threads can and do do things themselves, but generally these are more complex.
3. Ifs.These are the bits that actually check for if something is happening, and jump somewhere if it isn't happening. This may seem a little backwards at first but is quite sensible as it means you can say 'Is this happening? No? Oh well sod off then'.
| CODE |
00D6: if 0? 0214: pickup $PRINT_WORKS_ASSET picked_up 004D: jump_if_false ££Label00CA42 0417: start_mission 36? 004E: end_thread |
This is another random piece of code taken from the Print Works Asset buying thread (surprisingly). It checks to see if the player has picked up the buy asset marker (by this point in the code it will be available), and if they have, run the buy Print Works asset mission (yes, even buying things is classed as a mission). But if it hasn't been picked up, it never gets to that piece of code as it is redirected (jumped) to another label, which restarts the thread to check again. if 0? means the code will check 1 condition, 1 means 2 etc, 20+ are ors'. e.g. if 21? means if condition 1 OR condition 2 is met, return true.
4. Using them together.There are a few things that all threads need to work, firstly a definition. Without this, the code will not know that the thread exists and will not run it to check.
| CODE |
| 004F: create_thread ££Labelmy1stlabel |
This OpCode is always used for this, you just change the label name depending on your threads first label.
Second, you need to create the label for the first part of the thread and, although from what I have read, this is not essential, name it.
| CODE |
:Labelmy1stlabel 03A4: name_thread "my1stth" |
This tends to be all there is in the first label, although I belive this is more down to conventon and good coding practice than actual need. When using multiple labels in a thread, unless you jump in on label, the code will continue running through to the next label. e.g.
| CODE |
:Labelmy1stlabel 03A4: name_thread "my1stth"
:Labelmy2ndlabel 0001:wait $default_wait_time ms |
This will run the first label, then continue on to the second part. You will also notice a wait in there, the code needs this or the game will crash. It would run the thread continuously, but that gives it a break (in ms) so it is not running it then re-running straight away, the length of the wait depends on how often or quickly the thing could happen. If you were writing code to see if the player is jumping, you would need a short wait, but if you were checking to see if they have completed a mission, it can be a longer wait as they will have still completed is several seconds later, $default_wait_time is a standard variable with a preset time in.
The final thing they need is a bit at the end to loop back to the beginning to re-run the code and re-check. This tends to also be in its own label so you can jump to it if a condition is not met.
| CODE |
:Labelmy3rdlabel 0002: jump ££Labelmy2ndlabel |
Note the jump to ££Labelmy2ndlabel, this is because we don't need to re-re-name the thread.
5. My 1st ThreadIn section 4, we have already established how to run a thread, and all the esentials needed for it, so now we can start constructing our own thread. We will use the pink marker created in the last part and the truck to create a thread to only spawn the truck after you have stepped in the pink marker.
First we will need to stop the truck spawning in the first place, but we still need it to be defined, so go to the part of the code where your truck is, i.e. this bit
| CODE |
014B: $my1stcar = init_parked_car_generator #PACKER -1? -1? 0? alarm 0? door_lock 0? 0? 10000& at 470.9084! -121.0596! 10.36153! angle 0! 014C: set_parked_car_generator $my1stcar cars_to_generate_to 101? |
and change the 101 at the end to just 0.
| CODE |
| 014C: set_parked_car_generator $my1stcar cars_to_generate_to 0? |
Now if you placed your marker at the same place as me (over-looking the truck from a distance), then the co-ordinates for your blob should be:
556.2355! -3.073752! 14.3036!
, if not just use your instead.
We already have th start of our thread, with :Labelmy2ndlabel being the main part, but we need to make it check that the player is near the pink blob. There are alot of OpCodes which will check where a player is, so go to search and search for 'near' (or use F1) we want the player to be on foot when doing it, not in a car, so keep going until you find this line.
| CODE |
| 00F6: player $PLAYER_CHAR 0? ()near point on foot 1812?? 1816?? 1820?? radius 1.4! 1.8! 1.5! |
It is using a variable to define the co-ordinates, so change these to ours, we can also tell that this is an if statement check by the indent, which most of them have (if you aren't sure which is which, look in the OpCodes list file which has a complete list of all the OpCodes and what sort they are).
| CODE |
| 00F6: player $PLAYER_CHAR 0? ()near_point_on_foot 556.2355! -3.073752! 14.3036! radius 1.4! 1.8! 1.5! |
You can leave the radius as it is, this just says how close to the point you need to be. Now put this in an if statement with a jump_if_false to my3rdlabel, and you will have your first check (if 0? as there is only one condition).:
| CODE |
00D6: if 0? 00F6: player $PLAYER_CHAR 0? ()near_point_on_foot 556.2355! -3.073752! 14.3036! radius 1.4! 1.8! 1.5! 004D: jump_if_false ££Labelmy3rdlabel |
Now we know when the player is in our blob, we need to do something with that fact, as in, make the truck spawn. This is very easy, just copy the 014C opCode line you edited earlier, paste it under the if statement, then change the number back to 101. If you have done all this, you should have code something like this:
| CODE |
:Labelmy1stlabel 03A4: name_thread "my1stth"
:Labelmy2ndlabel 0001:wait $default_wait_time ms 00D6: if 0? 00F6: player $PLAYER_CHAR 0? ()near_point_on_foot 556.2355! -3.073752! 14.3036! radius 1.4! 1.8! 1.5! 004D: jump_if_false ££Labelmy3rdlabel 014C: set_parked_car_generator $my1stcar cars_to_generate_to 101?
:Labelmy3rdlabel 0002: jump ££Labelmy2ndlabel |
If we compile and run this it will work.
Before:

After:

Unfortunately, as you can see here:

, the marker is still there (and active) so everytime you go there again, you can still see it and it will continue to turn on the truck, even though it is already there. The easiest way to counter this is to set a variable that says it has already been done, then disable the markers. All the markers use the same command to disable them:
| CODE |
| 0164: disable_marker 264?? |
(after search). There are 2 markers in our code, $my1stblob and $my2ndblob, the pink marker and the radar marker, so copy the line twice and replace the variables with our variables.
| CODE |
0164: disable_marker $my1stblob 0164: disable_marker $my2ndblob |
Put this with the set_parked_car_generator line, and it will turn off the markers at the same time as it turns on your car.

Your first thread is now basically complete, you can leave it as that, or you can add, as mentioned before, a variable so that it doesn't keep doing things it has already done. This is another important OpCode, 0004.
| CODE |
| 0004: $my1stvar = 1? \\ integer values |
Put this with the other parts done after the if statement and when you stand in the circle, it will set your variable to 1, which is all well and good, but you need the code to know that it is 1. Using the if statement, change the value to 1, for 2 conditions, then add a new line to check if $my1stvar is 0 (1 means it has already been done and will skip the bits being done). However, this time, I'm not going to tell you the OpCode, you can look it up yourself, but I will tell you you are looking for
Practice activites:1. Place a pink marker and a radar marker in the middle door of the large building next door to 3321 Vice Point (the one with the armour next to it).
2. Make a thread and get it to run with a delay of 500ms.
3. Add an if statement to check whether the player is within a radius of 4! 4! 4!, in a car, of it (don't add a section to check if you have done it before).
4. Use OpCode 00BC, and text "TAX2_4" to print a message to the screen when you are there.
5. Add to the if statement so the text will only appear if you are driving a Boxville (you may want to spawn one somewhere for ease of access).
Thats it for this Part, I don't know what to do for the next yet, but if I think of anything, or someone gives me a good idea, then I will do another. So again, please comment below.
This post has been edited by Y_Less on Friday, Jul 9 2004, 08:12