Initial commit
This commit is contained in:
14 files changed
+1260
No files matched your search
@@ -0,0 +1,19 @@
|
||||
using Dalamud.Configuration;
|
||||
using System;
|
||||
|
||||
namespace SamplePlugin;
|
||||
|
||||
[Serializable]
|
||||
public class Configuration : IPluginConfiguration
|
||||
{
|
||||
public int Version { get; set; } = 0;
|
||||
|
||||
public bool IsConfigWindowMovable { get; set; } = true;
|
||||
public bool SomePropertyToBeSavedAndWithADefault { get; set; } = true;
|
||||
|
||||
// The below exists just to make saving less cumbersome
|
||||
public void Save()
|
||||
{
|
||||
Plugin.PluginInterface.SavePluginConfig(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.Plugin;
|
||||
using System.IO;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Plugin.Services;
|
||||
using SamplePlugin.Windows;
|
||||
|
||||
namespace SamplePlugin;
|
||||
|
||||
public sealed class Plugin : IDalamudPlugin
|
||||
{
|
||||
[PluginService] internal static IDalamudPluginInterface PluginInterface { get; private set; } = null!;
|
||||
[PluginService] internal static ITextureProvider TextureProvider { get; private set; } = null!;
|
||||
[PluginService] internal static ICommandManager CommandManager { get; private set; } = null!;
|
||||
[PluginService] internal static IClientState ClientState { get; private set; } = null!;
|
||||
[PluginService] internal static IPlayerState PlayerState { get; private set; } = null!;
|
||||
[PluginService] internal static IDataManager DataManager { get; private set; } = null!;
|
||||
[PluginService] internal static IPluginLog Log { get; private set; } = null!;
|
||||
|
||||
private const string CommandName = "/pmycommand";
|
||||
|
||||
public Configuration Configuration { get; init; }
|
||||
|
||||
public readonly WindowSystem WindowSystem = new("SamplePlugin");
|
||||
private ConfigWindow ConfigWindow { get; init; }
|
||||
private MainWindow MainWindow { get; init; }
|
||||
|
||||
public Plugin()
|
||||
{
|
||||
Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
|
||||
// You might normally want to embed resources and load them from the manifest stream
|
||||
var goatImagePath = Path.Combine(PluginInterface.AssemblyLocation.Directory?.FullName!, "goat.png");
|
||||
|
||||
ConfigWindow = new ConfigWindow(this);
|
||||
MainWindow = new MainWindow(this, goatImagePath);
|
||||
|
||||
WindowSystem.AddWindow(ConfigWindow);
|
||||
WindowSystem.AddWindow(MainWindow);
|
||||
|
||||
CommandManager.AddHandler(CommandName, new CommandInfo(OnCommand)
|
||||
{
|
||||
HelpMessage = "A useful message to display in /xlhelp"
|
||||
});
|
||||
|
||||
// Tell the UI system that we want our windows to be drawn through the window system
|
||||
PluginInterface.UiBuilder.Draw += WindowSystem.Draw;
|
||||
|
||||
// This adds a button to the plugin installer entry of this plugin which allows
|
||||
// toggling the display status of the configuration ui
|
||||
PluginInterface.UiBuilder.OpenConfigUi += ToggleConfigUi;
|
||||
|
||||
// Adds another button doing the same but for the main ui of the plugin
|
||||
PluginInterface.UiBuilder.OpenMainUi += ToggleMainUi;
|
||||
|
||||
// Add a simple message to the log with level set to information
|
||||
// Use /xllog to open the log window in-game
|
||||
// Example Output: 00:57:54.959 | INF | [SamplePlugin] ===A cool log message from Sample Plugin===
|
||||
Log.Information($"===A cool log message from {PluginInterface.Manifest.Name}===");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Unregister all actions to not leak anything during disposal of plugin
|
||||
PluginInterface.UiBuilder.Draw -= WindowSystem.Draw;
|
||||
PluginInterface.UiBuilder.OpenConfigUi -= ToggleConfigUi;
|
||||
PluginInterface.UiBuilder.OpenMainUi -= ToggleMainUi;
|
||||
|
||||
WindowSystem.RemoveAllWindows();
|
||||
|
||||
ConfigWindow.Dispose();
|
||||
MainWindow.Dispose();
|
||||
|
||||
CommandManager.RemoveHandler(CommandName);
|
||||
}
|
||||
|
||||
private void OnCommand(string command, string args)
|
||||
{
|
||||
// In response to the slash command, toggle the display status of our main ui
|
||||
MainWindow.Toggle();
|
||||
}
|
||||
|
||||
public void ToggleConfigUi() => ConfigWindow.Toggle();
|
||||
public void ToggleMainUi() => MainWindow.Toggle();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Dalamud.NET.Sdk/14.0.1">
|
||||
<PropertyGroup>
|
||||
<Version>0.0.0.1</Version>
|
||||
<PackageProjectUrl>https://github.com/goatcorp/SamplePlugin</PackageProjectUrl>
|
||||
<PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\Data\goat.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<Visible>false</Visible>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"Author": "your name here",
|
||||
"Name": "Sample Plugin",
|
||||
"Punchline": "A short one-liner that shows up in /xlplugins.",
|
||||
"Description": "A description that shows up in /xlplugins. List any major slash-command(s).",
|
||||
"ApplicableVersion": "any",
|
||||
"Tags": [
|
||||
"sample",
|
||||
"plugin",
|
||||
"goats"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Windowing;
|
||||
|
||||
namespace SamplePlugin.Windows;
|
||||
|
||||
public class ConfigWindow : Window, IDisposable
|
||||
{
|
||||
private readonly Configuration configuration;
|
||||
|
||||
// We give this window a constant ID using ###.
|
||||
// This allows for labels to be dynamic, like "{FPS Counter}fps###XYZ counter window",
|
||||
// and the window ID will always be "###XYZ counter window" for ImGui
|
||||
public ConfigWindow(Plugin plugin) : base("A Wonderful Configuration Window###With a constant ID")
|
||||
{
|
||||
Flags = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar |
|
||||
ImGuiWindowFlags.NoScrollWithMouse;
|
||||
|
||||
Size = new Vector2(232, 90);
|
||||
SizeCondition = ImGuiCond.Always;
|
||||
|
||||
configuration = plugin.Configuration;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public override void PreDraw()
|
||||
{
|
||||
// Flags must be added or removed before Draw() is being called, or they won't apply
|
||||
if (configuration.IsConfigWindowMovable)
|
||||
{
|
||||
Flags &= ~ImGuiWindowFlags.NoMove;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags |= ImGuiWindowFlags.NoMove;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
// Can't ref a property, so use a local copy
|
||||
var configValue = configuration.SomePropertyToBeSavedAndWithADefault;
|
||||
if (ImGui.Checkbox("Random Config Bool", ref configValue))
|
||||
{
|
||||
configuration.SomePropertyToBeSavedAndWithADefault = configValue;
|
||||
// Can save immediately on change if you don't want to provide a "Save and Close" button
|
||||
configuration.Save();
|
||||
}
|
||||
|
||||
var movable = configuration.IsConfigWindowMovable;
|
||||
if (ImGui.Checkbox("Movable Config Window", ref movable))
|
||||
{
|
||||
configuration.IsConfigWindowMovable = movable;
|
||||
configuration.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Lumina.Excel.Sheets;
|
||||
|
||||
namespace SamplePlugin.Windows;
|
||||
|
||||
public class MainWindow : Window, IDisposable
|
||||
{
|
||||
private readonly string goatImagePath;
|
||||
private readonly Plugin plugin;
|
||||
|
||||
// We give this window a hidden ID using ##.
|
||||
// The user will see "My Amazing Window" as window title,
|
||||
// but for ImGui the ID is "My Amazing Window##With a hidden ID"
|
||||
public MainWindow(Plugin plugin, string goatImagePath)
|
||||
: base("My Amazing Window##With a hidden ID", ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)
|
||||
{
|
||||
SizeConstraints = new WindowSizeConstraints
|
||||
{
|
||||
MinimumSize = new Vector2(375, 330),
|
||||
MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
|
||||
};
|
||||
|
||||
this.goatImagePath = goatImagePath;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
ImGui.Text($"The random config bool is {plugin.Configuration.SomePropertyToBeSavedAndWithADefault}");
|
||||
|
||||
if (ImGui.Button("Show Settings"))
|
||||
{
|
||||
plugin.ToggleConfigUi();
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
// Normally a BeginChild() would have to be followed by an unconditional EndChild(),
|
||||
// ImRaii takes care of this after the scope ends.
|
||||
// This works for all ImGui functions that require specific handling, examples are BeginTable() or Indent().
|
||||
using (var child = ImRaii.Child("SomeChildWithAScrollbar", Vector2.Zero, true))
|
||||
{
|
||||
// Check if this child is drawing
|
||||
if (child.Success)
|
||||
{
|
||||
ImGui.Text("Have a goat:");
|
||||
var goatImage = Plugin.TextureProvider.GetFromFile(goatImagePath).GetWrapOrDefault();
|
||||
if (goatImage != null)
|
||||
{
|
||||
using (ImRaii.PushIndent(55f))
|
||||
{
|
||||
ImGui.Image(goatImage.Handle, goatImage.Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("Image not found.");
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(20.0f);
|
||||
|
||||
// Example for other services that Dalamud provides.
|
||||
// PlayerState provides a wrapper filled with information about the player character.
|
||||
|
||||
var playerState = Plugin.PlayerState;
|
||||
if (!playerState.IsLoaded)
|
||||
{
|
||||
ImGui.Text("Our local player is currently not logged in.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playerState.ClassJob.IsValid)
|
||||
{
|
||||
ImGui.Text("Our current job is currently not valid.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If you want to see the Macro representation of this SeString use `.ToMacroString()`
|
||||
// More info about SeStrings: https://dalamud.dev/plugin-development/sestring/
|
||||
ImGui.Text($"Our current job is ({playerState.ClassJob.RowId}) '{playerState.ClassJob.Value.Abbreviation}' with level {playerState.Level}");
|
||||
|
||||
// Example for querying Lumina, getting the name of our current area.
|
||||
var territoryId = Plugin.ClientState.TerritoryType;
|
||||
if (Plugin.DataManager.GetExcelSheet<TerritoryType>().TryGetRow(territoryId, out var territoryRow))
|
||||
{
|
||||
ImGui.Text($"We are currently in ({territoryId}) '{territoryRow.PlaceName.Value.Name}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("Invalid territory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net10.0-windows7.0": {
|
||||
"DalamudPackager": {
|
||||
"type": "Direct",
|
||||
"requested": "[14.0.1, )",
|
||||
"resolved": "14.0.1",
|
||||
"contentHash": "y0WWyUE6dhpGdolK3iKgwys05/nZaVf4ZPtIjpLhJBZvHxkkiE23zYRo7K7uqAgoK/QvK5cqF6l3VG5AbgC6KA=="
|
||||
},
|
||||
"DotNet.ReproducibleBuilds": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.39, )",
|
||||
"resolved": "1.2.39",
|
||||
"contentHash": "fcFN01tDTIQqDuTwr1jUQK/geofiwjG5DycJQOnC72i1SsLAk1ELe+apBOuZ11UMQG8YKFZG1FgvjZPbqHyatg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user