diff --git a/LemonUI/Elements/BaseElement.cs b/LemonUI/Elements/BaseElement.cs index 208911b..d68def8 100644 --- a/LemonUI/Elements/BaseElement.cs +++ b/LemonUI/Elements/BaseElement.cs @@ -34,12 +34,9 @@ public abstract class BaseElement : I2Dimensional /// /// The Position of the drawable. /// - public PointF Position + public virtual PointF Position { - get - { - return literalPosition; - } + get => literalPosition; set { literalPosition = value; @@ -49,12 +46,9 @@ public PointF Position /// /// The Size of the drawable. /// - public SizeF Size + public virtual SizeF Size { - get - { - return literalSize; - } + get => literalSize; set { literalSize = value; @@ -64,11 +58,11 @@ public SizeF Size /// /// The Color of the drawable. /// - public Color Color { get; set; } = Color.FromArgb(255, 255, 255, 255); + public virtual Color Color { get; set; } = Color.FromArgb(255, 255, 255, 255); /// /// The rotation of the drawable. /// - public float Heading { get; set; } = 0; + public virtual float Heading { get; set; } = 0; #endregion diff --git a/LemonUI/Elements/ScaledAnim.cs b/LemonUI/Elements/ScaledAnim.cs new file mode 100644 index 0000000..0a46989 --- /dev/null +++ b/LemonUI/Elements/ScaledAnim.cs @@ -0,0 +1,148 @@ +#if ALTV +using AltV.Net.Client; +#elif FIVEM +using CitizenFX.Core; +#elif RAGEMP +using RAGE.Game; +#elif RPH +using Rage.Native; +#elif SHVDN3 || SHVDNC +using GTA; +#endif +using System; +using System.Drawing; + +namespace LemonUI.Elements +{ + /// + /// A scaled animation using YTD files with all of the frames. + /// + public class ScaledAnim : ScaledTexture + { + #region Fields + + private float frameRate; + private int start = 0; + private int duration; + + #endregion + + #region Properties + + /// + /// The total number of frames per second. + /// + public float FrameRate + { + get => frameRate; + set + { + if (value <= 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "The Frame Rate can't be equal or lower to zero."); + } + + frameRate = value; + } + } + /// + /// The duration of the animation in milliseconds. + /// + public int Duration + { + get => duration; + set + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "The duration can't be under zero."); + } + + duration = value; + } + } + + #endregion + + #region Constructors + + /// + /// Creates a new dictionary based animation. + /// + /// The texture dictionary (YTD) to use. + public ScaledAnim(string dict) : this(dict, PointF.Empty, SizeF.Empty) + { + } + /// + /// Creates a new dictionary based animation. + /// + /// The texture dictionary (YTD) to use. + /// The size of the animation. + public ScaledAnim(string dict, SizeF size) : this(dict, PointF.Empty, size) + { + } + /// + /// Creates a new dictionary based animation. + /// + /// The texture dictionary (YTD) to use. + /// The position of the animation. + /// The size of the animation. + public ScaledAnim(string dict, PointF pos, SizeF size) : base(pos, size, dict, string.Empty) + { + Dictionary = dict ?? throw new ArgumentNullException(nameof(dict)); + } + + #endregion + + #region Functions + + /// + /// Draws the animation. + /// + public override void Draw() + { + if (Duration <= 0) + { + return; + } + +#if ALTV + int time = Alt.Natives.GetGameTimer(); +#elif RAGEMP + int time = Misc.GetGameTimer(); +#elif RPH + int time = NativeFunction.CallByHash(0x9CD27B0045628463); +#elif FIVEM || SHVDN3 || SHVDNC + int time = Game.GameTime; +#endif + + int end = start + Duration; + + if (start == 0 || end <= time) + { + start = time; + } + + float progress = (time - (float)start) / Duration; + int totalFrames = (int)((duration / 1000.0f) * frameRate); + int currentFrame = (int)(totalFrames * progress) + 1; + + if (progress < 0) + { + currentFrame = 1; + start = time; + } + else if (currentFrame >= totalFrames) + { + currentFrame = totalFrames; + start = time; + } + + Texture = currentFrame.ToString(); + + base.Draw(); + } + + #endregion + } +}