Create your personal GTA 5 Trainer
-
Started, by request, a tutorial on how to use LemonUI to create your own personalized menus or even a complete mini-Trainer.
-
Here is the absolute minimum as starter code. More to come if you follow the tutorial. You don't need to be a programmer to get this done, in fact I'm definitely not a programmer but my code works. If someone can improve it, they're more than welcome to contribute. Note, I'm not going to explain how to install Visual Studio or LemonUI. There are tutorials for VS on Youtube although it's not much different from installing other software. As for LemonUI, it's a no-brainer but if needed there are instructions in the download.
using GTA; using LemonUI.Menus; using System; using System.Windows.Forms; namespace LemonUI.Menu1 { public class Basics : Script { private static readonly ObjectPool pool = new ObjectPool(); private static readonly NativeMenu menu = new NativeMenu("Name of your Menu", " ", " "); public Basics() { pool.Add(menu); Tick += Basics_Tick; KeyDown += Basics_KeyDown; } private void Basics_Tick(object sender, EventArgs e) { pool.Process(); } private void Basics_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.F3) { menu.Visible = true; } } } }
-
@JohnFromGWN Thank you !
-
@gus-solo You're very welcome.
Here is the link for Part 3
https://pastebin.com/gXXttp05actually here is part 3 of the tutorial too.
more to come.
-
I'm working on the following:
https://github.com/KimonoBoy/SHVDN-Tutorial
with the associated Wiki
But it's not at all about to be finished. It's a work in progress, and it's a huge mess.
-
@KimonoBoy Glad to see your project is initiated and progressing.
If you need help, or snippets of tested and working code, let me know.
I'm not a programmer but I've now written thousands of LOCs.
-
Thanks man! I just started writing the tutorial, been really busy. But I will let you know, once the mod and the Wiki is in a more complete state
Then we can improve it!
Edit: My biggest issue right now is Git ^^
-
@KimonoBoy Thank you for the Wiki, easy and clear ,very useful for me,
-
@KimonoBoy
Started to look at your wiki and wow, I wish I had had something like this when I started. Fantastic.
A few minor suggestions, not corrections. but rather for completeness.-
Under Reloading Scripts HotKey, you might mention that reloading a script can also be done from the console (F4). Perhaps at one point, although it might be scope creep, is have a dedicated section to the console?
-
Building directly to your scripts folder. One minor suggestion. There is another option which is to use post-build events, which over-rides the build event. It might be a little trickier because you need
COPY "$(TargetPath)"
, but might be worth mentioning for completeness.
Once more, great job. You need to get the word out there. So many people are having their games crash because of outdated or poorly written scripts. Learning how to script is incredibly empowering and the possibilities for GTA5 are limitless.
The barrier to entry for scripting has always been sparse and garbage documentation and you've addressed this. I also prefer your format, well organized and hyperlinked, to wasting time with YouTube videos.
-
-
@JohnFromGWN said in Create your personal GTA 5 Trainer:
@KimonoBoy
Started to look at your wiki and wow, I wish I had had something like this when I started. Fantastic.
A few minor suggestions, not corrections. but rather for completeness.-
Under Reloading Scripts HotKey, you might mention that reloading a script can also be done from the console (F4). Perhaps at one point, although it might be scope creep, is have a dedicated section to the console?
-
Building directly to your scripts folder. One minor suggestion. There is another option which is to use post-build events, which over-rides the build event. It might be a little trickier because you need
COPY "$(TargetPath)"
, but might be worth mentioning for completeness.
Once more, great job. You need to get the word out there. So many people are having their games crash because of outdated or poorly written scripts. Learning how to script is incredibly empowering and the possibilities for GTA5 are limitless.
The barrier to entry for scripting has always been sparse and garbage documentation and you've addressed this. I also prefer your format, well organized and hyperlinked, to wasting time with YouTube videos.
Thanks for your feedback.
Suggestion
- Agreed, should be mentioned. Some might actually prefer it.
- Yes.
COPY "$(TargetPath)"
- I use it for my own projects, this section should and will be revisited at a later time! But I think I'll add it as a Tips & Tricks section in the end, hoping not to throw people off with too much prepping before programming, that's also the reason why we just suddenly create a script in the "Your First Script" section, to maybe encourage people to continue.
If you find more improvements or suggestions, please share them 👍 I want the wiki and the mod to be in a state that is usable while not yet complete, before creating a topic! Once again, ty for your feedback
-
-
@gus-solo said in Create your personal GTA 5 Trainer:
@KimonoBoy Thank you for the Wiki, easy and clear ,very useful for me,
You're welcome, revisit the topic at a later time, and hopefully it'll help you create the mod you wish
-
@KimonoBoy
I have a suggestion regarding organizing the code. It quickly becomes close to unmanageable if you don't organize it.Early on I thankfully found the partial classes/methods. This allows me to keep my LemonUI menu solutions as clean as possible. I have 2 LemonUI specific classes and then anywhere from 1 to 20 other classes in each solution. I do have separate menu solutions for peds, vehicles, and teleports etc, but they are all linked in each menu.
- A LemonUI section that has the menu items and other declarations but no code.
- A second LemonUI section dedicated to adding the menu items to the pool and what code is activated, value changed etc.
- All other non-LemonUI functions and codes in their own sheets, own class items.
For point 3, as an example, I also keep spawning entities separate from other functions such as animations or tasks.
Since I have close to 1000 vehicles installed and coded, I group them by Country or by Brand and by Sub Brand - which is consistent with how my dlc folders and subfolders are organized on the hard disk. So I have a class Ferrrari.cs, a class MuscleCars.cs etc. inside the project.I also use the # region tag to organize code.
public partial class Basics : Script
-
@JohnFromGWN said in Create your personal GTA 5 Trainer:
@KimonoBoy
I have a suggestion regarding organizing the code. It quickly becomes close to unmanageable if you don't organize it.Early on I thankfully found the partial classes/methods. This allows me to keep my LemonUI menu solutions as clean as possible. I have 2 LemonUI specific classes and then anywhere from 1 to 20 other classes in each solution. I do have separate menu solutions for peds, vehicles, and teleports etc, but they are all linked in each menu.
- A LemonUI section that has the menu items and other declarations but no code.
- A second LemonUI section dedicated to adding the menu items to the pool and what code is activated, value changed etc.
- All other non-LemonUI functions and codes in their own sheets, own class items.
For point 3, as an example, I also keep spawning entities separate from other functions such as animations or tasks.
Since I have close to 1000 vehicles installed and coded, I group them by Country or by Brand and by Sub Brand - which is consistent with how my dlc folders and subfolders are organized on the hard disk. So I have a class Ferrrari.cs, a class MuscleCars.cs etc. inside the project.I also use the # region tag to organize code.
public partial class Basics : Script
We can cover partial classes, sure - but once you see the overall picture of the Wiki, you'll see that it uses services, these services behaves as a middle-man between the UI and the Scripts - we will not call Game.Player.Character directly from our menu, but rather just send the state of our menu items to a service and then have our scripts respond to changes in the service and perform game changes. Here is a quick example (not how i'll implement it, but should give you an idea)
PlayerMenu
public class PlayerMenu : MenuBase { private readonly PlayerService _playerService = PlayerService.Instance; public PlayerMenu(string subtitle, string description) : base(subtitle, description) { AddCheckbox("Invincible", "Set the Player Invincible.", false, @checked => { _playerService.SetInvincible(@checked); }); } }
The Menu updates the state in the service by the value of the checkbox item
PlayerServicepublic class PlayerService { public static PlayerService Instance = new(); public bool IsInvincible { get; private set; } public void SetInvincible(bool isInvincible) { IsInvincible = isInvincible; } }
The PlayerScript now performs some in-game action depending on the state of the PlayerService
PlayerScriptpublic class PlayerScript : Script { private readonly PlayerService _playerService = PlayerService.Instance; public PlayerScript() { Tick += OnTick; } private void OnTick(object sender, EventArgs e) { if (_playerService.IsInvincible) Game.Player.Character.IsInvincible = true; else Game.Player.Character.IsInvincible = false; } }
But we can surely cover partial classes, to break our classes into smaller digestable pieces and the above is just an example and not the actual implementation. The services also allows us to Save and Load data and only have our services be updated, this way when we load a file both the Menu and the Scripts reflects the changes happening in the service.
Note: To keep as little logic inside our Ticks as possible, we'll implement custom events that can register a Character switch rather than checking if the invincible state of the service is true every frame - for instance the IsInvincible actually only have to be set 1 time and the ped will stay invincible until changes again, however if we enter a house or switch a character the invincible wears off - we can instead of calling 500 different states every frame, just call a few every frame that determines if the states should be updated, e.g. when switching a character
-
@KimonoBoy very interesting. Yeah my point for partial was really about using multiple sheets within VS rather than cramming all the code in one class sheet, with or without regions.
I manufacture code in excel using string functions, all 3 components: the function, the items, and the additions to the pool. For example I save all my favourite locations in Menyoo than I import the xml into Excel and the code is automatically created. So when you do this for 100 maps and MLOs you end up with hundreds of LOCs. Unfortunately when you're doing customizations with unique x,y,z coordinates a one size fits all approach doesn't work.
In passing I rarely keep anything in ontick other than the pool. My character and other properties, particularly for vehicles, are Menyoo based and persistent (invincible, not wanted, etc)
One request for you. If you plan on doing sliders, can you provide a solution for using negative values? The slider only allows positive integers and for my positioning mod I need both. I tried using a middle of the range process but it failed.
Apparently the approach would be to remap values but thats beyond my non programmer expertise. So presently I use a half assed approach of multiplying by -1. (Integers are converted to floats).
-
When the Wiki is in a "release" state all of the topics currently shown in the Table of Contents section will be covered. Then I'll progressively update the Wiki and with time, we've covered all NativeItems - including Sliders, Panels, Color Pickers and more.
You can represent negative values in a NativeSliderItem. You can do this by changing the way the position of the slider is mapped to the corresponding value.
For example, if you have a Max Value of 5, you could map the position 0 to -5, position 1 to -4, position 2 to -3, and so on. To achieve this, you can use a simple mathematical formula that takes the position of the slider, subtracts half of the Max Value, and then negates the result.
int mappedValue; var sliderItem = new NativeSliderItem("Slider Item", "mappedValue goes from -50 to 50", 100, 0); sliderItem.ValueChanged += (sender, args) => { var position = sliderItem.Value; mappedValue = position - (sliderItem.Maximum / 2); Notification.Show(mappedValue.ToString()); }; Add(sliderItem);
Edit: About Menyoo and persistency, isn't Menyoo unsupported now?
Edit edit: If the above code is not what you were asking, could you rephrase the question? Or maybe come up with an example on the matter?
-
This post is deleted!
-
First, with respect to Menyoo, it is still maintained and still the best Trainer.
https://github.com/MAFINS/MenyooSPThanks for your help but I don't think I explained what i'm trying to do clearly. The issue is I'm using this for ped placement - so ped vector has to be taken into account.
I have 6 sliders. The first 3 are for position. The last 3 are for Rotation.
The slider is in integers and increments in steps of 1 and is positive only.- I need floats for position so I convert to float
- I need values smaller than 1 (sensitivity) so I divide by a constant
- I need to go forwards and backwards, up and down.
I can't start the slider at 0, because in that case it can only go left to right.
If I start the value at the middle, say 50 for a maximum of 100, I can go left and I can go right.
But because I want to increment by 1 integer value at a time (my step) and add it to my ped position, I can't get this to work.For example, with the formula you suggested, if I let the slider go at its default of zero:
var position = 0
mappedValue = 0 - (100 / 2) = - 50 which would bring my ped deep undergroundStarting at 49, just left of the mid point
mappedValue = 49 - 50 would give me -1 but the next click would give me -2Somewhow I need a mechanism to increment the position.x, position.y, and position.z
I initially had 12 sliders but that's kinda crazy. So now I use a 1/-1 multiplier, which is also kinda crappy.
Current code:
private void ChangeHeight(object sender, EventArgs e) { PedFloat = (float)PedHeight.Value / 100f * Multi; PedFloat = (ClosestPed.Position.Z + PedFloat); var forwardPos = ClosestPed.Position; Vector3 newForward = new Vector3(forwardPos.X, forwardPos.Y, PedFloat - 1f); ClosestPed.Position = newForward; }
-
@JohnFromGWN said in Create your personal GTA 5 Trainer:
First, with respect to Menyoo, it is still maintained and still the best Trainer.
https://github.com/MAFINS/MenyooSPThanks for your help but I don't think I explained what i'm trying to do clearly. The issue is I'm using this for ped placement - so ped vector has to be taken into account.
I have 6 sliders. The first 3 are for position. The last 3 are for Rotation.
The slider is in integers and increments in steps of 1 and is positive only.- I need floats for position so I convert to float
- I need values smaller than 1 (sensitivity) so I divide by a constant
- I need to go forwards and backwards, up and down.
I can't start the slider at 0, because in that case it can only go left to right.
If I start the value at the middle, say 50 for a maximum of 100, I can go left and I can go right.
But because I want to increment by 1 integer value at a time (my step) and add it to my ped position, I can't get this to work.For example, with the formula you suggested, if I let the slider go at its default of zero:
var position = 0
mappedValue = 0 - (100 / 2) = - 50 which would bring my ped deep undergroundStarting at 49, just left of the mid point
mappedValue = 49 - 50 would give me -1 but the next click would give me -2Somewhow I need a mechanism to increment the position.x, position.y, and position.z
I initially had 12 sliders but that's kinda crazy. So now I use a 1/-1 multiplier, which is also kinda crappy.
Current code:
private void ChangeHeight(object sender, EventArgs e) { PedFloat = (float)PedHeight.Value / 100f * Multi; PedFloat = (ClosestPed.Position.Z + PedFloat); var forwardPos = ClosestPed.Position; Vector3 newForward = new Vector3(forwardPos.X, forwardPos.Y, PedFloat - 1f); ClosestPed.Position = newForward; }
I'll have a look tomorrow night - should be manageable 👍
-
@KimonoBoy no urgency, just curious as how to do this properly. Your help is very much appreciated.
-
@JohnFromGWN said in Create your personal GTA 5 Trainer:
@KimonoBoy no urgency, just curious as how to do this properly. Your help is very much appreciated.
By the way, have you tried looking at the source code for the NativeSliderItem? It has two overrideable methods - GoLeft() and GoRight() you can create your own NativeSliderItem that extends the NativeSliderItem and then override the behavior of GoLeft() and GoRight();
/// <summary>Reduces the value of the slider.</summary> public override void GoLeft() { int num = this._value - this.Multiplier; if (num < 0) this.Value = 0; else this.Value = num; } /// <summary>Increases the value of the slider.</summary> public override void GoRight() { int num = this._value + this.Multiplier; if (num > this.maximum) this.Value = this.maximum; else this.Value = num; }
You can then create your own implementation of these two methods that maps the types as you please - I'll show an example later, I just quickly glanced at the Source Code
-
@KimonoBoy That's very interesting, creating your own slider.
Once more this isn't urgent because my positioning tool is just to be used to setup screenshots.
In a perfect world, the slider would be able to start at its mid point, which would be set to 0.
Moving to the left would increment, -1, and moving to the right +1.
Left: 0, -1, -2, -3, -4 etc and then Right back to -2, -1, 0, +1 etc.Assuming the slider was at -15, moving to the right would then be -14.
and so on.Edit: Kinda strange that in the source example they subtract a multiplier?
You would think a multiplier was used for multiplication rather than subtraction.
-
@JohnFromGWN
If it's not urgent, I'll get back to you at another time, maybe when I cover slider items in the wiki and mod, we can chat together, I guess the implementation of mapping values to a negative would be an appropriate fit for the guide. I've updated quite a lot of stuff today, and I'll have to re-organize the wiki once I've completed the current section. Tedious, tiresome process but necessary 😅
-
Not urgent at all. Thanks. Going to start working on a FiveM resource selector now that I've finished the SP version. DLC Selection and Map (asset) previewer.
-
@JohnFromGWN said in Create your personal GTA 5 Trainer:
Not urgent at all. Thanks. Going to start working on a FiveM resource selector now that I've finished the SP version. DLC Selection and Map (asset) previewer.
I've never tried FIVEM - so not entirely sure what I'm looking at 😅
-
@KimonoBoy
This is the SP version. This allows me to have thousands of lines for thousands of dlc in dlclist.xml and only select the ones I want to load for a given session. The principle behind it is to rename selected folders so they can load, the default is not too load.It also has a map viewer, all written in vb dot net.
Fivem version, wip, is essentially same except it use a config file at startup. Actually you can have one server.cfg parent and many children which is how I do it.