FFXIVで戦闘系エンドコンテンツを攻略する人にとってはおなじみのAdvanced Combat Tracker(以下ACT)という便利ツールがあります。
C#でプラグインを自分で作ってインポートできるようになっているのですが、 プラグインを作る際のHOWTOを探してみたらヒットする記事が古かったので、令和版ACTプラグインの作り方をまとめました。
準備
以下をインストールします。
- ACT本体
- Visual Studio 2019
- .NET Framwork 4.7.2 Developper Pack
Visual Studio Installerで.NETデスクトップ開発をインストールします。
- ACTでFFXIV_ACT_Plugin.dllをインポートしておきます。
プロジェクト作成
Visual Studioで新規にプロジェクトを作成します。プロジェクトのテンプレートは.NET Frameworkのクラスライブラリを選択します。
プロジェクトにユーザーコントロールを追加し、インターフェースIActPluginV1を実装して必要なメソッドを追加します。
ここまで実装したコード。ACTでプラグインをインポートしたときにInitPluginが呼ばれ、プラグインを無効化したり削除したりするとDeInitPluginが呼ばれます。
using Advanced_Combat_Tracker; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ActPluginSample { public class SampleUserControl : UserControl, IActPluginV1 { public void DeInitPlugin() { } public void InitPlugin(TabPage pluginScreenSpace, Label pluginStatusText) { } } }
いったんビルドして、dllを出力しておきます。
ACTでインポートしてみる
ビルドしてできたdllをインポートしてみます。Pluginのタブの中に新しく追加され、選択するとまっさらな画面が表示されます。
デバッグ実行できるようにする
クラスライブラリのプロジェクトはそのままではデバッグ実行できないので、 デバッグ実行の開始とともにACT本体が起動するようにします。 プロジェクトのプロパティを開き、デバッグ→外部プログラムの開始からProgram Files(x86)以下にインストールされたAdvancedCombatTracker.exeを選択します。 これでデバッグ実行を開始すると、ACTが起動し、プラグインのデバッグができるようになります。
ユーザーコントロールをいじってみる
さっき追加したSampleUserControlにコンポーネントを追加してみます。後でいろいろデータを表示したいのでButtonとDataGridViewを置いてみます。DataGridViewにはPlayerNameとHpのカラムを追加しておきます。
FFXIVActPluginのAPIを呼んでみる
↓からFFXIVACTPluginのSDKをダウンロードします。今回はFFXIV_ACT_Plugin_SDK_2.0.2.3.zipを使いました。 zipを解凍するといろいろdllが入っていますが、このサンプルではFFXIV_ACT_Plugin.Common.dllのみ使います。
プログラムからACTやFFXIVACTPluginのAPIを呼べるようにするため、ACT本体のexeとさきほどダウンロードしたFFXIV_ACT_Plugin.Common.dllを追加します。これらはプロジェクト内に適当なフォルダを作って入れておくと良さそうです。
ActGlobals.oFormActMain.ActPluginsでACTに読み込まれているプラグインのコレクションが取得できます。 その中からプラグイン名、プラグインの状態などでフィルターしてFFXIVACTPluginを取得します。
var xviPlugin = ActGlobals.oFormActMain.ActPlugins .Where(plugin => plugin.pluginFile.Name.Equals("FFXIV_ACT_Plugin.dll", StringComparison.OrdinalIgnoreCase)) .Where(plugin => plugin.lblPluginStatus.Text.Equals("FFXIV Plugin Started.", StringComparison.OrdinalIgnoreCase)) .FirstOrDefault() ?.pluginObj;
FFXIVPluginが取得できたら、その中からDataRepositoryというプロパティを取得します。DataRepositoryからプレイヤーの名前やHPなどの情報が取得できます。
var dataRepository = xviPlugin.GetType().GetProperty("DataRepository").GetValue(xviPlugin, null) as IDataRepository;
DataRepositoryのGetComatantListというメソッドを呼ぶと今いるフィールド上に存在するプレイヤーやNPCなどの情報のコレクションが取得できます。↓ではその中からPartyTypeでフィルターしてパーティメンバーを取得します。
var partyCombatantList = dataRepository.GetCombatantList() .Where(combatant => combatant.PartyType == PartyTypeEnum.Party) .ToList();
これでゲーム内の情報が取得できるようになりました。 さきほど作ったユーザーコントロールと組み合わせて、ボタンを押したらPTメンバーの情報をDataGridViewに表示してみます。
using Advanced_Combat_Tracker; using FFXIV_ACT_Plugin.Common; using FFXIV_ACT_Plugin.Common.Models; using System; using System.Data; using System.Linq; using System.Windows.Forms; namespace ActPluginSample { public partial class SamplePluginUserControl : UserControl, IActPluginV1 { public SamplePluginUserControl() { InitializeComponent(); } public void DeInitPlugin() { } public void InitPlugin(TabPage pluginScreenSpace, Label pluginStatusText) { pluginScreenSpace.Controls.Add(this); this.Dock = DockStyle.Fill; } private void loadButton_Click(object sender, EventArgs e) { var xviPlugin = ActGlobals.oFormActMain.ActPlugins .Where(plugin => plugin.pluginFile.Name.Equals("FFXIV_ACT_Plugin.dll", StringComparison.OrdinalIgnoreCase)) .Where(plugin => plugin.lblPluginStatus.Text.Equals("FFXIV Plugin Started.", StringComparison.OrdinalIgnoreCase)) .FirstOrDefault() ?.pluginObj; var dataRepository = xviPlugin.GetType().GetProperty("DataRepository").GetValue(xviPlugin, null) as IDataRepository; var partyCombatantList = dataRepository.GetCombatantList() .Where(combatant => combatant.PartyType == PartyTypeEnum.Party) .ToList(); partyGridView.Rows.Clear(); foreach (var combatant in partyCombatantList) { partyGridView.Rows.Add(combatant.Name, combatant.CurrentHP); } } } }
実際にゲームを起動して、パーティを組んだ状態でLoadボタンを押してみると、プレイヤー名とHpが取得できました。
今回のサンプルではプレイヤー名とHpを表示するだけでしたが、他にもいろいろなAPIが用意されているので、もっと便利な機能とかも作れそうです。 APIの仕様とかは↓のプラグインのソースがけっこう参考になりました。