Getting Started with Development

From GTA Network Wiki
Jump to: navigation, search

Requirements

  • RageMP Server With Bridge (Coming Soon)
  • Basic C# programming knowledge

Introduction

This page will be going over how to set up a server and write your first resource. A resource is a custom script which can be run on the server or the client.

Starting the server

In your RageMP server folder, you will find the main executable used to start the server, server.exe, run this exe once to create a default configuration file, a conf.json file used to configure your server settings. Open conf.json with your choice of text editor, or notepad.


In order to use the C# bridge, we will need to create a settings.xml file in the bridge folder, which for this tutorial it will look like this:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <resource src="mines" />
</config>

Creating a new resource

Every resource goes into its own folder inside the `bridge/resources` folder. Let's make our own resource!

1. Create a new folder called 'mines'.

2. Create a new text file called 'meta.xml' (Make sure you don't have file extensions hidden!) and fill it with the following:

<meta>
    <info name="Mines" description="Test resource to play around with mines" />

    <script src="mines.cs" type="server" lang="csharp" />
</meta>

On the second line, we declare an `info` tag, this will contain basic information about our resource such as name, description, author, etc. On the fourth line, we add our script file and this is where the magic will happen. The `type` is `server` since it will be running on the server, not the client, and `lang` is C#.

Main article: Meta.xml

3. Create a new text file called 'mines.cs' and fill it with the following:

using System;
using GTANetworkAPI;

public class MinesTest : Script
{
    public MinesTest()
    {
        
    }
}

This is a basic template for our scripts. All scripts must inherit the `Script` class and must reference GTANetworkAPI.

Let's fill it with some useful stuff. You can interact with RageMP using the `API` object. Let's make it write something to the server console when it starts:

We add an event handler called 'myResourceStart', and then attach it to API's `OnResourceStart` event inside the constructor.

using System;
using GTANetworkAPI;

public class MinesTest : Script
{
    public MinesTest()
    {
        API.OnResourceStart += myResourceStart;
    }

    public void myResourceStart()
    {
        // This will be run once all scripts are initialized!
        API.ConsoleOutput("Starting mines!");
    }
}

If you start the resource, you'll see "Starting mines!" pop up on your server console.

Now, we want it to do something useful. We want the resource to create a mine when the user types the command "/mine". Creating commands with RageMP is very easy, and it doesn't need any input sanitation since the server does it for you! All commands use the "[Command]" attribute, and take Client as the first parameter, indicating the player that sent the command.

using System;
using GTANetworkAPI;

public class MinesTest : Script
{
    public MinesTest()
    {
        API.OnResourceStart += myResourceStart;
    }

    public void myResourceStart()
    {
        API.ConsoleOutput("Starting mines!");
    }

    [Command("mine")]
    public void PlaceMine(Client sender)
    {
        // This is our command!
    }
}

Now let's make the command do something useful.

using System;
using GTANetworkAPI;

public class MinesTest : Script
{
    public MinesTest()
    {
        API.OnResourceStart += myResourceStart;
    }

    public void myResourceStart()
    {
        API.ConsoleOutput("Starting mines!");
    }

    [Command("mine")]
    public void PlaceMine(Client sender, float MineRange = 10f)
    {
        var pos = API.GetEntityPosition(sender);
        var playerDimension = API.GetEntityDimension(sender);

        var prop = API.CreateObject(API.GetHashKey("prop_bomb_01"), pos - new Vector3(0, 0, 1f), new Vector3(), playerDimension);     
        var shape = API.CreateSphereColShape(pos, MineRange);
        shape.dimension = playerDimension;
    }
}

We can see how easily we can add arguments to our commands. The command takes a single optional parameter, the mine detonation range, which is defaulted to 10 meters. The player can input "/mine" to create a mine with a range of 10 meters, or "/mine 5" to create one with a range of 5 meters.

On the first line, we get the player's position in the world and store it inside the "pos" variable. Then we do the same to player's dimension (virtual world) and store it in the "playerDimension" variable.

On the next two lines, we create an object in the world (a bomb) on player's feet and inside the player's dimension. Next, we create a sphere collision shape, which will detect any player/vehicle/object that enters or exits the shape. We also set it so it only detects entities inside player's dimension.


Now let's make it explode when someone enters its range. As the player is already inside the collision sphere when placing the mine, first we have to arm it when the player leaves the range, so it doesn't kill him instantly.

using System;
using GTANetworkAPI;

public class MinesTest : Script
{
    public MinesTest()
    {
        API.OnResourceStart += myResourceStart;
    }

    public void myResourceStart()
    {
        API.ConsoleOutput("Starting mines!");
    }

    [Command("mine")]
    public void PlaceMine(Client sender, float MineRange = 10f)
    {
        var pos = API.GetEntityPosition(sender);
        var playerDimension = API.GetEntityDimension(sender);

        var prop = API.CreateObject(API.getHashKey("prop_bomb_01"), pos - new Vector3(0, 0, 1f), new Vector3(), playerDimension);     
        var shape = API.CreateSphereColShape(pos, MineRange);
        shape.dimension = playerDimension;
        
        bool mineArmed = false;
        
		// Triggered when a player, vehicle or object enter the mine's range
        shape.OnEntityEnterColShape += (s, ent) =>
        {
            if (!mineArmed) return;
			// Otherwise, create an explosion at mine's position, in player's dimension
            API.CreateOwnedExplosion(sender, ExplosionType.HiOctane, pos, 1f, playerDimension);
            API.DeleteEntity(prop);
            API.DeleteColShape(shape);
        };

		// Triggered when a player, vehicle or object exit the mine's range
        shape.OnEntityExitColShape += (s, ent) =>
        {
            if (ent == sender.handle && !mineArmed)
            { // The player that placed the mine left it's range, let's arm the mine!
                mineArmed = true;
                API.SendNotificationToPlayer(sender, "Mine has been ~r~armed~w~!", true);
            }
        };
    }
}

We use lambda expressions to attach to our collision shape's events inside the command method. The mine won't explode until the player has left the mine range.

Now let's try it in-game!

Connect to your server using Direct Connect and input "127.0.0.1" as the server, and type "/mine" to spawn a mine at your feet!