Post: [C#] How to make a custom gamemode [In Depth]
10-25-2014, 02:49 PM #1
(adsbygoogle = window.adsbygoogle || []).push({});

Hello Next Gen Update Users!
In this thread I would like to explain how to make a Custom Game mode in C# Language.
This tutorial is explained properly with Pictures, References and Coding right here in this thread.
I will explain everything in depth, what each thing does and provide my RCXD Racing Game mode Source Code to help.
NOTE: This tutorial is explained for TMAPI.


Requirements:

Windows PC
Microsoft Visual Studio: You must login or register to view this content.
.dll Reference: You must login or register to view this content.


Now for the tutorial:

In this game mode you will create, it will most likely need different maps to it and obviously for extra help a Location Co-ordinate dump, which I will explain later on in this thread.

Firstly, lets open up Visual Studio, make a C# Windows Form and add our reference "PS3Lib.dll"

which can be done by going to the "Project" drop box and navigating to "Add reference" and select the "PS3Lib.dll reference, it can be downloaded in the requirements spoiler.

Now lets Make our buttons and design for the tool :p

Firstly, Make a Connect and Attach Button, a Combo box and a Button which can be set with the combo box, also a text box with a button which can be set with the text box. Example:
You must login or register to view this content.
You can add Optional Labels / MessageBoxes as we go.

Now that our design is set up lets set up our coding

We need to make 2 classes, this does not include form 1.cs. Firstly make a class called RPC.cs and Functions.cs you can do this by navigating to the Project dropdown box and "Add Class...".
Once you have added these classes make sure you have deleted EVERYTHING from each of them and we will replace it with the coding below:

RPC:
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using PS3Lib;

namespace WindowsFormsApplication1
{
class RPC
{

public static PS3API PS3 = new PS3API();
//Enable By Calling Init(); , Not Enable();

private static uint function_address;

public static int Call(uint func_address, params object[] parameters)
{
int length = parameters.Length;
int index = 0;
uint num3 = 0;
uint num4 = 0;
uint num5 = 0;
uint num6 = 0;
while (index < length)
{
if (parameters[index] is int)
{
PS3.Extension.WriteInt32(0x10020000 + (num3 * 4), (int)parameters[index]);
num3++;
}
else if (parameters[index] is uint)
{
PS3.Extension.WriteUInt32(0x10020000 + (num3 * 4), (uint)parameters[index]);
num3++;
}
else
{
uint num7;
if (parameters[index] is string)
{
num7 = 0x10022000 + (num4 * 0x400);
PS3.Extension.WriteString(num7, Convert.ToString(parameters[index]));
PS3.Extension.WriteUInt32(0x10020000 + (num3 * 4), num7);
num3++;
num4++;
}
else if (parameters[index] is float)
{
PS3.Extension.WriteFloat(0x10020024 + (num5 * 4), (float)parameters[index]);
num5++;
}
else if (parameters[index] is float[])
{
float[] input = (float[])parameters[index];
num7 = 0x10021000 + (num6 * 4);
WriteSingle(num7, input);
PS3.Extension.WriteUInt32(0x10020000 + (num3 * 4), num7);
num3++;
num6 += (uint)input.Length;
}
}
index++;
}
PS3.Extension.WriteUInt32(0x1002004C, func_address);
Thread.Sleep(20);
return PS3.Extension.ReadInt32(0x10020050);
}

public static void Enable()
{
PS3.SetMemory(function_address, new byte[] { 0x4E, 0x80, 0x00, 0x20 });
Thread.Sleep(20);
byte[] memory = new byte[]
{ 0x7C, 0x08, 0x02, 0xA6, 0xF8, 0x01, 0x00, 0x80, 0x3C, 0x60, 0x10, 0x02, 0x81, 0x83, 0x00, 0x4C,
0x2C, 0x0C, 0x00, 0x00, 0x41, 0x82, 0x00, 0x64, 0x80, 0x83, 0x00, 0x04, 0x80, 0xA3, 0x00, 0x08,
0x80, 0xC3, 0x00, 0x0C, 0x80, 0xE3, 0x00, 0x10, 0x81, 0x03, 0x00, 0x14, 0x81, 0x23, 0x00, 0x18,
0x81, 0x43, 0x00, 0x1C, 0x81, 0x63, 0x00, 0x20, 0xC0, 0x23, 0x00, 0x24, 0xc0, 0x43, 0x00, 0x28,
0xC0, 0x63, 0x00, 0x2C, 0xC0, 0x83, 0x00, 0x30, 0xC0, 0xA3, 0x00, 0x34, 0xc0, 0xC3, 0x00, 0x38,
0xC0, 0xE3, 0x00, 0x3C, 0xC1, 0x03, 0x00, 0x40, 0xC1, 0x23, 0x00, 0x48, 0x80, 0x63, 0x00, 0x00,
0x7D, 0x89, 0x03, 0xA6, 0x4E, 0x80, 0x04, 0x21, 0x3C, 0x80, 0x10, 0x02, 0x38, 0xA0, 0x00, 0x00,
0x90, 0xA4, 0x00, 0x4C, 0x90, 0x64, 0x00, 0x50, 0xE8, 0x01, 0x00, 0x80, 0x7C, 0x08, 0x03, 0xA6,
0x38, 0x21, 0x00, 0x70, 0x4E, 0x80, 0x00, 0x20 };
PS3.SetMemory(function_address + 4, memory);
PS3.SetMemory(0x10020000, new byte[0x2854]);
PS3.SetMemory(function_address, new byte[] { 0xF8, 0x21, 0xFF, 0x91 });
}

public static int Init()
{
function_address = 0x7AA1E0;
Enable();
return 0;
}

public static void WriteSingle(UInt32 address, float input)
{
byte[] array = new byte[4];
BitConverter.GetBytes(input).CopyTo(array, 0);
Array.Reverse(array, 0, 4);
PS3.SetMemory(address, array);
}

public static void WriteSingle(UInt32 address, float[] input)
{
int length = input.Length;
byte[] array = new byte[length * 4];
for (int i = 0; i < length; i++)
{
ReverseBytes(BitConverter.GetBytes(input[i])).CopyTo(array, (int)(i * 4));
}
PS3.SetMemory(address, array);
}

public static byte[] ReverseBytes(byte[] toReverse)
{
Array.Reverse(toReverse);
return toReverse;
}
}
}

This will set up RPC Functions for us.

In the Functions class Insert this into it:
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
class Functions
{
public static UInt32 spawnEntity(String ModelName, Single[] Origin, Single[] Angles)
{
UInt32 Entity = (UInt32)RPC.Call(0x278C60);//G_Spawn
RPC.WriteSingle(Entity + 0x134, Origin);//Sets Entity Origin
RPC.WriteSingle((Entity + 0x140), Angles);//Sets Entity Angles
RPC.Call(0x277644, Entity, ModelName);//G_SetModel
RPC.Call(0x2670E8, Entity);//SP_Script_model
return Entity;//Returns Entity Index
}
}
}

