[C#][Tutorial] Basics of creating a script PART 3
Hi guys, this is my part 3 of creating a script series!
In part 2, I showed you many features of SHVDN. We will now put them in a working script.
In our main script, this is where we left off:
We are going to add to the script. First thing we are going to do is read keys from an ini. So lets first declare a global Keys variable:
I usually make a LoadSettings() function, which loads all the settings on startup. Lets make that now:
This is a typical try-catch statement, we will add our code in the try statement:
Easy to understand, first parameter is the section, second parameter is the name of the key, third parameter is what to get should there is no key found. Lets put this LoadSettings() method in the constructor:
So now, it will load the file, and get the key we set it to in the ini. Simple, right? Lets change our if statement to take in our variable:
Easy, no? Now, we will look into native calling, and how we will put it into our script. It really is very easy, if you know how to call them. Now, I will explain something. Game.Player.Wanted level sets our wanted level using two natives, SET_PLAYER_WANTED_LEVEL and SET_PLAYER_WANTED_LEVEL_NOW. It all may sound confusing, but it really isnt. The first native, sets what wanted level we want to set it to, but it doesnt do it immediately. Thats where the second native comes in. It sets it immediately. Before we do anything, we need to know the parameters, which are:
For this native, we have three parameters. The first is the Player we want it to set the wanted level to, which is our Game.Player, the second parameter is the wanted level we want it to set to, which in our case is 0. The third and last parameter, as said in the last line, appears to be always false, so we will also keep it false. With this info, lets put it in the script!
Simple enough, right? Lets do the second native:
This has two parameters. The first is the Player, which again is our Game.Player, the second parameter is unknown. When it is unknown, you dont know how it affects the native and you have to tests. Luckily, someone has already put in that it is always false in their tests so we can use it too. Lets put it in our script:
Phew! Seems to be a bit too much for setting a wanted level, don't you think? This piece of code does the same thing Game.Player.WantedLevel does, but only manually.
Now, we have a method to load our settings from an ini, and we also have learnt how to go about using natives, and understanding their parameters. Let's do something with vehicles now. We will make a new if statement and a new Keys variable.
With that done, lets edit our LoadSettings() function to also load settings for our new key:
Awesome, lets go back to the if statement and code our functionality. One thing to note, World.CreateVehicle method returns the created vehicle so you can do stuff to it. We will be using this.
(I have already explained the vector stuff so wont do it again).
Here, we have two parameters. The first is the model, and the position. For model, we have lots of choices. If we know the hash of the vehicle, we could do something like new Model(hash)
but we dont know that. If we knew the name of the car, we could do something like this:
But, we might now know that. So we can do something like
A way to simplify this, is that just use VehicleHash, and not do the model thing. So the model is done. For the position, we already made a vector3 with the position so we will pass that in. The finished statement should look something like this:
This will create a vehicle, which is an Adder.
Awesome! Since we already stored our vehicle in ourCreatedVehicle variable, we can do whatever we want with it. We can change its color, turn on indicators, everything. But since i explained it in the last tutorial, I wont do it here.
Lets now talk about our onTick method and what it is. To put it simply, it runs every frame. If you have worked with Unity3d, it is like the void Update() function. At the moment, it doesnt have much use, but i felt like explaining it.
OutputArguments are something you want to use if you want to get an output from a parameter. The native _WORLD3D_TO_SCREEN2D returns a bool, and not the x and y value. This is the most basic code explaining OutputArguments.
x y and z are just the parameters, forget them.
you see how I used output1 and 2 to get the value? And then used the method GetResult() to get what it returned. It isnt easy, but you will get the hang of it later on.
Since we are already talking about returning from natives, sometimes, natives also return in another format.
See what I highlighted their? If it says a data type, in our case a bool, instead of void, it returns something. And to get what it returns, this is how we do it:
Simple enough, right?
One good tip to use, is to use this command:
COPY "$(TargetDir)$(TargetFileName)" "C:\Program Files(x86)\steam\steamapps\common\Grand Theft Auto V\scripts"
change the path to your path if it is different. You can go to Project->(yourprojectname) Properties->Build Events and copy it to Post-build event command line. This way, you wont have to keep copying each build.
In the next tutorial, we will see how to use the onTick event, and more classes of SHVDN.
YOU ARE AWESOME! Dude, you are so awesome i really like your tutorial's Keep going !
@GTAVModder4Life So the OutputArguments are the SHDNV equivalent to the out parameters in standard C# functions?
I have been struggling to find this answer because a few natives use *[parameter] which would be C++ pointers. Quite frequently I find SHDNV functions that just don't implement the Natives fully, so I have to fall back on calling the Natives directly but I hadn't been able to work out how to deal with the ones that wanted to output a pointer.
This might very well be my final missing link to be able to access all the natives directly, in which case... thank you.
Yes, that is exactly the case. It is says the *thing before the parameter that means you need an outputargument
@GTAVModder4Life Thank you... it can be so hard to find the simplest information sometimes.
@GTAVModder4Life Amazing tutorial, but just one quick suggestion, is it possible for you to add all the previous episodes link to this episod? This way, users will have ease connectivity with all your series with just one click. Nice work btw.
Can anyone help me with this little broblema Do World.CreateAmbientPickup ((PickupType) (-831 529 621), this.victim.Position + ((Vector3) (this.victim.ForwardVector * -0.5f)), "prop_cash_pile_01" this. rand.Next (1 0x3e9)) ;.