Implementing Fix Player Script - KimonoBoy/SHVDNTutorial-NucleiLite GitHub Wiki
Implementing Fix Player Script
Now that our menus are set-up and ready to be used, let's create the Fix Player Script inside our Player Menu - this script does the same as the one we created together earlier, except its now activated by the menu rather than a KeyPress
The Code
- Copy and Paste the below code
using System;
using System.Windows.Forms;
using GTA;
using LemonUI;
using LemonUI.Menus;
namespace NucleiLite
{
public class Main : Script
{
ObjectPool menuPool = new ObjectPool();
NativeMenu mainMenu = new NativeMenu("NucleiLite", "Main Menu");
NativeMenu playerMenu = new NativeMenu("NucleiLite", "Player Menu");
NativeMenu vehicleSpawnerMenu = new NativeMenu("NucleiLite", "Vehicle Spawner Menu");
NativeMenu weaponsMenu = new NativeMenu("NucleiLite", "Weapons Menu");
public Main()
{
mainMenu.AddSubMenu(playerMenu);
mainMenu.AddSubMenu(vehicleSpawnerMenu);
mainMenu.AddSubMenu(weaponsMenu);
menuPool.Add(mainMenu);
menuPool.Add(playerMenu);
menuPool.Add(vehicleSpawnerMenu);
menuPool.Add(weaponsMenu);
NativeItem itemFixPlayer = new NativeItem("Fix Player", "Restores Player's Health and Armor");
itemFixPlayer.Activated += (sender, args) =>
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
};
playerMenu.Add(itemFixPlayer);
KeyDown += OnKeyDown;
Tick += OnTick;
}
private void OnTick(object sender, EventArgs e)
{
menuPool.Process();
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F5)
{
mainMenu.Visible = !mainMenu.Visible;
}
}
}
}
- Build and Reload(), open your Menu F5 and Select Player Menu and then select Fix Player and you should see the following
- Press the Enter key to activate the script
Code Breakdown - Simplified
A few new things are going on here, and they might seem confusing, but let's give it a try
NativeItem itemFixPlayer = new NativeItem("Fix Player", "Restores Player's Health and Armor");
itemFixPlayer.Activated += (sender, args) =>
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
};
playerMenu.Add(itemFixPlayer);
NativeItem itemFixPlayer = new NativeItem("Fix Player", "Restores Player's Health and Armor");
The above code is based on the following constructor from the NativeItem class
public NativeItem(string title, string description)
A NativeItem is created this item can be activated to perform a specific task we'll elaborate on that below
itemFixPlayer.Activated += (sender, args) => { }
We call the itemFixPlayer defined just above - the itemFixPlayer has an event called Activated, this event is triggered when the user activates the item (typically by pressing Enter)
The (sender, args) => { }
is called an anonymous method where the (sender, args)
is the arguments/parameters/inputs passed in and the => { }
defines the task to be performed, where everything inside the { }
will be performed, in our case it looks like the following
itemFixPlayer.Activated += (sender, args) =>
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
};
So when the itemFixPlayer is activated (Enter pressed while the item is Selected) the code within the { }
is performed - Setting Health to MaxHealth and Setting Armor to MaxArmor and finally a message is displayed to the user, informing them about their Health and Armor being restored
The above code would be the equivalent to the following
private void FixPlayer(object sender, EventArgs e)
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
}
Creating the event-method and then assigning the .activated to that method instead, like so
itemFixPlayer.Activated += FixPlayer;
So for now, the anonymous method might seem overwhelming, but you'll see in our Spawn Vehicle Script why this is way easier than defining named Methods
playerMenu.Add(itemFixPlayer);
Finally, we add the new NativeItem to it's associated menu which is the playerMenu in our case
Code Breakdown - Advanced
Let's dive a bit more into what an anonymous method is, and why it's a powerful tool, consider our code
using System;
using System.Windows.Forms;
using GTA;
using LemonUI;
using LemonUI.Menus;
namespace NucleiLite
{
public class Main : Script
{
ObjectPool menuPool = new ObjectPool();
NativeMenu mainMenu = new NativeMenu("NucleiLite", "Main Menu");
NativeMenu playerMenu = new NativeMenu("NucleiLite", "Player Menu");
NativeMenu vehicleSpawnerMenu = new NativeMenu("NucleiLite", "Vehicle Spawner Menu");
NativeMenu weaponsMenu = new NativeMenu("NucleiLite", "Weapons Menu");
public Main()
{
mainMenu.AddSubMenu(playerMenu);
mainMenu.AddSubMenu(vehicleSpawnerMenu);
mainMenu.AddSubMenu(weaponsMenu);
menuPool.Add(mainMenu);
menuPool.Add(playerMenu);
menuPool.Add(vehicleSpawnerMenu);
menuPool.Add(weaponsMenu);
NativeItem itemFixPlayer = new NativeItem("Fix Player", "Restores Player's Health and Armor");
itemFixPlayer.Activated += (sender, args) =>
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
};
playerMenu.Add(itemFixPlayer);
KeyDown += OnKeyDown;
Tick += OnTick;
}
private void OnTick(object sender, EventArgs e)
{
menuPool.Process();
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F5)
{
mainMenu.Visible = !mainMenu.Visible;
}
}
}
}
Let's break down the new changes
NativeItem itemFixPlayer = new NativeItem("Fix Player", "Restores Player's Health and Armor");
itemFixPlayer.Activated += (sender, args) =>
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
};
playerMenu.Add(itemFixPlayer);
This adds a new item to the playerMenu submenu that will restore the player's health and armor when activated. Here's what it does in more detail
NativeItem itemFixPlayer = new NativeItem("Fix Player", "Restores Player's Health and Armor");
This line creates a new instance of the NativeItem class, which represents an item in a LemonUI Menu. This instance is named itemFixPlayer.
The NativeItem constructor we're using takes two parameters:
public NativeItem(string title, string description)
string title: Representing the text that will be displayed for the *item in the menu. (In our case Fix Player)
string description: Representing an optional description of the item that will be displayed in a tooltip at the bottom of the menu when the item is highlighted. (In our case Restores Player's Health and Armor)
There are overloaded constructors defined in the NativeItem class - an overloaded constructor is another constructor that creates the same item but with different parameters (input). If we go to the Documentation of the NativeItem, you'll notice there are three different constructors
public NativeItem(string title)
: this(title, string.Empty, string.Empty)
{
}
This only takes a Title and leaves the Description and the AltTitle blank
public NativeItem(string title, string description)
: this(title, description, string.Empty)
{
}
This is the one we're currently using. This takes a Title and a Description and leaves the AltTitle blank
public NativeItem(string title, string description, string altTitle)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
this.title = new ScaledText(PointF.Empty, title, 0.345f);
Description = description;
this.altTitle = new ScaledText(PointF.Empty, altTitle, 0.345f);
}
This takes a Title, a Description and an AltTitle (Title to the right of the Menu)
You can learn more about Overloaded Methods and Constructors at Constructor Overloading - pretty much the same concept goes for Methods
itemFixPlayer.Activated += (sender, args) =>
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
};
After creating the itemFixPlayer instance, we use that variable and add an event handler for the item's Activated event using the += operator. The Activated event is raised when the user selects the item and hits Enter in the menu.
The event handler is defined using a lambda expression, which is a concise way of defining an anonymous method. The lambda expression takes two parameters (inputs), sender and args, the sender represents the object that raised the event and the args parameter represents any additional information or data related to the event that is being raised.
You can learn more about Lambda Expressions at Lambda Expressions and more about Anonymous Methods at Anonymous Methods
Inside the code-block { }
the task to restore the Player's Health and Armor is defined
{
Game.Player.Character.Health = Game.Player.Character.MaxHealth;
Game.Player.Character.Armor = Game.Player.MaxArmor;
Notification.Show("Health and Armor Restored!");
};
playerMenu.Add(itemFixPlayer);
Finally, we add the new NativeItem to it's associated menu which is the playerMenu in our case
Conclusion
We've implemented the Fix Player Script we've created earlier into our Menu - we can now Restore Health and Armor simply by selecting the item from our Menu
Previous - Introduction to LemonUI
Next - Implementing Invincible Script