Log in to reply
 

[.NET] [C#] [SHVDN] Modding Basics and How to Start Modding In C#! [PART 1]



  • Hello guys, it's been a long time since I've been here, and since then, looking back at my older tutorials they just don't feel really good and everything feels really un-organized. So this time, I'm going to guide you, from the very basics and guide you up to the very top.

    One thing, however, is that I don't know where to lead with this series. Do you want this to be more of a Lets Make a Mod or like fundamentals of modding? If you want it to be a former, tell me what mod you'd like to see be made(or re-made).

    REQUIREMENTS
    Intermediate knowledge of C#
    ScriptHookVDotNet(SHVDN)
    ScriptHookV(SHV)
    Visual Studio Community

    Setting Up
    First of all, after downloading the above files, drag everything from SHVDN and SHV rars to your game folder. THATS IT. Also, make a scripts folder if not already made in you game directory. After doing that, this is how your game directory should look like:
    alt text
    I do have extra files, that's because I have RAGE Plugin Hook, but you don't need that.
    After installing the hooks, you should make a folder where all your coding stuff goes. I'll make a folder at my desktop named GTA 5 Coding:
    alt text
    After that, drag your SDK folder (from the SHVDN rar) into that folder. Keep in mind this is all for organisation and if you don't want to do it, certainly don't.
    alt text
    After that, open up Visual Studio Community that you installed earlier and this is the screen you will be greeted with:
    alt text
    Click File->New->Project and then this screen will show up:
    alt text
    Make sure Class Library is selected and in the Name write down the name of your mod, in our case, I'll just name it "First Script" (without the quotation marks. ALSO the location has to be that GTA 5 Coding folder we created earlier so make sure it is like mine. After you hit OK, you will be greeted with the C# script:
    alt text
    First of all, we need to setup the "references" to our SDK which we dropped into our GTA 5 Coding folder, so in the right of the window there is a "Solution Explorer". In there, there is a References key. Right click it and click Add Reference:
    alt text
    Click on Browse and browse to your SDK folder, in which you will find this:
    alt text
    Click on Add and make sure it is ticked after it appears in the Reference Manager. However, we still need to add one more Reference for handling Keypresses. It is inside the Assemblies section, to the left on the Reference Manager window.
    alt text
    In here, find System.Windows.Forms, check it and click OK:
    alt text
    After that, we need to add on to our "using" namespaces so that we can "use" all the functions inside of the .NET Hook so that we can manipulate the game world. We have three main using namespaces to add:
    alt text
    using GTA - This using reference is basically for everything revolving the GTA game world, like creating vehicles, handling weather, everything. However, we still need to add two more references:
    using GTA.Native - This using reference allows us to call native functions DIRECTLY to the main C++ hook. You don't need to understand what that all means yet, we'll talk about that later.
    using GTA.Math - This using reference allows us to use GTA or 3D math, as far as we are concerned. We will learn about these later.

    With these three out of the way, we also need to add the System.Windows.Forms reference.
    alt text
    This is needed only for the KeyEventArgs class which is used for keypress handling and for you C# dudes, I know, crosire(the .net hook dev) should've added a KeyEventArgs class in his own hook so we wouldn't have to add this reference but oh well :P

    Now, we have to make the hook know that this class is a Script, and not any other class that just randomly happened to end up in our project :P and to do that we need to inherit from the main Script class. If you don't know what that means, I suggest you read the REQUIREMENTS note at the top and then continue :)
    alt text
    The random and boring "Class1" class seems too uninformational for us so lets change that to something like "Main". To do that, go over to your Solution Explorer and right click Class1.cs and rename it to Main.cs:
    alt text
    Now, the final thing we need to do for setting up, is to make the constructor and add the Tick and Keydown event handler! (Again, if you don't know what an eventhandler is, read the requirements note)
    alt text
    This code hooks the Tick and KeyDown events from the Script class we inherited from to our two event handlers, OnTick and OnKeyDown.
    We are done setting up! We can now continue to the actual fun stuff!

    Coding A Simple Script
    Let's code a script, that, if we press J, we set our Wanted Level to 0? It's quite easy to do, but first, we need to detect a keypress. We do this in our OnKeyDown method. The KeyEventArgs class gives us all the info we need to know what key was pressed.
    alt text
    Now we need a way to manipulate the Player, we can easily do using Game.Player. Game.Player has a property WantedLevel that we can edit, and set to anything we want(setting it to more than 5 just doesn't work so don't try it :P)
    alt text
    Pretty straight-forward code, nothing a C# noob couldn't understand.
    This checks if the key we have pressed was J and if it was, set our Wanted Level to 0. We can also let the player know that the script works and there aren't any errors, for two reasons:

    1. It looks good :P
    2. For debugging, so we could know why it didn't work. When modding or scripting, keep this habbit in mind since it is very useful when code doesn't work.

    How do we do this, you ask? Well, the .NET hook gives us an ENTIRE class full of goodies we can mess around lol which is the UI class. Inside it we can mess with anything UI related, but we are going to find one specific method:
    ShowSubtitle
    This method, as it says, shows a subtitle for a duration we can set(it is in milliseconds so be careful) and the text we want it to display, like this:
    alt text
    The first parameter is the text (it is a string) and the second parameter is the time we want it to display, which I have set to 3 seconds or 3000 milliseconds.
    This script now functions, but how do we put it in the game? Look down!

    Compiling and running the script
    To build the script, hover over Build and click Build FirstScript:
    alt text
    If your script didn't have any errors, it would build successfully and show you the path to where it was compiled. Since we put the project in our GTA 5 Coding folder, navigate to this directory:

    GTA 5 Coding\FirstScript\FirstScript\bin\Debug

    Over here, you would find the two files which are important:
    FirstScript.dll and FirstScript.pdb
    The dll is the actual compiled script and the pdb contains info about the script. This is good for debugging so if the script crashes we can know exactly at which line it crashed at. Copy both these files to your scripts folder in you GTA 5 directory

    IMPORTANT: DO NOT COPY THE SCRIPTHOOKVDOTNET.DLL WHICH WAS COMPILED

    After this, run your game and press J. Did the script work for you? It did for me!

    Keep experimenting with what you just learnt today. Explore. In the next tutorial we'll cover different things like 3D space and model spawning. Until then, bye.



  • @GTAVModder4Life very happy that you are back and making this helpful tutorials for us.

    2 things i want to know at the moment to complete and update scripts from me.

    1. how must the code look if i want 2 functions on one button/key like press=open driver door, hold is open passenger door. the functions are just examples. i want to know how to do the hold function without activating the press function.

    second is something about game.player.ped. if you look at my "itwasntme" script on the mod page you see i do a character switch from franklin to a cop but i want to do a switch between my actual character and the cop and then back to this character but i dont know how to save the character. also the weapons he has before the switch
    if you can help me with that

    if you think this post fits not to your topic and i should in future write these questions better as chat message, tell me and i delete it



  • @TobsiCred I have created a similar post on GTA Forums for holding keys, and this is what I came up with:

        bool isHoldKeyPressed;
        int secondsForStuff = 4000;
        int secsPressed;
    
        void OnTick(object sender, EventArgs e)
        {
            if(isHoldKeyPressed)
            {
                secsPressed += 1000;
            }
    
            if(secsPressed == secondsForStuff)
            {
                ExplodeCurrentVehicle();
                secsPressed = 0;
                isHoldKeyPressed = false;
            }
        }
    
        void ExplodeCurrentVehicle()
        {
            Vehicle veh;
    
            if (Game.Player.Character.IsInVehicle())
                veh = Game.Player.Character.CurrentVehicle;
            else
                return;
    
            veh.Explode();
        }
    
        void OnKeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.J)
            {
                isHoldKeyPressed = true;
            }
            else
            {
                isHoldKeyPressed = false;
            }
        }
    

    Basically change the secondsForStuff variable to the amount of seconds you should hold. In the OnKeyDown event you can change the Key that has to be held down. The ExplodeCurrentVehicle is just a placeholder, you can replace that code with anything you want to do when you hold the key.

    For changing the player ped, you need to use this native:
    alt text



  • This post is deleted!


  • This post is deleted!


  • @TobsiCred I forgot to mention, in your constructor put in Interval = 1000;
    at the start.



  • This post is deleted!


  • @TobsiCred post your code in a new thread, so as to not confuse my readers :) I'll look at it first thing.



  • Mine didnt rebuild properly, I'll show a screenshot of my script:
    0_1487523800217_Screenshot (25).png



  • @zZIrish_GamerZz change ; to : "public class Main : Script"



  • @TobsiCred It is recommended that you don't have the same name for both Namespace and Class, apparently it can cause reference problems.

    https://blogs.msdn.microsoft.com/ericlippert/2010/03/09/do-not-name-a-class-the-same-as-its-namespace-part-one/



  • @LeeC2202 Compiled everything into a .dll succesfully; but .dll is only 5k, and when I rename it to .asi, it doesn't appear to get loaded. What step am I missing?



  • @meimeiriver Why are you renaming to an asi? If it's a C# script, it's a dll and it goes in your scripts folder.



  • @LeeC2202 said in [.NET] [C#] [SHVDN] Modding Basics and How to Start Modding In C#! [PART 1]:

    @meimeiriver Why are you renaming to an asi? If it's a C# script, it's a dll and it goes in your scripts folder.

    It's the NoBlood script I tried compiling:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using GTA;
    using GTA.Native;
    
    namespace NoBloodV {
        public class NoBlood : Script {
            public static int busy = 0;
            public NoBlood () {
            	Interval = 100;
                Tick += onTick;
            }
    
            private void onTick (object sender, EventArgs e) {
                if (busy == 0)  {
                    busy = 1;
                    Ped playerPed = Game.Player.Character;
                    if ((playerPed.HasCollidedWithAnything) || (playerPed.IsSwimming)) {
                        playerPed.ClearBloodDamage ();
                        playerPed.ResetVisibleDamage ();
                        Function.Call (Hash.CLEAR_PED_LAST_WEAPON_DAMAGE, playerPed);
                    }
                    busy = 0;
                }
            }
        }
    }
    

    It compiles fine (VS 2017). I thought you needed to rename it to .asi, to get ScriptHookV to pick up on it. :) I put the .dll in the scripts folder now, but it doesn't seem to work. I best pull out the SubTitle thingy again. :)



  • @LeeC2202 All is well again. :) Removed the busy flag, which was preventing it from running correctly somehow. But, without it, things run just fine.



  • @LeeC2202 For completion's sake, here is the new script I'm using for car collision (see below). I think I've been using HasCollidedWithAnything wrong. Although defined for playerPed too, I really think it's meant to be used on CurrentVehicle, like:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using GTA;
    using GTA.Native;
    
    namespace NoBloodV {
        public class NoBlood : Script {
            public NoBlood () {
            	Interval = 100;
                Tick += onTick;
            }
    
            private void onTick (object sender, EventArgs e) {
                Ped playerPed = Game.Player.Character;
                if (playerPed.IsInVehicle ()) {
                    if (playerPed.CurrentVehicle.HasCollidedWithAnything) {
                        playerPed.ClearBloodDamage ();
                        playerPed.ResetVisibleDamage ();
                        Function.Call (Hash.CLEAR_PED_LAST_WEAPON_DAMAGE, playerPed);
                    }
                }
            }
        }
    }
    

    I didn't get the spurious crashes any more (although that might have just been a coincidence).



  • @AHK1221 Thanks for this tutorials serie and keep the good work going on please, it really help.

    May i suggest you to edit your posts to add links to other parts of the tutorial ? It would be helpfull in my opinion.


Log in to reply
 

Looks like your connection to GTA5-Mods.com Forums was lost, please wait while we try to reconnect.