Mission Coding with Sanny Builder Tutorial
Hi, in Part II we will get some basics of coding, create spheres, actors, cars, markers, texts, panels etc....
If you need to look at Part I it's here.
As in Part I, I recommend you to print the topic using Printable Version of Topic, by clicking print this topic on top right of the first message. Or read it in Sanny Builder's Help by pressing F12 in Articles section.Which I think is the best place to read it. You can print it as well from Sanny Builder's Help.
A lot of examples here use globals (variables that start with a $ like : $markerxx, $car00, $actor00, $myweaps00) but it doesn't mean you cannot use locals (varaiables that end with a @ like : 0@, 1@, 28@, 1004@). I use gobals so I can name them for easier understading. But when you'll be coding you should use locals, for many reasons they are better. You only need to use gloabls when you need the varaible in two (or more) different threads (it's pretty rare, and it isn't usually much more than a few varaible).
Often I will give a four digit hexadecimal number (like 0103, 02a8, 00ec, 032b, etc...) they're opcodes, to have a description write the four digit number on a new line in Sanny Builder and press F1.
Most examples are given in a CODE tag like this :
So you can copy and past it in Sanny, I recommand you to do so often, it will help you understanding. And you won't have to write the opcode number and press F1 everytime.
1. Using Sanny
This part is most repeat parts of Sanny's Help but sometimes explained differently. But you can still report to the Hotkeys page for more details.
- F1 : the magic hotkey !!!!! write an opcode like 004F and press F1 and ho magic appears :
|004F: create_thread @ODDVEH|
or write thread and press it and press it again, Sanny will suggest you all those different lines :
004F: create_thread @ODDVEH
00D7: create_thread_with_wasted_busted_check @NONAME_2
03A4: name_thread 'MAIN'
0459: end_thread_named 'INT'
004F: create_thread @ODDVEH
F1 will be the key you'll use a lot, just think about what you want (car, actor, checkpoint, markers, weapon, money, paintjob, etc...) write it and press F1. It won't do what you want everytime but it will get you going.
F1 is kind of google for Sanny !!!!!!!
But notice that it only works for one and only one word.
Remember (or learn if you didn't know) that F1 gets it's suggestions from opcodes.txt so make sure you did what it's in part II introduction.
- Ctrl + Shift + <0..9> : make bookmark, at the line you are like :
They should be save when you save the file.
- Ctrl + <0..9> : go to bookmark number <0..9>, put you at the line of the bookmark (if it exist)
- Ctrl + Num2/Num8 : when you place your cusor (the blinky |) on a jump (or gosub or jf -jump_if_false-)and press it the editor will bring you the the label. Look animation to see that I've place on @PSAVE1_1498 and it bring me to the label it self :PSAVE1_1498.
- F3 : find next
- Ctrl + F3 : find previous
- Ctrl + Alt holded : Rectangular selection :
- Ctrl + Alt + 1 : Coords Manager (game must be running)
- Ctrl + Alt + C : Insert player coordinates where you cursor is
- Ctrl + Alt + E : Insert z angle value where you cursor is
- Ctrl + T : delete word, remember things like end_thread will be considered as one word.
- Ctrl + Y : delete line
- Ctrl + Shift + Y : clear line, leave the line but delete what's written in it.
- Ctrl + Scroll Up/Down : page up / down
- Ctrl + Shift + U/L : make word UPPERCASE / lowercase.
- Ctrl + Q : comment out the line your cursor is (adds // at begining of the line), so the line will be ignored when compiling.
- Ctrl + G : go to line
- Ctrl + R : replace
- Ctrl + C : copy
- Ctrl + V : paste
- F7 : compile and copy to GTA SA folder main.scm and script.img
Editor completion :
Sanny can complete some thing for you like global variables, labels, model IDs, to use it just write first character ($, @, or #) and get what you need. Look the animation I think it explains well :
Those are the most used exemples, but you might find many use for this tool.
Notice that with models, the nudel number is shown, so it's a pretty easy way to find what number a model is.
Coords Manager :
Very usefull tool here which get the 3D position of the player. Of course the game muste be running....
The 3 dimension position is the value of each axis (x, y, z). The San Andreas map goes from -3000.0 to 3000.0 on x and y axis. The altitude (z) max of planes is about 800.0 units. Axis x is oriented west east, the x value increases when going east. Axis y is oriented south north, the y value increases when going north. Center of the map is located at 0.0 0.0 0.0.
Well it looks like that :
This screenshot is from old Sanny Builder new coord manager is slightly different.
Copy will copy into clipboard the 3d pos like 747.756 -1809.0986 13.0234
Read will refresh the position of the player ingame.
Set will put player at the position you've written in the three dimensions.
In new Sanny Builder you get the Z angle value. This is the value of the angle around z axis which means what direction the player (CJ) is looking at. 0.0 is north, 180.0 is south, 90.0 is east, 270.0 is west.
2. Adding mission mods :
This isn't really coding but it is usefull for everyone to look/test/use/imitate parts of other's mods.
First thing to know when adding mods : FOLLOW INSTRUCTIONS !!!!!!!!!!!!!!!!!!!! Every mods is different so when adding a mod first follow the author instructions to add it, they're the best instructions. But sometimes there isn't much instruction.
Then, most of mods are main part (look part I, 1.Main.scm architecture) mods. So they're activated (create_thread) and executed in the main part. You probably want to add mods to original main.scm (or modded main.scm), then you'll will use 004F (create_thread) here :
|004F: create_thread @ODDVEH |
004F: create_thread @R3
004F: create_thread @GYM
004F: create_thread @SHOOT
004F: create_thread @BLOODR
004F: create_thread @HOTR
004F: create_thread @KICKS
004F: create_thread @PSAVE1
004F: create_thread @FLOW
004F: create_thread @HELP
004F: create_thread @COLLS
004F: create_thread @CRANES
004F: create_thread @BUY_PRO
004F: create_thread @VALET_L
004F: create_thread @ADPLANE
Between any of those lines you'll add :
|004F: create_thread @modlabel|
Then you've got the mod itself, you have to add it anywhere in main part. BUT it isn't really anywhere, it's more like anywhere after it's been created/activated, and not inside another thread. to simplify just put it at the very end of main part, so before :
// Originally: Initial 1
Then compile and copy to San Andreas data\script (F7), launch the game, start a new game and.....
Hang on, if it really did work, you're like really very very lucky (and you did a good job apparently) !!!! Most of time first try simply doesn't work. So watch what you've done, look how the author of the mod did it, watch global variables (if only numbers you should change it to a custom name), the try again, and if you really can't get it working, ask the author how he did (do that after several tries and checks, don't disturb the author for a mistake you've done).
3. Weapon pickups and parked cars :
For me this part isn't real coding neither but it's usefull and asked very very very often, and it's a good opportunity to explain how it works.
Pickups and parked car are spaecial opcode because it telle the engine to create such car or such weapon if player is close enough to the point.
Well I'll take exemple to the cars/vehicles that you always find in one place (the skimmer near the dam, the AT400 at Vegas airport, the cropduster in the desert, these are the only one I can think of right now) everytime (actually not everytime) you come back it's here. Same for weapons (the heatseek rockets at the abandonned village, the gun behind Sweet's house...), life (red heart in gang wars), and armor.
Parked cars :
|014B: $mycarx00 = init_parked_car_generator #CHEETAH 15 15 1 alarm 0 door_lock 0 0 0 at -1253.1 -348.0 13.9 angle 0.0 |
014C: set_parked_car_generator $mycarx00 cars_to_generate_to 101
- This will create a cheetah (#CHEETAH)
- at the 3d coordinate -1253.1 -348.0 13.9
- the car will be headed the z_angle 219.0 (z_angle is the angle around the axis z, 0.0 and 360.0 is north, 180.0 is south, 90.0 is east, 270.0 is west), so this car is
directed to south-west
- with color one number 15 (you can notice sometimes -1 which mean any)
- with color two number 15 (you can notice sometimes -1 which mean any)
- Car belongs to the player (the cops don't think you've stole it) becasue next parameters is set to 1. If would set on 0 cops will give you a wanted level when you enter it
- Without alarm, because it's 0. It's actaully percentage of chances of getting alarm. So if you want the alarm to go off everytime set it to 100, if you want it once out of two time then 50 etc....
- Doors won't be lock. As you can read door_lock is set to 0. If 1 doors will be lock. The two others parameters are unknown.
- This car generation (not the car itself) is set as handle $mycarx00
And you should be wondering how do I know all that (beside simply reading and thinking) ???????
Well go check http://sa-db.webtools4you.net/, clic go without writting anything, and with your internet browser (if you don't know what it is then it's Internet Explorer) go Edition\Find in the page, and search for 014B.
You'll then get 014B description
The line after 014C just activates or unactivate the parked car generator for this car generation handle : 101 makes it spawn and 0 doesn't. It is needed don't forget one for each car generation, but they don't have to be together you can separate them.
There is other types of parked cars they're very close to this one and they ain't much usefull.
Weapon pickups :
There is two types of weapons pickups, one for weapons which doesn't need ammunitions (like dildos, katana, golf club, shovel, parachute....), and is actualy just a normal pickup.
Those both pickup opcodes like with parked cars opcode don't need to request and load the model before using.
- Melee (and gift) weapons
CODE 0213: $myweaps00 = create_pickup #CHNSAW type 15 at -2083.0 298.0 42.0
0213: $myweaps01 = create_pickup #BAT type 15 at -2306.0 93.0 35.0
0213: $myweaps02 = create_pickup #SHOVEL type 15 at -2796.4155 123.686 6.844
0213: $myweaps03 = create_pickup #POOLCUE type 15 at -2135.0 197.0 35.0
0213: $myweaps04 = create_pickup #KATANA type 15 at -2208.0 696.0 50.0
0213: $myweaps05 = create_pickup #BRASSKNUCKLE type 15 at -2206.0 961.0 80.0
You can use this opcode for other pickups like the keycard (what you get with the croupier girl- model : #KEYCARD), armour (model : #BODYARMOUR), life (model : #HEALTH), bribe (model : #BRIBE), save disks (only the pickup not the saving routine ! - model : #PICKUPSAVE), briefcase (model : #BRIEFCASE) etc...
All the melee weapons (including parachute -#PARA_PACK- but not the goggles), and health, armour, bribes, are hardcoded that mean you don't have to check if the player picks up the so-called pickup, just go to the pickup and it automaticly gives the weapon/bribe/armour/health etc....
For keycard, save disk, briefcase, but as well as all define objects models (if there ain't too big of course) because they can be use as a pickup, you have to check if the pickup has been pickup or not. You don't have to destroy it once it's been picked, because as soon as the player is on it it will automaticly disappear.
For this you must use something like this :
CODE 00D6: if
0214: pickup $pickupvar picked_up
004D: jump_if_false @
- Firearms (and all others)
But for weapons which have ammunition, with an exeption for the night and infrared goggles, (models : #NVGOGGLES, and #IRGOGGLES) you'll need to use the pickups which give ammunition with the weapon (doesn't it sound obvious ?) :
CODE 032B: $myweaps06 = create_weapon_pickup #NVGOGGLES 15 ammo 1 at 299.5 -31.7 1001.0
032B: $myweaps07 = create_weapon_pickup #IRGOGGLES 15 ammo 1 at 299.6 -41.3 1001.0
032B: $myweaps08 = create_weapon_pickup #M4 15 ammo 60 at 2021.879 1001.467 10.3203
032B: $myweaps09 = create_weapon_pickup #MP5LNG 15 ammo 120 at 2025.286 1001.496 10.3203
032B: $myweaps10 = create_weapon_pickup #SHOTGSPA 15 ammo 120 at 2021.327 1013.349 10.3203
032B: $myweaps11 = create_weapon_pickup #SATCHEL 15 ammo 20 at 2023.775 1013.527 10.5203
032B: $myweaps12 = create_weapon_pickup #SNIPER 15 ammo 60 at -2035.7729 139.4337 28.3359
032B: $myweaps13 = create_weapon_pickup #MICRO_UZI 15 ammo 120 at -2038.4301 139.6281 28.3359
032B: $myweaps14 = create_weapon_pickup #CHROMEGUN 15 ammo 120 at -2038.6639 137.4694 28.3359
032B: $myweaps15 = create_weapon_pickup #GRENADE 15 ammo 20 at -2035.474 137.2511 28.3359
032B: $myweaps16 = create_weapon_pickup #AK47 15 ammo 120 at 2499.3899 -1707.463 1014.25
032B: $myweaps17 = create_weapon_pickup #TEC9 15 ammo 120 at 2499.5139 -1709.64 1014.25
032B: $myweaps18 = create_weapon_pickup #SAWNOFF 15 ammo 60 at 2493.491 -1708.2371 1014.932
032B: $myweaps19 = create_weapon_pickup #MOLOTOV 15 ammo 20 at 2493.553 -1706.863 1015.132
032B: $myweaps22 = create_weapon_pickup #COLT45 15 ammo 100 at -365.4774 -1422.401 25.5
032B: $myweaps23 = create_weapon_pickup #FLAME 15 ammo 200 at -366.066 -1418.683 25.5
Well for those ones, the number after ammo is the number of ammunition you'll have when you pick the weapon up.
type 1 disables the pickup (you can't pick it up)
type 3 make the pickup pickable only one time
type 15 make the pickup re-grows up everytime after you picked it up (probably what you want)
the three floats are the coordinates of the pickup like those :-366.066 -1418.683 25.5
$myweapsxx is the handle of the pickup, the variable that contains it.
and #GRENADE is the model.
One last thing is that you can find a weapon list in the file [SA] Weapon numbers.txtin the help folder of Sanny Builder folder.
There is some weapons like the jetpack, or the parachute where you can use either 0213 or 032B with ammo 1 it has the same result.
You can destroy pickups before it's been pickup, with 0215 :
|0215: destroy_pickup $myweaps01|
4. Threads :
There isn't much to say more than what's been told in Part I : 4. Threads and labels.
Just that you create them with 004F like that :
|004F: create_thread @name_of_your_thread|
You name it with 03A4 :
|03A4: name_thread 'NAME'|
No more than 7 letter.
You can end it with 004E from the thread itself :
Or from anywhere else with 0459 :
|0459: end_thread_named 'NAME'|
Sometime you can find weird 004F like :
Don't worry it's just how you can set local variable for the thread you create. Like on the example $ACTOR_RYDER will be 0@, 0 (first one) will be 1@, 0 (second one) will be 2@, 2 will be 3@, 1 will be 4@ in the thread :AUDIOL.
Like Sanny tells you you can set up to 32 locals there for the thread you create from 0@ to 31@. It can be very usefull but if you don't really understend it doesn't really matter, it's just so you know about it.
Edited by tomworld10, 31 May 2008 - 05:10 PM.