add vbm as a combatmodule
authorJackson <9527380+Jaksuhn@users.noreply.github.com>
Thu, 19 Dec 2024 15:41:17 +0000 (16:41 +0100)
committerJackson <9527380+Jaksuhn@users.noreply.github.com>
Thu, 19 Dec 2024 15:41:17 +0000 (16:41 +0100)
Questionable/Controller/CombatModules/BossModModule.cs [new file with mode: 0644]
Questionable/Controller/CombatModules/BossModPreset.json [new file with mode: 0644]
Questionable/Questionable.csproj
Questionable/QuestionablePlugin.cs

diff --git a/Questionable/Controller/CombatModules/BossModModule.cs b/Questionable/Controller/CombatModules/BossModModule.cs
new file mode 100644 (file)
index 0000000..0d04cce
--- /dev/null
@@ -0,0 +1,117 @@
+using Dalamud.Game.ClientState.Objects.Types;
+using Dalamud.Plugin;
+using Dalamud.Plugin.Ipc;
+using Dalamud.Plugin.Ipc.Exceptions;
+using Dalamud.Plugin.Services;
+using Microsoft.Extensions.Logging;
+using Questionable.Model;
+using System;
+using System.IO;
+using System.Numerics;
+
+namespace Questionable.Controller.CombatModules;
+
+internal sealed class BossModModule(ILogger<BossModModule> logger, MovementController movementController, IClientState clientState, IDalamudPluginInterface pluginInterface) : ICombatModule, IDisposable
+{
+    private const string Name = "BossMod";
+    private readonly ILogger<BossModModule> _logger = logger;
+    private readonly MovementController _movementController = movementController;
+    private readonly IClientState _clientState = clientState;
+    private readonly ICallGateSubscriber<string, string?> _getPreset = pluginInterface.GetIpcSubscriber<string, string?>($"{Name}.Presets.Get");
+    private readonly ICallGateSubscriber<string, bool, bool> _createPreset = pluginInterface.GetIpcSubscriber<string, bool, bool>($"{Name}.Presets.Create");
+    private readonly ICallGateSubscriber<string, bool> _setPreset = pluginInterface.GetIpcSubscriber<string, bool>($"{Name}.Presets.SetActive");
+    private readonly ICallGateSubscriber<bool> _clearPreset = pluginInterface.GetIpcSubscriber<bool>($"{Name}.Presets.ClearActive");
+
+    private DateTime _lastDistanceCheck = DateTime.MinValue;
+
+    public bool CanHandleFight(CombatController.CombatData combatData)
+    {
+        try
+        {
+            return _getPreset.HasFunction;
+        }
+        catch (IpcError)
+        {
+            return false;
+        }
+    }
+
+    public bool Start(CombatController.CombatData combatData)
+    {
+        try
+        {
+            _logger.LogInformation("Starting {Name}", Name);
+            var path = Path.Combine(pluginInterface.AssemblyLocation.DirectoryName!, @"Controller\CombatModules\BossModPreset.json");
+            if (_getPreset.InvokeFunc("Questionable") == null)
+                _logger.LogInformation("Loading Questionable BossMod Preset: {LoadedState}", _createPreset.InvokeFunc(File.ReadAllText(path), true));
+            _setPreset.InvokeFunc("Questionable");
+            _lastDistanceCheck = DateTime.Now;
+            return true;
+        }
+        catch (IpcError e)
+        {
+            _logger.LogWarning(e, "Could not start combat");
+            return false;
+        }
+    }
+
+    public bool Stop()
+    {
+        try
+        {
+            _clearPreset.InvokeFunc();
+            return true;
+        }
+        catch (IpcError e)
+        {
+            _logger.LogWarning(e, "Could not turn off combat");
+            return false;
+        }
+    }
+
+    public void MoveToTarget(IGameObject gameObject)
+    {
+        var player = _clientState.LocalPlayer;
+        if (player == null)
+            return; // uh oh
+
+        float hitboxOffset = player.HitboxRadius + gameObject.HitboxRadius;
+        float actualDistance = Vector3.Distance(player.Position, gameObject.Position);
+        float maxDistance = player.ClassJob.ValueNullable?.Role is 3 or 4 ? 20f : 2.9f;
+        if (actualDistance - hitboxOffset >= maxDistance)
+        {
+            if (actualDistance - hitboxOffset <= 5)
+            {
+                _logger.LogInformation("Moving to {TargetName} ({DataId}) to attack", gameObject.Name,
+                    gameObject.DataId);
+                _movementController.NavigateTo(EMovementType.Combat, null, [gameObject.Position], false, false,
+                    maxDistance + hitboxOffset - 0.25f, true);
+            }
+            else
+            {
+                _logger.LogInformation("Moving to {TargetName} ({DataId}) to attack (with navmesh)", gameObject.Name,
+                    gameObject.DataId);
+                _movementController.NavigateTo(EMovementType.Combat, null, gameObject.Position, false, false,
+                    maxDistance + hitboxOffset - 0.25f, true);
+            }
+        }
+
+        _lastDistanceCheck = DateTime.Now;
+    }
+
+    public void Update(IGameObject gameObject)
+    {
+        if (_movementController.IsPathfinding || _movementController.IsPathRunning)
+            return;
+
+        if (DateTime.Now > _lastDistanceCheck.AddSeconds(10))
+        {
+            MoveToTarget(gameObject);
+            _lastDistanceCheck = DateTime.Now;
+        }
+    }
+
+    public bool CanAttack(IBattleNpc target) => true;
+
+    public void Dispose() => Stop();
+}
diff --git a/Questionable/Controller/CombatModules/BossModPreset.json b/Questionable/Controller/CombatModules/BossModPreset.json
new file mode 100644 (file)
index 0000000..b6c6a28
--- /dev/null
@@ -0,0 +1,377 @@
+{
+  "Name": "Questionable",
+  "Modules": {
+    "BossMod.Autorotation.xan.DNC": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.MCH": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.MNK": [
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.PCT": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      },
+      {
+        "Track": "Motifs",
+        "Option": "Downtime"
+      }
+    ],
+    "BossMod.Autorotation.xan.PLD": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.SAM": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.SGE": [
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.VPR": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.NIN": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.GNB": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.SMN": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.DRK": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.RPR": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.WHM": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.AST": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.BRD": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.SCH": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.BLM": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.StandardWAR": [
+      {
+        "Track": "AOE",
+        "Option": "AutoFinishCombo"
+      }
+    ],
+    "BossMod.Autorotation.xan.RDM": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ],
+    "BossMod.Autorotation.xan.DRG": [
+      {
+        "Track": "Buffs",
+        "Option": "Auto"
+      },
+      {
+        "Track": "Buffs",
+        "Option": "Delay",
+        "Mod": "Shift, Ctrl"
+      },
+      {
+        "Track": "AOE",
+        "Option": "AOE"
+      },
+      {
+        "Track": "Targeting",
+        "Option": "Manual"
+      }
+    ]
+  }
+}
\ No newline at end of file
index 6d44ba067e2a24553243db8dbf64fd9fbe7933c8..eb91f928b9c2d647af16c2295d82fc7f68a9a0e7 100644 (file)
         <ProjectReference Include="..\QuestPaths\QuestPaths.csproj"/>
         <ProjectReference Include="..\vendor\NotificationMasterAPI\NotificationMasterAPI\NotificationMasterAPI.csproj" />
     </ItemGroup>
+
+       <ItemGroup>
+               <None Remove="Controller\CombatModules\BossModPreset.json" />
+               <Content Include="Controller\CombatModules\BossModPreset.json">
+                       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+               </Content>
+       </ItemGroup>
 </Project>
index 8e4ad410f240db2508d4a873c2cbeb43dadcb6d2..73af794f6d86a924b94942776ee8e89214095e75 100644 (file)
@@ -247,6 +247,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
 
         serviceCollection.AddSingleton<ICombatModule, Mount128Module>();
         serviceCollection.AddSingleton<ICombatModule, ItemUseModule>();
+        serviceCollection.AddSingleton<ICombatModule, BossModModule>();
         serviceCollection.AddSingleton<ICombatModule, RotationSolverRebornModule>();
     }