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:
- 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!
Angles
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 Destructors
New 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.
Code: Select all
CRANE_DATA crane_name = (X,Y) home_rotation homecrane
Code: Select all
CRANE_DATA city_crane = (127.5,127.5) 180 NO_HOMECRANE
Code: Select all
CRANE_DATA crane_in = (127.5,127.5) 180 NO_HOMECRANE FIRST (125.5,125.5,3.0) 180
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.
Code: Select all
CRUSHER crusher_name = (X,Y)
Code: Select all
CRUSHER town_crusher = (127.5,127.5)
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.
Code: Select all
DESTRUCTOR destructor_name = (X,Y,Z) (check_width,check_height)
Code: Select all
DESTRUCTOR town_destructor = (127.5,127.5,3.0) (2.0,1.0)
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:
Code: Select all
CONVEYOR conveyor_name = (X,Y,Z) (width,height) speedX speedY
Below is an example of a conveyor that moves things north (top of screen):
Code: Select all
CONVEYOR conveyor_in = (127.5,127.5,3.0) (1.0,7.0) 0 -1
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).
Code: Select all
GENERATOR crusher_generator = (127.5,127.5,3.0) 0 MOVING_COLLECT_01 80 80
Code: Select all
DECLARE_POWERUP_CARLIST (car01,car02,car03...car16,car17,car18,car19)
Machine Gun
Rocket Launcher
Electrogun
Molotov Cocktails
Grenades
Shotgun
Electro Baton(1)
Flame Thrower
Silenced Machine Gun
Health
Armour
Get Out of Jail Free Card
Cop Bribe
Invulnerability
Double Damage
Fast Reload
Electro Fingers
Respect
Invisibility
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.
Code: Select all
DECLARE_CRANE_POWERUP (second_crane_name,powerup_generator,X,Y,Z)
[syntax=mis]CRANE_DATA redn_crane_in = (004.5,072.5) 200 NO_HOMECRANE FIRST (5.50, 75.50) 180 // picks up car and drops at crusher
CRANE_DATA redn_crane_out = (007.5,077.5) 135 redn_crane_in SECOND (9.50, 75.50) 180 // picks up wreck from crusher and drops on first conveyor
CRUSHER redn_crusher = (005.5,075.5) // the car crusher
DESTRUCTOR redn_destructpr1 = (009.5,083.5,3.0) (2.0,1.0) // placed at end of conveyor to delete items
DESTRUCTOR redn_destructor2 = (004.5,078.0,3.0) (2.0,1.0)
CONVEYOR conveyor1 = (009.5,077.5,3.0) (1.0,13.0) 0 1 // Conveyor for car wreck going in
CONVEYOR conveyor2 = (004.5,080.5,3.0) (1.0,07.0) 0 -1 // Conveyor for powerup coming out
GENERATOR redn_crane_gen = (004.5,082.5,3.0) 0 MOVING_COLLECT_01 80 80 // generator for car crusher powerup
DECLARE_POWERUP_CARLIST ( BUG , STRIPETB , TBIRD , SPRITE , FIAT , SPIDER , BUS , TRANCEAM , VTYPE ,
PICKUP , MONSTER , MORGAN , COPCAR , STRATOSB , STYPECAB , ZCX5 , MERC , EDSELFBI , STYPE ) // accepted cars for different powerups
DECLARE_CRANE_POWERUP (redn_crane_out,redn_crane_gen,009,081,3) // detects wreck type going through, place before first destructor[/syntax]
Garages
Add 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.
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.
[syntax=mis]PLAYER_DATA p1 = (127.5,127.5,2.0) 25 180 // the player
PARKED_CAR_DATA limo01 = (130.5,127.5,2.0) 02 180 LIMO // the limousine
DECLARE_DOOR_INFO (969,976,2) // tile numbers in STY file with start tile, end tile and animation speed
DOOR_DATA garage_door = DOUBLE (101,113,2) (101.0,114.0,2.0,2.0,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
COUNTER loop = 1 // general game loop
COUNTER limo_parked = 0 // has the limo been parked yet?
LEVELSTART // start the level!
WHILE_EXEC (loop=1) // game loop
// check if limo is in front of garage door and park car if it is close enough
IF ((IS_CAR_IN_BLOCK(limo01 , 101.0 , 112.0 , 2.0 , 2.0 , 3.0 ) )
AND (limo_parked = 0))
PARK (limo01,garage_door ) // automatically 'pull' the car in to garage and teleport player out
SET limo_parked = 1
ENDIF
// check if parking procedure has finished then give $5,000 to player
IF ((limo_parked=1)
AND (HAS_PARK_FINISHED()))
SET limo_parked = 0
ADD_SCORE (p1,5000)
ENDIF
ENDWHILE
LEVELEND[/syntax]
IF Statements and Counters
Worth a mention on how to do some basic IF statements!
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:
[syntax=mis]OBJ_DATA powergen01 = (127.5,127.5,2.0) 0 POWERGEN // power generator object
COUNTER loop = 1 // general game loop
COUNTER gen_dead = 0 // has the generator been destroyed? 0 for no, 1 for yes
LEVELSTART
WHILE_EXEC (loop=1) // while the counter 'loop' is set to 1, loop everything below
IF ((CHECK_OBJ_MODEL(powergen01,POWERGEN_DEAD)) // has power generator been destroyed?
AND (gen_dead = 0))
SET gen_dead = 1 // power generator now destroyed
DISPLAY_BRIEF (1337) // message saying "You destroyed the generator!"
ENDIF
ENDWHILE // end of WHILE_EXEC loop
LEVELEND[/syntax]
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!
[syntax=mis]IF (CHECK_CHARACTER_HEALTH(p1,0))
GIVE_WEAPON (p1,ROCKET_LAUNCHER,99)
ENDIF[/syntax]
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:
Code: Select all
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)
Cars
- 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).
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.
Code: Select all
MAP_ZONE nice_area = (700,500,50,150,600,50,50,100,0,200,0)
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.
Code: Select all
MAP_ZONE prison = (0,0,0,0,400,0,0,0,1000,0,0)
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.
Phones
As 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.
Shops
Perhaps 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.
Trains
Slow 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.
Vehicles
Worth 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.