PalacePal/Pal.Client/Rendering/SplatoonRenderer.cs

196 lines
6.2 KiB
C#
Raw Normal View History

2023-03-26 13:47:18 +00:00
using System;
2023-02-08 15:06:43 +00:00
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Reflection;
2023-03-26 13:47:18 +00:00
using Dalamud.Plugin;
2023-10-03 09:08:38 +00:00
using Dalamud.Plugin.Services;
2023-03-26 13:47:18 +00:00
using ECommons;
using ECommons.Reflection;
using ECommons.Schedulers;
using ECommons.SplatoonAPI;
using Microsoft.Extensions.Logging;
using Pal.Client.Configuration;
2023-02-15 22:17:19 +00:00
using Pal.Client.DependencyInjection;
2023-02-18 20:12:36 +00:00
using Pal.Client.Floors;
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
namespace Pal.Client.Rendering;
internal sealed class SplatoonRenderer : IRenderer, IDisposable
2023-02-08 15:06:43 +00:00
{
2023-03-30 20:01:43 +00:00
private const long OnTerritoryChange = -2;
private readonly ILogger<SplatoonRenderer> _logger;
private readonly DebugState _debugState;
2023-10-03 09:08:38 +00:00
private readonly IClientState _clientState;
2023-03-30 20:01:43 +00:00
private readonly Chat _chat;
public SplatoonRenderer(
ILogger<SplatoonRenderer> logger,
DalamudPluginInterface pluginInterface,
IDalamudPlugin dalamudPlugin,
DebugState debugState,
2023-10-03 09:08:38 +00:00
IClientState clientState,
2023-03-30 20:01:43 +00:00
Chat chat)
2023-02-08 15:06:43 +00:00
{
2023-03-30 20:01:43 +00:00
_logger = logger;
_debugState = debugState;
_clientState = clientState;
_chat = chat;
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
_logger.LogInformation("Initializing splatoon");
ECommonsMain.Init(pluginInterface, dalamudPlugin, ECommons.Module.SplatoonAPI);
}
2023-02-15 22:17:19 +00:00
2023-03-30 20:01:43 +00:00
private bool IsDisposed { get; set; }
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
public void SetLayer(ELayer layer, IReadOnlyList<IRenderElement> elements)
{
// we need to delay this, as the current framework update could be before splatoon's, in which case it would immediately delete the layout
_ = new TickScheduler(delegate
2023-02-08 15:06:43 +00:00
{
try
{
2023-03-30 20:01:43 +00:00
Splatoon.AddDynamicElements(ToLayerName(layer),
elements.Cast<SplatoonElement>().Select(x => x.Delegate).ToArray(),
new[] { Environment.TickCount64 + 60 * 60 * 1000, OnTerritoryChange });
2023-02-08 15:06:43 +00:00
}
catch (Exception e)
{
2023-03-30 20:01:43 +00:00
_logger.LogError(e, "Could not create splatoon layer {Layer} with {Count} elements", layer,
elements.Count);
_debugState.SetFromException(e);
2023-02-08 15:06:43 +00:00
}
2023-03-30 20:01:43 +00:00
});
}
public void ResetLayer(ELayer layer)
{
try
{
Splatoon.RemoveDynamicElements(ToLayerName(layer));
}
catch (Exception e)
{
_logger.LogError(e, "Could not reset splatoon layer {Layer}", layer);
2023-02-08 15:06:43 +00:00
}
2023-03-30 20:01:43 +00:00
}
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
private string ToLayerName(ELayer layer)
=> $"PalacePal.{layer}";
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
public IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, uint color, bool fill = false)
{
MarkerConfig config = MarkerConfig.ForType(type);
Element element = new Element(ElementType.CircleAtFixedCoordinates)
2023-02-08 15:06:43 +00:00
{
2023-03-30 20:01:43 +00:00
refX = pos.X,
refY = pos.Z, // z and y are swapped
refZ = pos.Y,
offX = 0,
offY = 0,
offZ = config.OffsetY,
Filled = fill,
radius = config.Radius,
FillStep = 1,
color = color,
thicc = 2,
};
return new SplatoonElement(this, element);
}
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
public void DrawDebugItems(uint trapColor, uint hoardColor)
{
try
2023-02-08 15:06:43 +00:00
{
2023-03-30 20:01:43 +00:00
Vector3? pos = _clientState.LocalPlayer?.Position;
if (pos != null)
2023-02-08 15:06:43 +00:00
{
2023-03-30 20:01:43 +00:00
ResetLayer(ELayer.Test);
2023-03-30 20:01:43 +00:00
var elements = new List<IRenderElement>
{
CreateElement(MemoryLocation.EType.Trap, pos.Value, trapColor),
CreateElement(MemoryLocation.EType.Hoard, pos.Value, hoardColor),
};
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
if (!Splatoon.AddDynamicElements(ToLayerName(ELayer.Test),
elements.Cast<SplatoonElement>().Select(x => x.Delegate).ToArray(),
new[] { Environment.TickCount64 + RenderData.TestLayerTimeout }))
{
_chat.Message("Could not draw markers :(");
2023-02-08 15:06:43 +00:00
}
}
2023-03-30 20:01:43 +00:00
}
catch (Exception)
{
try
2023-02-08 15:06:43 +00:00
{
2023-03-30 20:01:43 +00:00
var pluginManager = DalamudReflector.GetPluginManager();
IList installedPlugins =
pluginManager.GetType().GetProperty("InstalledPlugins")?.GetValue(pluginManager) as IList ??
new List<object>();
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
foreach (var t in installedPlugins)
{
AssemblyName? assemblyName =
(AssemblyName?)t.GetType().GetProperty("AssemblyName")?.GetValue(t);
string? pluginName = (string?)t.GetType().GetProperty("Name")?.GetValue(t);
if (assemblyName?.Name == "Splatoon" && pluginName != "Splatoon")
2023-02-08 15:06:43 +00:00
{
2023-03-30 20:01:43 +00:00
_chat.Error(
$"Splatoon is installed under the plugin name '{pluginName}', which is incompatible with the Splatoon API.");
_chat.Message(
"You need to install Splatoon from the official repository at https://github.com/NightmareXIV/MyDalamudPlugins.");
return;
2023-02-08 15:06:43 +00:00
}
}
}
2023-03-30 20:01:43 +00:00
catch (Exception)
{
// not relevant
}
_chat.Error("Could not draw markers, is Splatoon installed and enabled?");
2023-02-08 15:06:43 +00:00
}
2023-03-30 20:01:43 +00:00
}
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
public ERenderer GetConfigValue()
=> ERenderer.Splatoon;
2023-03-30 20:01:43 +00:00
public void Dispose()
{
_logger.LogInformation("Disposing splatoon");
2023-03-30 20:01:43 +00:00
IsDisposed = true;
2023-03-30 20:01:43 +00:00
ResetLayer(ELayer.TrapHoard);
ResetLayer(ELayer.RegularCoffers);
ResetLayer(ELayer.Test);
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
ECommonsMain.Dispose();
}
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
private sealed class SplatoonElement : IRenderElement
{
private readonly SplatoonRenderer _renderer;
2023-03-30 20:01:43 +00:00
public SplatoonElement(SplatoonRenderer renderer, Element element)
{
_renderer = renderer;
Delegate = element;
}
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
public Element Delegate { get; }
2023-02-08 15:06:43 +00:00
2023-03-30 20:01:43 +00:00
public bool IsValid => !_renderer.IsDisposed && Delegate.IsValid();
2023-02-15 22:17:19 +00:00
2023-03-30 20:01:43 +00:00
public uint Color
{
get => Delegate.color;
set => Delegate.color = value;
2023-02-08 15:06:43 +00:00
}
}
}