ZodiacFinder/Plugin.cs

189 lines
6.2 KiB
C#
Raw Permalink Normal View History

2024-05-28 23:20:15 +00:00
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using ImGuiNET;
using System;
using System.Collections.Generic;
using System.Numerics;
using Dalamud.Interface.Utility;
using Dalamud.Plugin.Services;
namespace ZodiacFinder
{
public class Plugin : IDalamudPlugin
{
2024-05-28 23:23:54 +00:00
private readonly DalamudPluginInterface _pluginInterface;
private readonly IClientState _clientState;
private readonly IObjectTable _objectTable;
private readonly IDataManager _dataManager;
private readonly IGameGui _gameGui;
2024-05-28 23:20:15 +00:00
2024-05-28 23:23:54 +00:00
private readonly IDictionary<uint, Book> _books = new Dictionary<uint, Book>();
2024-05-28 23:20:15 +00:00
2024-05-28 23:23:54 +00:00
private readonly ISet<uint> _atmaWeapons = new HashSet<uint> {
2024-05-28 23:20:15 +00:00
7824, // Curtana Atma
7825, // Sphairai Atma
7826, // Bravura Atma
7827, // Gae Bolg Atma
7828, // Artemis Bow Atma
7829, // Thyrus Atma
7830, // Stardust Rod Atma
7831, // Veil of Wiyu Atma
7832, // Omnilex Atma
7833, // Holy Shield Atma
9251, // Yoshimitsu Atma
};
public Plugin(
DalamudPluginInterface pi,
IChatGui chat,
IClientState clientState,
IObjectTable objectTable,
IDataManager dataManager,
IGameGui gameGui)
{
2024-05-28 23:23:54 +00:00
this._pluginInterface = pi;
this._clientState = clientState;
this._objectTable = objectTable;
this._dataManager = dataManager;
this._gameGui = gameGui;
2024-05-28 23:20:15 +00:00
2024-05-28 23:23:54 +00:00
this._pluginInterface.UiBuilder.Draw += this.Draw;
2024-05-28 23:20:15 +00:00
this.PopulateBooks();
}
#region IDisposable Support
protected virtual void Dispose(bool disposing)
{
if (!disposing) return;
2024-05-28 23:23:54 +00:00
this._pluginInterface.UiBuilder.Draw -= this.Draw;
2024-05-28 23:20:15 +00:00
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
private unsafe void Draw()
{
2024-05-28 23:23:54 +00:00
if (!_clientState.IsLoggedIn || _clientState.IsPvP || _objectTable == null || !HasAtmaWeaponEquipped())
2024-05-28 23:20:15 +00:00
return;
var bookId = GetCurrentBook();
if (bookId == 0)
return;
var relicNote = RelicNote.Instance();
if (relicNote == null)
return;
2024-05-28 23:23:54 +00:00
var book = _books[bookId];
for (int index = 0; index < _objectTable.Length; ++index)
2024-05-28 23:20:15 +00:00
{
2024-05-28 23:23:54 +00:00
GameObject obj = _objectTable[index];
2024-05-28 23:20:15 +00:00
if (!(obj is BattleNpc npc) || npc.CurrentHp == 0)
continue;
var indexInBook = book.Enemies.IndexOf(npc.NameId);
if (indexInBook == -1)
continue;
if (relicNote->GetMonsterProgress(indexInBook) >= 3)
continue;
2024-05-28 23:23:54 +00:00
if (!_gameGui.WorldToScreen(new Vector3(obj.Position.X, obj.Position.Y, obj.Position.Z), out var pos))
2024-05-28 23:20:15 +00:00
continue;
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(0, 0));
ImGuiHelpers.ForceNextWindowMainViewport();
ImGuiHelpers.SetNextWindowPosRelativeMainViewport(new Vector2(0, 0));
ImGui.Begin($"zodiac###{index}",
ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoTitleBar |
ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoSavedSettings);
ImGui.SetWindowSize(ImGui.GetIO().DisplaySize);
ImGui.GetWindowDrawList().AddCircleFilled(new Vector2(pos.X, pos.Y), 5f, ImGui.GetColorU32(0xff0000ff), 100);
//ImGui.GetWindowDrawList().AddText(new Vector2(pos.X, pos.Y), ImGui.GetColorU32(0xffffffff), $"{npc.NameId} - {obj.Name.TextValue}");
ImGui.End();
ImGui.PopStyleVar();
}
}
private bool HasAtmaWeaponEquipped()
{
2024-05-28 23:23:54 +00:00
return _atmaWeapons.Contains(GetEquippedItem(0)) || _atmaWeapons.Contains(GetEquippedItem(1));
2024-05-28 23:20:15 +00:00
}
private unsafe uint GetCurrentBook()
{
var im = InventoryManager.Instance();
if (im == null)
return 0;
var keyItems = im->GetInventoryContainer(InventoryType.KeyItems);
for (int i = 0; i < keyItems->Size; ++i)
{
var slot = keyItems->GetInventorySlot(i);
if (slot == null)
continue;
uint itemId = slot->ItemID;
2024-05-28 23:23:54 +00:00
if (_books.ContainsKey(itemId))
2024-05-28 23:20:15 +00:00
return itemId;
}
return 0;
}
private unsafe uint GetEquippedItem(int index)
{
var im = InventoryManager.Instance();
if (im == null)
return 0;
var equipped = im->GetInventoryContainer(InventoryType.EquippedItems);
if (equipped == null)
return 0;
var slot = equipped->GetInventorySlot(index);
if (slot == null)
return 0;
return slot->ItemID;
}
private void PopulateBooks()
{
2024-05-28 23:23:54 +00:00
var relicNoteSheet = this._dataManager.GetExcelSheet<Excel.RelicNote>()!;
2024-05-28 23:20:15 +00:00
foreach (var row in relicNoteSheet)
{
if (row.EventItem == null || row.EventItem.Row == 0)
continue;
var book = new Book();
for (int i = 0; i < row.MonsterNoteTargetCommon.Length; i++)
{
book.Enemies.Add(row.MonsterNoteTargetCommon[i].MonsterNoteTargetCommon.Value!.BNpcName.Row);
}
//chat.Print($"{row.EventItem.Row} - {book}");
2024-05-28 23:23:54 +00:00
_books.Add(row.EventItem.Row, book);
2024-05-28 23:20:15 +00:00
}
}
internal sealed class Book
{
public IList<uint> Enemies = new List<uint>();
public override string ToString()
{
return string.Join(",", Enemies);
}
}
}
}