using CitizenFX.Core;
using CitizenFX.Core;
using CitizenFX.Core.Native;
using CitizenFX.Core.Native;
using CitizenFX.Core.UI;
using CitizenFX.Core.UI;
using NativeUI;
using NativeUI;
using System;
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using System.Threading.Tasks;
using TinyJson;
using TinyJson;
namespace Emotes
namespace Emotes
public class Emotes : BaseScript
public class Emotes : BaseScript
string emotesText = string.Empty;
string emotesText = string.Empty;
List<Emote> emotes = new List<Emote>();
List<Emote> emotes = new List<Emote>();
List<string> errors = new List<string>();
List<string> errors = new List<string>();
Config config = new Config();
Config config = new Config();
MenuPool menuPool;
MenuPool menuPool;
UIMenu mainMenu;
UIMenu mainMenu;
public Emotes()
public Emotes()
// FiveM related things
// FiveM related things
EventHandlers["onPlayerJoining"] += new Action<dynamic, dynamic>(OnPlayerJoining);
EventHandlers["onPlayerJoining"] += new Action<dynamic, dynamic>(OnPlayerJoining);
// Récupère les configs et la liste d'emote
Tick += OnTick;
Tick += OnTick;
public async Task OnTick()
public async Task OnTick()
//if (menuLoaded)
//if (menuLoaded)
menuPool.ProcessMenus();
menuPool.ProcessMenus();
// Cancel emote when player is moving
// Cancel emote when player is moving
if (Game.IsControlJustReleased(0, Control.MoveUpOnly) ||
if (Game.IsControlJustReleased(0, Control.MoveUpOnly) ||
Game.IsControlJustReleased(0, Control.MoveDownOnly) ||
Game.IsControlJustReleased(0, Control.MoveDownOnly) ||
Game.IsControlJustReleased(0, Control.MoveLeftOnly) ||
Game.IsControlJustReleased(0, Control.MoveLeftOnly) ||
Game.IsControlJustReleased(0, Control.MoveRightOnly))
Game.IsControlJustReleased(0, Control.MoveRightOnly))
CancelEmote();
CancelEmote();
else if (Game.IsControlJustPressed(0, Control.ReplayShowhotkey))
else if (Game.IsControlJustPressed(0, Control.DropAmmo))
mainMenu.Visible = !mainMenu.Visible;
mainMenu.Visible = !mainMenu.Visible;
#region Methods
#region Methods
void LoadConfig()
void LoadConfig()
string configFile = Function.Call<string>(Hash.LOAD_RESOURCE_FILE, "emotes", "config.ini");
string configFile = Function.Call<string>(Hash.LOAD_RESOURCE_FILE, "emotes", "config.ini");
Debug.WriteLine("{0}", configFile);
Debug.WriteLine("{0}", configFile);
string[] lines = configFile.Split('\n');
string[] lines = configFile.Split('\n');
foreach (string line in lines)
foreach (string line in lines)
string[] content = line.Split('=');
string[] content = line.Split('=');
if (content[0].ToLower() == "jsonfile")
if (content[0].ToLower() == "jsonfile")
config.JsonFile = content[1];
config.JsonFile = content[1];
config.JsonFile = config.JsonFile.Replace("\n", "");
config.JsonFile = config.JsonFile.Replace("\n", "");
void LoadJson()
void LoadJson()
string jsonString = string.Empty;
string jsonString = string.Empty;
string fileName = string.Empty;
string fileName = string.Empty;
foreach (char c in config.JsonFile)
foreach (char c in config.JsonFile)
if ((int)c != 13)
if ((int)c != 13)
fileName += c;
fileName += c;
jsonString = Function.Call<string>(Hash.LOAD_RESOURCE_FILE, "emotes", fileName);
jsonString = Function.Call<string>(Hash.LOAD_RESOURCE_FILE, "emotes", fileName);
var jsonObject = (Dictionary<string, object>)jsonString.FromJson<object>();
var jsonObject = (Dictionary<string, object>)jsonString.FromJson<object>();
var emoteList = (List<object>)jsonObject["emotes"];
var emoteList = (List<object>)jsonObject["emotes"];
foreach (Dictionary<string, object> emote in emoteList)
foreach (Dictionary<string, object> emote in emoteList)
emotes.Add(new Emote()
emotes.Add(new Emote()
EmoteType = (string)emote["hash"],
EmoteType = (string)emote["hash"],
Command = (string)emote["title"],
Command = (string)emote["title"],
Description = (string)emote["description"],
Description = (string)emote["description"],
Delay = (int)emote["delay"],
Delay = (int)emote["delay"],
PlayEnterAnim = (bool)emote["playEnterAnim"]
PlayEnterAnim = (bool)emote["playEnterAnim"]
errors.Add((string)jsonObject["errorVehicle"]);
errors.Add((string)jsonObject["errorVehicle"]);
errors.Add((string)jsonObject["errorUnexpected"]);
errors.Add((string)jsonObject["errorUnexpected"]);
errors.Add((string)jsonObject["errorPlayerID"]);
errors.Add((string)jsonObject["errorPlayerID"]);
foreach (Emote emote in emotes)
if (emotesText == string.Empty)
emotesText += emote.Command;
emotesText += ", " + emote.Command;
void PrintEmoteList()
void PrintEmoteList()
TriggerEvent("chatMessage", "ALERT", new int[] { 255, 0, 0 } , emotesText);
TriggerEvent("chatMessage", "ALERT", new int[] { 255, 0, 0 } , emotesText);
void CancelEmote()
void CancelEmote()
Function.Call(Hash.CLEAR_PED_TASKS, Game.PlayerPed);
Function.Call(Hash.CLEAR_PED_TASKS, Game.PlayerPed);
void PlayEmote(Emote emote)
void PlayEmote(Emote emote)
if (Game.PlayerPed != null)
if (Game.PlayerPed != null)
bool isInVehicle = Function.Call<bool>(Hash.IS_PED_IN_ANY_VEHICLE, Game.PlayerPed, true);
bool isInVehicle = Function.Call<bool>(Hash.IS_PED_IN_ANY_VEHICLE, Game.PlayerPed, true);
if (!isInVehicle)
if (!isInVehicle)
Function.Call(Hash.TASK_START_SCENARIO_IN_PLACE, Game.PlayerPed, emote.EmoteType, emote.Delay, emote.PlayEnterAnim);
Function.Call(Hash.TASK_START_SCENARIO_IN_PLACE, Game.PlayerPed, emote.EmoteType, emote.Delay, emote.PlayEnterAnim);
Screen.ShowNotification(emote.Description);
Screen.ShowNotification(emote.Description);
Screen.ShowNotification(errors.ElementAt(0));
Screen.ShowNotification(errors.ElementAt(0));
Screen.ShowNotification(errors.ElementAt(2));
Screen.ShowNotification(errors.ElementAt(2));
#region Events
#region Events
void OnItemSelect(UIMenu sender, UIMenuItem item, int index)
void OnItemSelect(UIMenu sender, UIMenuItem item, int index)
Emote emote = emotes.FirstOrDefault(o => o.Description == item.Text);
Emote emote = emotes.FirstOrDefault(o => o.Description == item.Text);
if (emote != null)
if (emote != null)
PlayEmote(emote);
PlayEmote(emote);
Screen.ShowNotification(errors.ElementAt(1));
Screen.ShowNotification(errors.ElementAt(1));
mainMenu.Visible = false;
mainMenu.Visible = false;
// TODO: Should check if player already loaded
// TODO: Should check if player already loaded
void OnPlayerJoining(dynamic arg1, dynamic arg2)
void OnPlayerJoining(dynamic arg1, dynamic arg2)
// Récupère les configs et la liste d'emote
// Crée le menu
// Crée le menu
menuPool = new MenuPool();
menuPool = new MenuPool();
mainMenu = new UIMenu("Emotes", "Select an emote");
mainMenu = new UIMenu("Emotes", "Choose an emote");
mainMenu.MouseControlsEnabled = false;
mainMenu.MouseControlsEnabled = false;
menuPool.Add(mainMenu);
menuPool.Add(mainMenu);
mainMenu.OnItemSelect += OnItemSelect;
mainMenu.OnItemSelect += OnItemSelect;
foreach (Emote emote in emotes)
foreach (Emote emote in emotes)
mainMenu.AddItem(new UIMenuItem(emote.Description));
mainMenu.AddItem(new UIMenuItem(emote.Description));
menuPool.RefreshIndex();
menuPool.RefreshIndex();