using System.Numerics; using Dalamud.Data; using Dalamud.Game.ClientState.Resolvers; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Memory; namespace Dalamud.Game.ClientState.Fates; /// /// This class represents an FFXIV Fate. /// public unsafe partial class Fate : IEquatable { /// /// Initializes a new instance of the class. /// /// The address of this fate in memory. internal Fate(IntPtr address) { this.Address = address; } /// /// Gets the address of this Fate in memory. /// public IntPtr Address { get; } private FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext*)this.Address; public static bool operator ==(Fate fate1, Fate fate2) { if (fate1 is null || fate2 is null) return Equals(fate1, fate2); return fate1.Equals(fate2); } public static bool operator !=(Fate fate1, Fate fate2) => !(fate1 == fate2); /// /// Gets a value indicating whether this Fate is still valid in memory. /// /// The fate to check. /// True or false. public static bool IsValid(Fate fate) { var clientState = Service.GetNullable(); if (fate == null || clientState == null) return false; if (clientState.LocalContentId == 0) return false; return true; } /// /// Gets a value indicating whether this actor is still valid in memory. /// /// True or false. public bool IsValid() => IsValid(this); /// bool IEquatable.Equals(Fate other) => this.FateId == other?.FateId; /// public override bool Equals(object obj) => ((IEquatable)this).Equals(obj as Fate); /// public override int GetHashCode() => this.FateId.GetHashCode(); } /// /// This class represents an FFXIV Fate. /// public unsafe partial class Fate { /// /// Gets the Fate ID of this . /// public ushort FateId => this.Struct->FateId; /// /// Gets game data linked to this Fate. /// public Lumina.Excel.GeneratedSheets.Fate GameData => Service.Get().GetExcelSheet().GetRow(this.FateId); /// /// Gets the time this started. /// public int StartTimeEpoch => this.Struct->StartTimeEpoch; /// /// Gets how long this will run. /// public short Duration => this.Struct->Duration; /// /// Gets the remaining time in seconds for this . /// public long TimeRemaining => this.StartTimeEpoch + this.Duration - DateTimeOffset.Now.ToUnixTimeSeconds(); /// /// Gets the displayname of this . /// public SeString Name => MemoryHelper.ReadSeString(&this.Struct->Name); /// /// Gets the state of this (Running, Ended, Failed, Preparation, WaitingForEnd). /// public FateState State => (FateState)this.Struct->State; /// /// Gets the progress amount of this . /// public byte Progress => this.Struct->Progress; /// /// Gets the level of this . /// public byte Level => this.Struct->Level; /// /// Gets the position of this . /// public Vector3 Position => this.Struct->Location; /// /// Gets the territory this is located in. /// public ExcelResolver TerritoryType => new(this.Struct->TerritoryId); }