using Microsoft.Xna.Framework; using System; using System.Linq; namespace OpenVIII { /// /// Root class all menu objects can grow from. /// public abstract class Menu_Base { #region Fields protected Rectangle _pos; #endregion Fields #region Properties /// /// Focus scales and centers the menu. /// public static Matrix Focus { get; protected set; } /// /// Adjusted mouse location used to determine if mouse is highlighting a button. /// public static Point MouseLocation => InputMouse.Location.Transform(Focus); public static Point ScreenBottomLeft => new Point(0, Memory.Graphics.GraphicsDevice.Viewport.Height).Transform(Focus); public static Point ScreenBottomRight => new Point(Memory.Graphics.GraphicsDevice.Viewport.Width, Memory.Graphics.GraphicsDevice.Viewport.Height).Transform(Focus); public static Point ScreenTopLeft => new Point(0, 0).Transform(Focus); public static Point ScreenTopRight => new Point(Memory.Graphics.GraphicsDevice.Viewport.Width, 0).Transform(Focus); public Menu_Base CONTAINER { get; set; } public Cursor_Status Cursor_Status { get; set; } = Cursor_Status.Disabled; /// /// Characters/Enemies/GF /// public virtual Damageable Damageable { get; protected set; } /// /// If enabled the menu is Visible and all functionality works. Else everything is hidden and /// nothing functions. /// public bool Enabled { get; private set; } = true; public virtual int Height { get => _pos.Height; set => _pos.Height = value; } public OffsetAnchor OffsetAnchor { get; set; } /// /// Position of party member 0,1,2. If -1 at the time of setting the character wasn't in the party. /// public sbyte PartyPos { get; protected set; } = sbyte.MaxValue; /// /// Where to draw this item. /// public virtual Rectangle Pos { get => _pos; set => _pos = value; } public virtual int Width { get => _pos.Width; set => _pos.Width = value; } public virtual int X { get => _pos.X; set => _pos.X = value; } public virtual int Y { get => _pos.Y; set => _pos.Y = value; } #endregion Properties #region Methods public static implicit operator Rectangle(Menu_Base v) => v.Pos; public abstract void Draw(); /// /// Hide object prevents drawing, update, inputs. /// public virtual void Hide() => Enabled = false; public virtual void HideChildren() { } public abstract bool Inputs(); public virtual void ModeChangeEvent(object sender, Enum e) { } /// /// Things that change rarely. Like a party member changes or Laguna dream happens. /// public virtual void Refresh() => RefreshChild(); /// /// by default null damageable won't propogate to children. resets to false after refresh. /// public bool ForceNullDamageable { get; set; } = false; /// /// Update set characters and then refresh. /// /// /// public virtual void Refresh(Damageable damageable) { SetDamageable(damageable, null); Refresh(); } public bool Battle { get; protected set; } = false; public void SetDamageable(Damageable damageable, sbyte? partypos = null, bool forcenull = false) { if ((Damageable != damageable) || (partypos.HasValue && partypos.Value != PartyPos)) { if (partypos != null) { Damageable = damageable; PartyPos = partypos.Value; if (Damageable == null) { if (PartyPos >= 0 && Memory.State?.PartyData != null && PartyPos < Memory.State.PartyData.Count) Damageable = Memory.State[Memory.State.PartyData[PartyPos]]; else { var enemypos = (0 - PartyPos) - 1; if (PartyPos < 0 && Enemy.Party != null && enemypos < Enemy.Party.Count) { Damageable = Enemy.Party[enemypos]; } } } } else if (damageable != null) { Damageable = damageable; if (Damageable.GetCharacterData(out var c)) { PartyPos = (sbyte)(Memory.State?.Party?.Where(x => !x.Equals(Characters.Blank)).ToList().FindIndex(x => x.Equals(c.ID)) ?? -1); } else if (Damageable is Enemy) { PartyPos = checked((sbyte)(0 - Enemy.Party.FindIndex(x => x.Equals(Damageable)) - 1)); } else PartyPos = sbyte.MaxValue; } else if(ForceNullDamageable || forcenull) { ForceNullDamageable = true; Damageable = null; PartyPos = sbyte.MaxValue; } } } /// /// Plan is to use this to reset values to a default state if done. /// public virtual void Reset() { } /// /// Show object enables drawing, update, inputs. /// public virtual void Show() => Enabled = true; public abstract bool Update(); protected abstract void Init(); /// /// For child items. /// protected virtual void RefreshChild() { } #endregion Methods } public class OffsetAnchor { #region Fields private Vector2 v = Vector2.Zero; #endregion Fields #region Constructors public OffsetAnchor(Vector2 pos) => this.v = pos; public OffsetAnchor(Point pos) => this.v = pos.ToVector2(); public OffsetAnchor() { } #endregion Constructors #region Properties public Point pPos { get => v.ToPoint(); set => v = value.ToVector2(); } public Vector2 vPos { get => v; set => v = value; } public float X { get => v.X; set => v.X = value; } public float Y { get => v.Y; set => v.Y = value; } #endregion Properties #region Methods public static explicit operator Point(OffsetAnchor a) => a.v.ToPoint(); public static implicit operator OffsetAnchor(Vector2 a) => new OffsetAnchor(a); public static implicit operator OffsetAnchor(Point a) => new OffsetAnchor(a); public static implicit operator Vector2(OffsetAnchor a) => a.v; public OffsetAnchor Offset(float x, float y) { v.X += x; v.Y += y; return this; } public OffsetAnchor Offset(Vector2 _v) { v += _v; return this; } internal void Set(Vector2 vector2) => v = vector2; #endregion Methods } }