Skip to content

Instantly share code, notes, and snippets.

@CamxxCore
Created July 26, 2017 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CamxxCore/a0c49de27c0bd0a58e0216bb8b418c95 to your computer and use it in GitHub Desktop.
Save CamxxCore/a0c49de27c0bd0a58e0216bb8b418c95 to your computer and use it in GitHub Desktop.
Class to display a chat box like multiplayer
using System;
using System.Windows.Forms;
using GTA;
using GTA.Native;
using Control = System.Windows.Forms.Control;
public delegate void UIChatMessageHandler(UIChat sender, string message);
public class UIChat : GTA.Script
{
static int scaleform;
static string username;
static bool capsLock;
public static bool Active { get; private set; }
private static DateTime displayTimer;
public static event UIChatMessageHandler MessageSent;
private string textBuffer = null;
public UIChat()
{
Tick += OnTick;
KeyDown += KeyPressed;
KeyUp += KeyReleased;
scaleform = Function.Call<int>(Hash.REQUEST_SCALEFORM_MOVIE, "multiplayer_chat");
username = Game.Player.Name;
Active = false;
}
private void KeyReleased(object sender, KeyEventArgs e)
{
if (Active && e.KeyCode == Keys.CapsLock)
capsLock = Control.IsKeyLocked(Keys.CapsLock);
}
private void KeyPressed(object sender, KeyEventArgs e)
{
if (!Active)
return;
char keyChar = KeyHelper.GetCharFromKey(e.KeyCode, (e.Modifiers & Keys.Shift) != 0);
if (char.IsLetterOrDigit(keyChar))
{
if (capsLock)
keyChar = char.ToUpper(keyChar);
}
else
{
switch (e.KeyCode)
{
case Keys.Back:
{
if (textBuffer.Length < 1)
{
SetTypingDone();
SetVisibleState(VisibleState.Default);
ResetDisplayTimer(5000);
}
else
{
SetVisibleState(VisibleState.Typing);
textBuffer = textBuffer.Substring(0, textBuffer.Length - 1);
AddTypingText(textBuffer);
}
return;
}
case Keys.Enter:
OnMessageSent(textBuffer);
SetTypingDone(true);
SetVisibleState(VisibleState.Default);
ResetDisplayTimer(5000);
return;
case Keys.Escape:
SetTypingDone();
SetVisibleState(VisibleState.Default);
ResetDisplayTimer(5000);
return;
}
}
AddTypingText(keyChar);
}
private static void OnTick(object sender, EventArgs e)
{
if (displayTimer.Ticks > 0 && DateTime.Now > displayTimer)
{
SetVisibleState(VisibleState.Hidden);
displayTimer = new DateTime();
}
if (Active)
{
Function.Call(Hash.DISABLE_ALL_CONTROL_ACTIONS, 0);
if (Function.Call<bool>(Hash.IS_DISABLED_CONTROL_JUST_PRESSED, 0, (int) GTA.Control.CursorScrollUp))
{
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION, scaleform, "PAGE_UP");
Function.Call(Hash._POP_SCALEFORM_MOVIE_FUNCTION_VOID);
}
else if (Function.Call<bool>(Hash.IS_DISABLED_CONTROL_JUST_PRESSED, 0, (int) GTA.Control.CursorScrollDown))
{
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION, scaleform, "PAGE_DOWN");
Function.Call(Hash._POP_SCALEFORM_MOVIE_FUNCTION_VOID);
}
}
Function.Call((Hash) 0x0DF606929C105BE1, scaleform, 255, 255, 255, 100, 0);
}
protected void AddTypingText(string text)
{
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION, scaleform, "ADD_TEXT");
Function.Call(Hash._BEGIN_TEXT_COMPONENT, "STRING");
Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, text);
Function.Call(Hash._END_TEXT_COMPONENT);
Function.Call(Hash._POP_SCALEFORM_MOVIE_FUNCTION_VOID);
}
protected void AddTypingText(char text)
{
AddTypingText(Convert.ToString(text));
}
protected void SetTypingDone(bool addMessage = false)
{
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION, scaleform, "SET_TYPING_DONE");
Function.Call(Hash._POP_SCALEFORM_MOVIE_FUNCTION_VOID);
if (addMessage)
{
AddFeedMessage(username, textBuffer);
}
textBuffer = string.Empty;
}
public static void SetVisibleState(VisibleState state, TypeMode mode = TypeMode.None)
{
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION, scaleform, "SET_FOCUS");
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_INT, (int) state);
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_INT, (int) mode);
Function.Call(Hash._BEGIN_TEXT_COMPONENT, "STRING");
Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, username);
Function.Call(Hash._END_TEXT_COMPONENT);
Function.Call(Hash._POP_SCALEFORM_MOVIE_FUNCTION_VOID);
Active = state == VisibleState.Typing;
if (Active) displayTimer = new DateTime();
}
public static void AddFeedMessage(string name, string message)
{
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION, scaleform, "ADD_MESSAGE");
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_STRING, name.Length < 0 ? "undefined" : name);
Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_STRING, message);
Function.Call(Hash._POP_SCALEFORM_MOVIE_FUNCTION_VOID);
if (!Active) ResetDisplayTimer(5000);
}
private static void ResetDisplayTimer(int interval)
{
displayTimer = DateTime.Now + TimeSpan.FromMilliseconds(interval);
}
protected virtual void OnMessageSent(string msg)
{
MessageSent?.Invoke(this, msg);
}
public static void SetLocalUsername(string Username)
{
username = Username;
}
public enum VisibleState
{
Hidden,
Default,
Typing
}
public enum TypeMode
{
None,
Team,
All,
Clan
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment