Advanced Warning - this post is VERY long and will, when Ben gets the time, be added to my tutorial list on his site. These are updates to my existing tutorials and some new ones!
Figured it was about time I updated some of my tutorials that Ben has on his site
. I'll post some new changes here that you can update the tutorials in time with and I'll split them by category. I know that you mentioned that you'll update the phone and remote control with my new examples so I won't put them here.
Will leave it up to you where to place them in the page! On some I'll re-write the introduction of some that you can use and I'll annotate things in green text that doesn't need to be copied but inform you of what/why I'm changing it
Can I also add that it might be useful to split the table of tutorials from other categories like useful tiles in STY files, multiplayer set-up, zones and the likes.
Possible things I intend to add:
Last Update: 07/02/2012Angles
- Working garage/park example (such as waiting for a limo to be parked and giving $5,000 for it). Added!.
- Working crane/crusher tutorial with possible map example. Added (code only)!
- Working timer example.
- Basic IF statement example(s). Added!
- Declaring zones such as setting ratios and how to make gang cars appear (this is briefly mentioned in the Gangs section but could do with expanding) and making zones like the prison where just gang members appear. Added!
You can specify the angle of any object, character or vehicle by using angles to make it face a certain direction in game when you declare them. Nearly all objects use the first set of angles listed below, but phones are unique and use different angle numbers which is shown below in the second set of angles.Slightly different introduction and might be stating the obvious, but figured might as well include reference to objects, characters and vehicles instead of just objects. Also explained a little about phone angles being different. Might also be worth mentioning that north is counted as the top of the screen, east is right of the screen and so on.Cranes, Crushers, Conveyors and DestructorsNew section on how to create these. Feel free to pick a better name/title for this!
No doubt you will have seen the cranes in single player that give you certain weapons or powerups depending on the car you deliver to it. The first crane picks up the car, drops it on a crusher that destroys it, a second crane picks up the wreck and places it on the first conveyor. This conveyor delivers the wreck to a a destructor (which removes the wreck) and a weapon or powerup arrives on the second conveyor. If the powerup is not picked up by then, it too is destroyed.
Sounds pretty straight forward, right? Crushing cars to get powerups? There is quite a bit of code involved and the map itself needs to be set up in such a way that both cranes can reach the crusher (one to drop it in and one to pick up the wreck that goes on first conveyor) as well as make spots for conveyors. At each end of a conveyor there is a hidden destructor which is usually covered up (it's an invisible object but looks strange when the wrecks/items suddenly disappear!). You also need to make sure that the player can access the powerup before it is destroyed too.
Below are each of the components that make up the complete car crusher system.Cranes
Cranes are an essential item in being able to pick up cars and drop them in places including a patch of ground, on a trailers and even crushers. The cranes themselves are ideally positioned on a crane tower (built in the map editor with the lid of the top cube set to field) which is usually 3 blocks tall so that the crane arm is able to pick up and drop stuff without clipping through scenery but varies by map and where you place them.
Below is the code you'll need to make a basic crane, this is the most useful for picking cars up from trailers or putting them on.
CRANE_DATA crane_name = (X,Y) home_rotation homecrane
The 'home_rotation' is the angle the crane faces when it is not doing anything (being idle) between 0 and 359. The 'homecrane' is used if this crane is linked to another crane, so this value would either be a name of another crane or use 'NO_HOMECRANE' if this isn't linked. There is no need to put a height (Z) coordinate in as the game does this automatically. An example:
CRANE_DATA city_crane = (127.5,127.5) 180 NO_HOMECRANE
If you are going to use linked cranes, which you'll need for a car crusher system, you'll need to use an additional parameter after the 'homecrane' which is either 'FIRST' or 'SECOND'. Sounds a bit confusing but easier to show with an example. Below shows two linked cranes, the first crane is not actually linked to any other but the second crane needs the first one to work, so needs the name of the first one followed by 'SECOND' and some coordinates to drop the item with the angle it will then face.
CRANE_DATA crane_in = (127.5,127.5) 180 NO_HOMECRANE FIRST (125.5,125.5,3.0) 180Crushers
CRANE_DATA crane_out = (122.5,122.5) 000 crane_in SECOND (120.5,120.5,2.0) 180
Crushers are very simple on their own; they will simply crush any car that goes inside it and will turn it into a wreck. Note that this crusher will kill any passengers (or even the player!) if they are still in a car when it gets crushed. Like cranes, you do not need to use a height (Z) coordinate as the game will place it automatically on a valid field surface.
CRUSHER crusher_name = (X,Y)
The 'crusher_name' is a unique name for this and the X and Y are coordinates. An example:
CRUSHER town_crusher = (127.5,127.5)Destructor
Like crushers, destructors are simple objects, except that whatever goes into range of a destructor is instantly killed/deleted and disappears. Again, this will kill the player if they go too close. These are placed at the end of conveyor belts for best effect and covered up so the player can't see the items disappearing.
DESTRUCTOR destructor_name = (X,Y,Z) (check_width,check_height)
The check_width and check_height will check a certain area around the position of the destructor that will destroy anything that comes in range of it. An example:
DESTRUCTOR town_destructor = (127.5,127.5,3.0) (2.0,1.0)Conveyor
Conveyors are items that will move any objects on top of them in a desired direction including players, cars and objects. In the case of our car crusher system, conveyors are used to move the wrecks to be destroyed and a powerup to appear at another conveyor. Below is the code you'll need:
CONVEYOR conveyor_name = (X,Y,Z) (width,height) speedX speedY
When placing the conveyor you need to place it in the middle of the area you want it in as the width and height is based around that. For example, a height of 8 would mean that, from the centre position, there would be a conveyor 4 blocks each side of it. The same is true for width. For speedX, a positive value will move things to the right and negative to the left. For speedY, a positive value will move things down and negative will move it up. A speed of 0 will not move in that direction.
Below is an example of a conveyor that moves things north (top of screen):
CONVEYOR conveyor_in = (127.5,127.5,3.0) (1.0,7.0) 0 -1
It is worth mentioning that speedX or speedY speed of 1 (or -1) is sufficient for a car crusher system and any higher would make it extremely fast moving. In the map editor, it is beneficial to use the conveyor belt animation with an animation speed of 3 so that it matches up correctly in game.Completing the Car Crusher System
With the different parts explained, it is now time to put them all together to make a complete car crusher system. Before that though, there are a few extra items required to make it complete.
The first is we need a GENERATOR to create the powerup based on the crushed car and simple to do. While it appears that a generator will generate a certain item and wouldn't, we do not actually switch it on. This is simply used to make a variable generator tied uniquely to the car being crushed. The generator speed, however, is still used and will define how bunched up the items are when they come out. Finally, this generator is placed at the start of the second conveyor (first conveyor is used for the wrecks).
GENERATOR crusher_generator = (127.5,127.5,3.0) 0 MOVING_COLLECT_01 80 80
The second item is to declare what cars will trigger each powerup. This is highly dependant on the STY file you use for your map with each one being different since different cars spawn. You need to declare nineteen (19) car names (the script name for cars found the in the vehicle tutorial) here like the following:
Each car in the list is tied to a powerup, and in order they are declared are:
Silenced Machine Gun
Get Out of Jail Free Card
Any car that can be crushed, but not declared above, will only give machine gun powerups.
(1) = It is advised to either declare a large vehicle that cannot be picked up by a crane such as a bus for car 7 on the declare list or repeating a car that has been previously used to prevent the player from getting the Electro Baton.
Third, and finally, you need to declare which generator will be used for the car crusher powerup system. You need one of these per car crusher system in your map. The coordinates (which are integers and not float points) are placed before the first destructor and acts as a sort of 'scanner' to detect which wrecked car type is passing through before picking the correct powerup. Also, you need the name of the second crane used in the system.
Once all that has been done, below is a complete script with everything mentioned with actual code and all of this is done before the LEVELSTART command. Fit this into your script and change the coordinates to fit your crane and crusher system. This also uses car types from the second city.
GaragesAdd a mention about the checking area of a garage door that setting them to 0.0 will make the game auto-detect a vehicle approaching.
redn_crane_in = (004.5
,072.5) 200 NO_HOMECRANE FIRST (5.50
, 75.50) 180 // picks up car and drops at crusher
redn_crane_out = (007.5
redn_crane_in SECOND (9.50
, 75.50) 180 // picks up wreck from crusher and drops on first conveyor
redn_crusher = (005.5
,075.5) // the car crusher
redn_destructpr1 = (009.5
,1.0) // placed at end of conveyor to delete items
redn_destructor2 = (004.5
conveyor1 = (009.5
,13.0) 0 1 // Conveyor for car wreck going in
conveyor2 = (004.5
,07.0) 0 -1 // Conveyor for powerup coming out
redn_crane_gen = (004.5
,3.0) 0 MOVING_COLLECT_01 80 80 // generator for car crusher powerup
DECLARE_POWERUP_CARLIST ( BUG
, STYPE ) // accepted cars for different powerups
,3) // detects wreck type going through, place before first destructor
Parsed in 0.025 seconds, using GeSHi
Below is a full, working example of a parking system with introduction that uses garage doors and 'pulls' the car in. Could place this near the end of the page?
Below is an example of a very simple, fully working garage that checks if the limousine named 'limo01' is in range of the garage, open the doors, 'pulls' the car in, teleports the player outside and then gives $5,000 to the player. Of course, you will need to create your own garage area in your map for this to work (see above on how to do this in your map) and change the coordinates to fit.
This garage, however, only checks for the one car ('limo01') as part of the door declaration and won't open to anything else. For more advanced doors, you will need to do a check to see if a player/character is in a specific car then use the command "UPDATE_DOOR_TARGET (door_name,car_name)" and is very useful if you want multiple, different cars going to the same garage.
IF Statements and CountersWorth a mention on how to do some basic IF statements!
PLAYER_DATA p1 = (127.5
,2.0) 25 180 // the player
limo01 = (130.5
,2.0) 02 180 LIMO // the limousine
,2) // tile numbers in STY file with start tile, end tile and animation speed
garage_door = DOUBLE (101
,4.0 ) BOTTOM 0 ANY_PLAYER_ONE_CAR CLOSE_WHEN_OPEN_RULE_FAILS 0 FLIP_RIGHT NOT_REVERSED
limo01 // double door on garage, will only open for 'limo01' car
loop = 1 // general game loop
limo_parked = 0 // has the limo been parked yet?
LEVELSTART // start the level!
loop=1) // game loop
// check if limo is in front of garage door and park car if it is close enough
limo01 , 101.0
, 3.0 ) )
limo_parked = 0))
limo01,garage_door ) // automatically 'pull' the car in to garage and teleport player out
limo_parked = 1
// check if parking procedure has finished then give $5,000 to player
limo_parked = 0
Parsed in 0.025 seconds, using GeSHi
If you want to do any kind of checking in scripts you will need to use the IF statement commands to do it. At a basic level, it will check if something is true then do something or do something else if it false. For example, you can use an IF statement to wait for a player to steal a certain type of car and then show an arrow to the next objective, but while waiting it will do nothing. There are a lot of commands you can use inside IF statements including, but not limited to, checking if a character is in a block, a vehicle is at a location, a car has been wrecked, if a character has died, check a players score and many, many more.
While you can place IF statements anywhere in your script, the best place to put them is after the LEVELSTART and WHILE_EXEC commands. Without the WHILE_EXEC loop or outside it, an IF statement will only check if it is true or false once at the time its called and no more. By putting it inside the WHILE_EXEC loop the game will constantly check it and updates it as needs be. As well as this, you will need to combine using the COUNTER command along side your IF statements that can switch an IF statement 'off' as such or else it will keep looping infinitely, and this is definitely bad if it loops adding to the players score!
Counters are declared before the LEVELSTART command and are used to hold an integer value and can be used with IF statements to check if something is true or not to carry on with the next check. For example, using an IF statement to wait for a player to destroy a generator, if the player enters blows up the generator you will use the SET command and the counter name to change the counters value, usually from 0 (generator intact) to 1 (generator blown up). Below is an example of how this would be done in code:
powergen01 = (127.5
,2.0) 0 POWERGEN // power generator object
loop = 1 // general game loop
gen_dead = 0 // has the generator been destroyed? 0 for no, 1 for yes
loop=1) // while the counter 'loop' is set to 1, loop everything below
powergen01,POWERGEN_DEAD)) // has power generator been destroyed?
gen_dead = 0))
gen_dead = 1 // power generator now destroyed
DISPLAY_BRIEF (1337) // message saying "You destroyed the generator!"
ENDWHILE // end of WHILE_EXEC loop
Parsed in 0.022 seconds, using GeSHi
The biggest issue with IF statements is mainly the placement of brackets. You should pay close attention to these and make sure your brackets 'add up'. In the above example, you can count there are four open brackets and four close brackets. If you do not do these correctly the compiler will throw an error! However, with large IF structures it can be a bit of a nightmare getting the brackets in the correct place. Generally, the very first bracket after the IF statement and the last one after the last parameter need to be checked as this is where they should go.
With this, you should be able to create useful checks in your script to do a wide variety of stuff!Using IF Statements in Multiplayer
If you are using IF statements in multiplayer scripts, you will probably find that some commands will crash the game. These are usually IF statements looking for players that are not actually in the game, especially if your script has code to check multiple people. To get around this, you will need to use the CHECK_CHARACTER_HEALTH command and then use your desired IF statement inside that since the game will actually count a non-existent person as having zero health.
Below is an example of checking to see if a player exists in multiplayer, then if they do, give them a weapon. You would then have multiple commands for all the players you want, so you could have this script six times to check for each player!
Parsed in 0.019 seconds, using GeSHi
For a one-off, you could use this after the LEVELSTART command but before the WHILE_EXEC loop, but if you wanted to give the impression of infinite ammo, you could use this inside your WHILE_EXEC loop instead.Map Zones
Many maps have zones in them, mostly restart zones for when the player dies, but this will cover being able to control mostly the navigation and local navigation zones in how many peds and cars will spawn and the likes. This tutorial assumes you have set up a basic navigation zone in your map somewhere, but it is worth mentioning that if you want to use the code below for the zone names you cannot have any spaces in it or else the compiler will throw up an error! You should preferably use one word zone names if you can.Declaring a Map Zone
Once you have a navigation zone in your map, you can tell it what to spawn inside it with the following command:
MAP_ZONE name = (car_density, good_car_ratio, bad_car_ratio, police_car_ratio, ped_density, mugger_density, car_thief_density, elvis_ratio, gang_char_ratio, police_ped_ratio, gang_car_ratio)
This is quite a long list with eleven types of items to spawn. Each value can range from 0 to 1000 and are grouped by cars and peds and the 'ratios' should add up. A density of 1000 will create the most peds and cars in the local area (slightly larger than the screen size) and a density of 0 will not create that type, while average is about 400 to 600. Below are the explanations of each type and how they are grouped:
- Car Density = Overall amount of cars to spawn, from 0 to 1000.
- Good Car Ratio = Ratio of nice looking, expensive cars such as Wellards and B-Types.
- Bad Car Ratio = Ratio of average and poor looking cars such as Minx's, Panto's and Spiders.
- Police Car Ratio = Ratio of police cars driving by.
- Ped Density = Overall amount of peds to spawn, from 0 to 1000.
- Mugger Density = Ratio of muggers (red shirt and shorts who steal money).
- Car Thief Density = Ratio of car thieves (green shirts and shorts who steal cars).
- Elvis Ratio = Ratio of getting an Elvis group to spawn.
- Gang Char Ratio = Ratio of getting gang members to spawn (must be a navigation zone inside a gang zone).
- Police Ped Ratio = Ratio of seeing police officers on foot.
- Gang Car Ratio = Ratio of seeing a gang car drive past (must be a navigation zone inside a gang zone).
With these explained by category, each group can have a total ratio of 0 to 1000 (which would either be your ped density of car density) and each part of that would be split among that. For example, you set an overall car ratio of 700 (pretty busy) and you divide the good car and bad car ratio so they both add up to 700, so you could have 350 each or 200 good car and 500 bad car. The same is true for overall ped density and dividing that up between ped types.
Below is an example zone where its moderately busy with peds and has nice cars driving around with police going past too and few muggers and car thieves, a good example of a posh and rich neighbourhood.
MAP_ZONE nice_area = (700,500,50,150,600,50,50,100,0,200,0)
As you can see, and by referring to the details above, the first four numbers are for the cars, the next six are for peds and the final is for gang cars. The values for each group don't have to add up to the overall ratio as the game will still generate normal cars or peds. So with this, you can easily create custom map areas to make things like run-down, busy industrial zones with lots of thieves and poor cars and nice, posh areas with nice cars and lots of police or anything in between!Gang Member Only Zones and Gang Cars
You might have seen the prison (Alma Mater Prison) and the Cop HQ in the second city in GTA2 and noticed it only contains gang members. If you are wondering how to do this, then read on!
By using the MAP_ZONE declare from above, you can specify exactly what you want to spawn in a zone and in this case you'd want just gang members to spawn. In this example, for a moderately busy gang-only area you'd set the overall ped density to, say, 600 but set the gang ped density to 1000. You might be wondering how a ped type (the gang ped ratio of 1000) can exceed the total ratio of 600, but GTA2 has a nasty habit of placing normal peds in with them and this is no good if you only want gang members!
Below is an example of a gang-only zone which would be used for a prison which is moderately busy but contains no cars of any type, no muggers and no gang cars.
MAP_ZONE prison = (0,0,0,0,400,0,0,0,1000,0,0)
As you can see, the ped ratio is 400 and the gang ped ratio is 1000 meaning that only gang members will spawn in this zone!
Finally, a quick mention on gang cars. While gang members will walk around in a gang area you will notice there are no gang cars driving around. To fix this, you need to use the MAP_ZONE declare and change the final number, the gang car ratio, above 0 to something like 100 or 200. This way you'll see the occasional gang car drive past in your gang zones.Unique Map Zones
In the official GTA2 maps, you will hear on the police radio what zone you are in such as "10-24 in west Zarelli". These unique map zones are not only declared in the script, but they are also tied in with the GTA2 text file (e.gxt) as well as the audio file for that city, meaning that if you were to declare a map zone in your script named "m10" (and an actual zone in your map also called "m10") the game would actually show the zone name as "Escobar" and have the police audio attached to it!
Below is a table of the map zone names (inside your map) and script alongside what zone name will pop-up in game split by what city they originally appear in. The first table of zone names will also have audio attached to them.Need a table here with 3 main headers of Downtown, Residential and Industrial and each further split in 2 with sub-headers of Map/Script Zone Name and In-Game Zone Name.
Downtown are zones m31 to m44, Residential zones are m16 to m30 and Industrial zones are m01 to m15 and need the actual zone names for each from GXT file like Zarelli, Omnitron etc.
Finally, there are other unique zones that are similar to the above with proper names showing up in-game, except these ones do not have audio attached. These zones are usually made as local navigation zones inside the map.Again, need a similar table but this time showing zone names 'w01' to 'w03' for Downtown, 's01' to 's09' for Residential and 'b01' to 'b25' for Industrial.PhonesAs well as adding the basic phone example I made, might be worth emphasizing the fact coloured phones must be in gang zones, perhaps bold it and use the word 'must' instead of 'have'? Of course once the new phone tutorial is added you can then remove the second paragraph about not giving an example. Maybe also update the phone pictures with smaller ones from a STY file?
Also, might be a good idea to put a table header above the code for the various phones in that table with the pictures, perhaps call it 'phone type' since that is what the example shows above it.ShopsPerhaps add a mention of, instead of using the general 'CAR_SHOP' that changes car colour, people can use the 'BUSY_CAR_SHOP' as a variant that only changes the car plate and not the colour. Maybe add it as a new paragraph with code example. I know it's listed in first code example but might be worth separating out to highlight the difference.TrainsSlow Freight Trains
You can make some slow moving freight trains in GTA2 by simply changing the way the entry and exit zones are placed. You still need a valid platform to start this however, but generally by placing the exit zone (where trains speed up) very far away it gives the impression of a slow moving train. I usually place the exit zone a block or two before the entry zone of the next station so the trains still function correctly and doesn't crash the game.
By using the maximum train carriage length of nine you can make pretty large freight trains for your map. For working examples, you can check out the Jailbreak map and the converted GTA1 San Andreas map.Definitely worth a mention and a rather unique way of using trains in maps, could be handy for others in future! Obviously, hyperlinks to Jailbreak and Converted GTA1 Cities pages required.VehiclesWorth mentioning that adding trailers to vehicles only works by using CAR_DATA and not PARKED_CAR_DATA as it's simply ignored by the game, and probably highlight its only recommended to use TRUKCAB1 and TRUKCAB2 to tow trailers. Also could be worth mentioning that you can make any car, not just trucks, carry trailers or other vehicles but can have some undesirable effects and might crash the game.
Could also mention that you can use CAR_DATA name = (X,Y,Z) remap rotation model as an alternative to using PARKED_CAR_DATA.
Would it be worth adding a third column to the remap table with an approximate colour so people can see what it expects to look like?
Might be worth making a new section just about Bank Vans since it is the only one that can use remap 36, with default colour being blue/silver and remap 36 makes them green/silver colour. Probably remove remap 36 from the initial list and place it with Bank Van information.