This sets up our functions offsets and entities.

Now lets set up our main tool functions, go to Form1.cs's coding.

In here firstly insert the code below
Above "Public Form 1"
As shown here:
You must login or register to view this content.
    
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using PS3Lib;//PS3 Reference for connection etc...

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
PS3API PS3 = new PS3API(SelectAPI.TargetManager); //Selection of TMAPPI

float CarePackageWidth = 26f; //CP Width
float CarePackageLength = 65f;//CP Length
float CarePackageHeight = 34f;//CP Height

string greencarepackage = "t6_wpn_supply_drop_ally";//green carepackage (friendly cp)
string redcarepackage = "t6_wpn_supply_drop_axis";//red carepackage (enemy cp)
string rxcd = "rc_car_medium_mp"; //RCXD Race Car in this case


This sets up our gamemode properly, but adding carepackage height, length and width.
You can also add your own models as shown I have done "string greencarepackage = "model";" if you wanted to add your own you could just do this as an example: string helicopter = "helicopter model";" except you would use the correct coding for the model of course.

Connect, Attach, Start Gamemode:

Go to our Connect and attach Button and Double click the button, it should direct you to the coding of the button in which you can add this coding to:
    
{
if (PS3.ConnectTarget())
{
if (PS3.AttachProcess())
{
RPC.Init();
MessageBox.Show("Status: Connected and Attached");
}
else
{
MessageBox.Show("Status: Cannot Attach");
}
}
else
{
MessageBox.Show("Status: Cannot Connect");
}
}

This allows us to connect and attach if there are any errors a message box pops up and explains what error you are receiving.

Now lets get to our actual gamemode coding, first of all lets go to our combo box we made earlier and add the maps we want in, you can do this by going to the design, clicking on the combo box, click on the arrow pointing right and press "Edit items" then edit what maps you want in there as shown mine is nuketown:
You must login or register to view this content.

Because mine is nuketown i would go to our "Start game mode" button and add this coding:
    
