File BaseScaleform.cs
File List > LemonUI > LemonUI > Scaleform > BaseScaleform.cs
Go to the documentation of this file
#if FIVEM
using CitizenFX.Core;
using CitizenFX.Core.Native;
using System.Threading.Tasks;
#elif RAGEMP
using RAGE.Game;
#elif ALTV
using AltV.Net.Client;
#elif RPH
using Rage.Native;
#elif SHVDN3 || SHVDNC
using GTA;
using GTA.Native;
#endif
using System;
namespace LemonUI.Scaleform
{
public abstract class BaseScaleform : IScaleform
{
#region Fields
#if FIVEM || SHVDN3
[Obsolete("Please use the Handle or Name properties and call the methods manually.", true)]
#endif
#if FIVEM
protected CitizenFX.Core.Scaleform scaleform = new CitizenFX.Core.Scaleform(string.Empty);
#elif SHVDN3
protected GTA.Scaleform scaleform = new GTA.Scaleform(string.Empty);
#endif
#endregion
#region Properties
public int Handle { get; private set; }
public string Name { get; }
public bool Visible { get; set; }
public bool IsLoaded
{
get
{
#if FIVEM
return API.HasScaleformMovieLoaded(Handle);
#elif ALTV
return Alt.Natives.HasScaleformMovieLoaded(Handle);
#elif RAGEMP
return Invoker.Invoke<bool>(Natives.HasScaleformMovieLoaded, Handle);
#elif RPH
return NativeFunction.CallByHash<bool>(0x85F01B8D5B90570E, Handle);
#elif SHVDN3 || SHVDNC
return Function.Call<bool>(Hash.HAS_SCALEFORM_MOVIE_LOADED, Handle);
#endif
}
}
#endregion
#region Constructors
public BaseScaleform(string sc)
{
Name = sc ?? throw new ArgumentNullException(nameof(sc));
#if FIVEM
Handle = API.RequestScaleformMovie(Name);
#elif ALTV
Handle = Alt.Natives.RequestScaleformMovie(Name);
#elif RAGEMP
Handle = Invoker.Invoke<int>(Natives.RequestScaleformMovie, Name);
#elif RPH
Handle = NativeFunction.CallByHash<int>(0x11FE353CF9733E6F, Name);
#elif SHVDN3 || SHVDNC
Handle = Function.Call<int>(Hash.REQUEST_SCALEFORM_MOVIE, Name);
#endif
}
#endregion
#region Tools
private void CallFunctionBase(string function, params object[] parameters)
{
if (function == null)
{
throw new ArgumentNullException(nameof(function), "The function name is null.");
}
if (string.IsNullOrWhiteSpace(function))
{
throw new ArgumentOutOfRangeException(nameof(function), "The function name is empty or white space.");
}
#if FIVEM
API.BeginScaleformMovieMethod(Handle, function);
#elif ALTV
Alt.Natives.BeginScaleformMovieMethod(Handle, function);
#elif RAGEMP
Invoker.Invoke(0xF6E48914C7A8694E, Handle, function);
#elif RPH
NativeFunction.CallByHash<int>(0xF6E48914C7A8694E, Handle, function);
#elif SHVDN3 || SHVDNC
Function.Call((Hash)0xF6E48914C7A8694E, Handle, function);
#endif
foreach (object obj in parameters)
{
if (obj == null)
{
throw new ArgumentNullException(nameof(parameters), "Unexpected null function argument in parameters.");
}
else if (obj is int objInt)
{
#if FIVEM
API.ScaleformMovieMethodAddParamInt(objInt);
#elif ALTV
Alt.Natives.ScaleformMovieMethodAddParamInt(objInt);
#elif RAGEMP
Invoker.Invoke(0xC3D0841A0CC546A6, objInt);
#elif RPH
NativeFunction.CallByHash<int>(0xC3D0841A0CC546A6, objInt);
#elif SHVDN3 || SHVDNC
Function.Call((Hash)0xC3D0841A0CC546A6, objInt);
#endif
}
else if (obj is string objString)
{
#if FIVEM
API.BeginTextCommandScaleformString("STRING");
API.AddTextComponentSubstringPlayerName(objString);
API.EndTextCommandScaleformString();
#elif ALTV
Alt.Natives.BeginTextCommandScaleformString("STRING");
Alt.Natives.AddTextComponentSubstringPlayerName(objString);
Alt.Natives.EndTextCommandScaleformString();
#elif RAGEMP
Invoker.Invoke(Natives.BeginTextCommandScaleformString, "STRING");
Invoker.Invoke(Natives.AddTextComponentSubstringPlayerName, objString);
Invoker.Invoke(Natives.EndTextCommandScaleformString);
#elif RPH
NativeFunction.CallByHash<int>(0x80338406F3475E55, "STRING");
NativeFunction.CallByHash<int>(0x6C188BE134E074AA, objString);
NativeFunction.CallByHash<int>(0x362E2D3FE93A9959);
#elif SHVDN3 || SHVDNC
Function.Call((Hash)0x80338406F3475E55, "STRING");
Function.Call((Hash)0x6C188BE134E074AA, objString);
Function.Call((Hash)0x362E2D3FE93A9959);
#endif
}
else if (obj is float objFloat)
{
#if FIVEM
API.ScaleformMovieMethodAddParamFloat(objFloat);
#elif ALTV
Alt.Natives.ScaleformMovieMethodAddParamFloat(objFloat);
#elif RAGEMP
Invoker.Invoke(0xD69736AAE04DB51A, objFloat);
#elif RPH
NativeFunction.CallByHash<int>(0xD69736AAE04DB51A, objFloat);
#elif SHVDN3 || SHVDNC
Function.Call((Hash)0xD69736AAE04DB51A, objFloat);
#endif
}
else if (obj is double objDouble)
{
#if FIVEM
API.ScaleformMovieMethodAddParamFloat((float)objDouble);
#elif ALTV
Alt.Natives.ScaleformMovieMethodAddParamFloat((float)objDouble);
#elif RAGEMP
Invoker.Invoke(0xD69736AAE04DB51A, (float)objDouble);
#elif RPH
NativeFunction.CallByHash<int>(0xD69736AAE04DB51A, (float)objDouble);
#elif SHVDN3 || SHVDNC
Function.Call((Hash)0xD69736AAE04DB51A, (float)objDouble);
#endif
}
else if (obj is bool objBool)
{
#if FIVEM
API.ScaleformMovieMethodAddParamBool(objBool);
#elif ALTV
Alt.Natives.ScaleformMovieMethodAddParamBool(objBool);
#elif RAGEMP
Invoker.Invoke(0xC58424BA936EB458, objBool);
#elif RPH
NativeFunction.CallByHash<int>(0xC58424BA936EB458, objBool);
#elif SHVDN3 || SHVDNC
Function.Call((Hash)0xC58424BA936EB458, objBool);
#endif
}
else
{
throw new ArgumentException($"Unexpected argument type {obj.GetType().Name}.", nameof(parameters));
}
}
}
#endregion
#region Functions
public bool IsValueReady(int id)
{
#if FIVEM
return API.IsScaleformMovieMethodReturnValueReady(id);
#elif ALTV
return Alt.Natives.IsScaleformMovieMethodReturnValueReady(id);
#elif RAGEMP
return Invoker.Invoke<bool>(Natives._0x768FF8961BA904D6, id);
#elif RPH
return NativeFunction.CallByHash<bool>(0x768FF8961BA904D6, id);
#elif SHVDN3 || SHVDNC
return Function.Call<bool>(Hash.IS_SCALEFORM_MOVIE_METHOD_RETURN_VALUE_READY, id);
#endif
}
public T GetValue<T>(int id)
{
if (typeof(T) == typeof(string))
{
#if FIVEM
return (T)(object)API.GetScaleformMovieMethodReturnValueString(id);
#elif ALTV
return (T)(object)Alt.Natives.GetScaleformMovieMethodReturnValueString(id);
#elif RAGEMP
return Invoker.Invoke<T>(0xE1E258829A885245, id);
#elif RPH
return (T)NativeFunction.CallByHash(0xE1E258829A885245, typeof(string), id);
#elif SHVDN3 || SHVDNC
return (T)(object)Function.Call<string>(Hash.GET_SCALEFORM_MOVIE_METHOD_RETURN_VALUE_STRING, id);
#endif
}
else if (typeof(T) == typeof(int))
{
#if FIVEM
return (T)(object)API.GetScaleformMovieMethodReturnValueInt(id);
#elif ALTV
return (T)(object)Alt.Natives.GetScaleformMovieMethodReturnValueInt(id);
#elif RAGEMP
return Invoker.Invoke<T>(0x2DE7EFA66B906036, id);
#elif RPH
return (T)(object)NativeFunction.CallByHash<int>(0x2DE7EFA66B906036, id);
#elif SHVDN3 || SHVDNC
return (T)(object)Function.Call<int>(Hash.GET_SCALEFORM_MOVIE_METHOD_RETURN_VALUE_INT, id);
#endif
}
else if (typeof(T) == typeof(bool))
{
#if FIVEM
return (T)(object)API.GetScaleformMovieMethodReturnValueBool(id);
#elif ALTV
return (T)(object)Alt.Natives.GetScaleformMovieMethodReturnValueBool(id);
#elif RAGEMP
return Invoker.Invoke<T>(0xD80A80346A45D761, id);
#elif RPH
return (T)(object)NativeFunction.CallByHash<bool>(0xD80A80346A45D761, id);
#elif SHVDN3 || SHVDNC
return (T)(object)Function.Call<bool>(Hash.GET_SCALEFORM_MOVIE_METHOD_RETURN_VALUE_BOOL, id);
#endif
}
else
{
throw new InvalidOperationException($"Expected string, int or bool, got {typeof(T).Name}.");
}
}
public void CallFunction(string function, params object[] parameters)
{
CallFunctionBase(function, parameters);
#if FIVEM
API.EndScaleformMovieMethod();
#elif ALTV
Alt.Natives.EndScaleformMovieMethod();
#elif RAGEMP
Invoker.Invoke(0xC6796A8FFA375E53);
#elif RPH
NativeFunction.CallByHash<int>(0xC6796A8FFA375E53);
#elif SHVDN3 || SHVDNC
Function.Call((Hash)0xC6796A8FFA375E53);
#endif
}
#if FIVEM || SHVDN3 || SHVDNC
#if FIVEM
public async Task<T> CallFunction<T>(string function, params object[] parameters)
#else
public T CallFunction<T>(string function, params object[] parameters)
#endif
{
int id = CallFunctionReturn(function, parameters);
while (!IsValueReady(id))
{
#if FIVEM
await BaseScript.Delay(0);
#elif SHVDN3 || SHVDNC
Script.Yield();
#endif
}
return GetValue<T>(id);
}
#endif
public int CallFunctionReturn(string function, params object[] parameters)
{
CallFunctionBase(function, parameters);
#if FIVEM
return API.EndScaleformMovieMethodReturnValue();
#elif ALTV
return Alt.Natives.EndScaleformMovieMethodReturnValue();
#elif RAGEMP
return Invoker.Invoke<int>(0xC50AA39A577AF886);
#elif RPH
return NativeFunction.CallByHash<int>(0xC50AA39A577AF886);
#elif SHVDN3 || SHVDNC
return Function.Call<int>((Hash)0xC50AA39A577AF886);
#endif
}
public abstract void Update();
public virtual void DrawFullScreen()
{
if (!Visible)
{
return;
}
Update();
#if FIVEM
API.DrawScaleformMovieFullscreen(Handle, 255, 255, 255, 255, 0);
#elif ALTV
Alt.Natives.DrawScaleformMovieFullscreen(Handle, 255, 255, 255, 255, 0);
#elif RAGEMP
Invoker.Invoke(Natives.DrawScaleformMovieFullscreen, Handle, 255, 255, 255, 255, 0);
#elif RPH
NativeFunction.CallByHash<int>(0x0DF606929C105BE1, Handle, 255, 255, 255, 255, 0);
#elif SHVDN3 || SHVDNC
Function.Call(Hash.DRAW_SCALEFORM_MOVIE_FULLSCREEN, Handle, 255, 255, 255, 255, 0);
#endif
}
public virtual void Draw() => DrawFullScreen();
public virtual void Process() => DrawFullScreen();
public void Dispose()
{
int id = Handle;
#if FIVEM
API.SetScaleformMovieAsNoLongerNeeded(ref id);
#elif ALTV
Alt.Natives.SetScaleformMovieAsNoLongerNeeded(ref id);
#elif RAGEMP
IntReference idPtr = new IntReference(id);
Invoker.Invoke(Natives.SetScaleformMovieAsNoLongerNeeded, idPtr);
#elif RPH
using (NativePointer idPtr = new NativePointer(4))
{
idPtr.SetValue(id);
NativeFunction.CallByHash<int>(0x6DD8F5AA635EB4B2, idPtr);
}
#elif SHVDN3 || SHVDNC
unsafe
{
Function.Call(Hash.SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED, &id);
}
#endif
}
#endregion
}
}