if (comboBox1.Text == "Nuketown 2025")//Calls the map
{

this means that the coding in this function will be ONLY for the map nuketown, if you want to change the map, then change "Nuketown 2025" to another map which was in the combo box.

Now that we have done that lets get to our spawn entity function (Main function)
    
//Spawn race boundaries/track (carepackages)
float[] xyz = { -90.4551f, 318.369f, -60.0048f }; //co-ordinates
float[] angles = { 0f, 0f, 0f };//angle in degrees
Functions.spawnEntity(greencarepackage, xyz, angles);//call the model (care package)
System.Threading.Thread.Sleep(20); //1000 = 1 second, this waits 20 milli seconds then runs next carepackage

As seen here I have the angles, and co-ordinates of my care package and also a sleep timer.
The sleep timer basically makes it so that they spawn one after another so that they don't freeze you.

Now lets explain each line:
    
float[] xyz = { -90.4551f, 318.369f, -60.0048f }; //co-ordinates

this is where we enter our co-ordinates of our carepackage, I will explain how to get co-ordinates at the end of this thread. the co-ordinates also must have f after each number and a "," then a space as shown in the coding.

    
float[] angles = { 0f, 0f, 0f };//angle in degrees

This is our angles, it is Roll, Pitch and Yaw. this is something you may have to search up but I have a picture explaining it here:
You must login or register to view this content.
Its the same deal as the co-ordinates you must have a "f" and a "," then space it after each number as shown in the coding.

    
Functions.spawnEntity(greencarepackage, xyz, angles);//call the model (care package)
System.Threading.Thread.Sleep(20); //1000 = 1 second, this waits 20 milli seconds then runs next carepackage

These two lines self explain them selves, the function.spawnEntity line basically calls the function, and the bottom line is a sleep timer which times how long it takes for each entity to spawn after one another.

This is everything you need to know to make your gamemode, excpet one thing, getting our co-ordinates. which I will explain.

How to gain Co-ordinates:

Earlier we made a textbox and button, this gets our co-ordinates. I will now explain how, we start a game and go any where on the map in which you want the co-ordinates of, you then Connect the tool and press the button which dumps the location, this will dump the location in a .txt file you will make which will be explained.

Lets add our coding behind the "Dump Location" Buttton:
    
System.IO.File.AppendAllText(System.IO.Directory.GetCurrentDirectory() + @"\DevDumps\TeleportLocations.txt", Environment.NewLine + textBox1.Text + " X: " + Convert.ToString(PS3.Extension.ReadFloat(0x1780F50)) + " Y: " + Convert.ToString(PS3.Extension.ReadFloat(0x1780F54)) + " Z: " + Convert.ToString(PS3.Extension.ReadFloat(0x1780F5Cool Man (aka Tustin)));

This coding goes behind our Dump location button. once you press Dump location the location co-ordinates will go to your .txt file and you will see the X,Y,Z Inside.
NOTE: Make sure in your tool there is a folder called "DevDumps" and in the folder a .txt file called "TeleportLocations" this is where your dump location text will be directed into.

You have now made a Location Dump Smile


Enjoy Everyone! I hope this helped! If you guys still need help here is my RCXD Racing Gamemode Source:

You must login or register to view this content.
Last edited by ScaRzModZ ; 10-25-2014 at 05:15 PM.

The following 11 users say thank you to ScaRzModZ for this useful post:

One, BISOON, FusionIsDaName, HaX-Stylin, Jakeboii, ksa_7ooo7, Quinster08, RM|T Lerks, Sunnis, XxBlud23xX, zackdavies
10-25-2014, 02:54 PM #2
msg me on skype bish

The following user thanked FusionIsDaName for this useful post:

ScaRzModZ
10-25-2014, 03:21 PM #3
-removed-
10-25-2014, 03:22 PM #4
Originally posted by Quinster08 View Post
Looks nice and helpfull, im interessted tho. I never created a tool before, i hope your intressted in helping me out with beginner stuff. If you are add me on skype il msg it to u.


This should help even the worst of the worst lmao
10-25-2014, 03:49 PM #5
Originally posted by ScaRzModZ View Post
This should help even the worst of the worst lmao


LOL i am a lazy guy, i never read threads full, i just read them with my nose lmao. I miss understood your thread xD!
10-25-2014, 05:15 PM #6
Originally posted by Quinster08 View Post
LOL i am a lazy guy, i never read threads full, i just read them with my nose lmao. I miss understood your thread xD!


the tutorial is up.

The following user thanked ScaRzModZ for this useful post:

Quinster08
10-25-2014, 05:39 PM #7
Noice job man.

The following user thanked John for this useful post:

ScaRzModZ
10-25-2014, 05:47 PM #8
Originally posted by FeverDEX View Post
Noice job man.


thanks man
10-25-2014, 05:53 PM #9
Smooth
< ^ > < ^ >
Nice tutorial, now do it in a big boy language Winky Winky c++

The following 2 users say thank you to Smooth for this useful post:

Connerg123, ScaRzModZ
10-25-2014, 05:54 PM #10
Originally posted by Smooth View Post
Nice tutorial, now do it in a big boy language Winky Winky c++


hahaha, nah man. the only c++ work for me is GSC, in which im going to work on hide and seek Winky Winky

Copyright © 2024, NextGenUpdate.
All Rights Reserved.

Gray NextGenUpdate Logo