Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lots of changes #2

Merged
merged 2 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion RotationSolver.Basic/Actions/ActionBasicInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public readonly struct ActionBasicInfo
/// <summary>
/// The animation lock time of this action.
/// </summary>
public readonly float AnimationLockTime => OtherConfiguration.AnimationLockTime?.TryGetValue(AdjustedID, out var time) ?? false ? time : 0.6f;
[Obsolete("Use ActionManagerHelper.GetCurrentAnimationLock()")]
public readonly float AnimationLockTime => ActionManagerHelper.GetCurrentAnimationLock();

/// <summary>
/// The level of this action.
Expand Down
4 changes: 2 additions & 2 deletions RotationSolver.Basic/Actions/ActionCooldownInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ internal bool CooldownCheck(bool isEmpty, bool onLastAbility, bool ignoreClippin
{
if (onLastAbility)
{
if (DataCenter.NextAbilityToNextGCD > _action.Info.AnimationLockTime + DataCenter.Ping + DataCenter.MinAnimationLock) return false;
if (DataCenter.NextAbilityToNextGCD > ActionManagerHelper.GetCurrentAnimationLock() + DataCenter.Ping + DataCenter.MinAnimationLock) return false;
}
else if (!ignoreClippingCheck)
{
if (DataCenter.NextAbilityToNextGCD < _action.Info.AnimationLockTime) return false;
if (DataCenter.NextAbilityToNextGCD < ActionManagerHelper.GetCurrentAnimationLock()) return false;
}
}

Expand Down
2 changes: 1 addition & 1 deletion RotationSolver.Basic/Actions/BaseAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class BaseAction : IBaseAction
public uint AdjustedID => Info.AdjustedID;

/// <inheritdoc/>
public float AnimationLockTime => Info.AnimationLockTime;
public float AnimationLockTime => ActionManagerHelper.GetCurrentAnimationLock();

/// <inheritdoc/>
public uint SortKey => Cooldown.CoolDownGroup;
Expand Down
2 changes: 1 addition & 1 deletion RotationSolver.Basic/Configuration/Configs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public const string

[ConditionBool, UI("Show RS logo animation",
Filter = UiWindows)]
private static readonly bool _drawIconAnimation = False;
private static readonly bool _drawIconAnimation = false;

[ConditionBool, UI("Auto turn off when player is moving between areas.",
Filter =BasicAutoSwitch)]
Expand Down
2 changes: 2 additions & 0 deletions RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace RotationSolver.Basic;
internal static class DataCenter
{
private static uint _hostileTargetId = GameObject.InvalidGameObjectId;

public static bool IsActivated() => State || IsManual || Service.Config.TeachingMode;
internal static BattleChara? HostileTarget
{
get
Expand Down
21 changes: 21 additions & 0 deletions RotationSolver.Basic/Helpers/ActionManagerHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using FFXIVClientStructs.FFXIV.Client.Game;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RotationSolver.Basic.Helpers
{
internal static class ActionManagerHelper
{
public static unsafe float GetCurrentAnimationLock()
{
var actionManager = ActionManager.Instance();
if (actionManager == null) return 0.6f;

var animationLockRaw = ((IntPtr)actionManager + 8);
return *(float*)animationLockRaw;
}
}
}
2 changes: 1 addition & 1 deletion RotationSolver.Basic/Service.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace RotationSolver.Basic;

internal class Service : IDisposable
{
public const string COMMAND = "/rotation", USERNAME = "ArchiDog1998", REPO = "RotationSolver";
public const string COMMAND = "/rotation", USERNAME = "FFXIV-CombatReborn", REPO = "RotationSolverReborn";

// From https://GitHub.com/PunishXIV/Orbwalker/blame/master/Orbwalker/Memory.cs#L85-L87
[Signature("F3 0F 10 05 ?? ?? ?? ?? 0F 2E C6 0F 8A", ScanType = ScanType.StaticAddress, Fallibility = Fallibility.Infallible)]
Expand Down
8 changes: 8 additions & 0 deletions RotationSolver/Commands/RSCommands_Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ public static partial class RSCommands
static DateTime _lastClickTime = DateTime.MinValue;
static bool _lastState;

public static void IncrementState()
{
if (!DataCenter.State) { DoStateCommandType(StateCommandType.Auto); return; }
if (DataCenter.State && !DataCenter.IsManual && DataCenter.TargetingType == TargetingType.Big) { DoStateCommandType(StateCommandType.Auto); return; }
if (DataCenter.State && !DataCenter.IsManual) { DoStateCommandType(StateCommandType.Manual); return; }
if (DataCenter.State && DataCenter.IsManual) { DoStateCommandType(StateCommandType.Cancel); return; }
}

internal static unsafe bool CanDoAnAction(bool isGCD)
{
if (!_lastState || !DataCenter.State)
Expand Down
3 changes: 0 additions & 3 deletions RotationSolver/Data/UiString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ internal enum UiString
[Description("Rotation Solver helped you by clicking actions {0:N0} times.")]
ConfigWindow_About_ClickingCount,

[Description("You have said hello to other users {0:N0} times!")]
ConfigWindow_About_SayHelloCount,

[Description("Macro")]
ConfigWindow_About_Macros,

Expand Down
4 changes: 4 additions & 0 deletions RotationSolver/UI/ControlWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ static void DrawCommandAction(IAction? gcd, IAction? ability, SpecialCommandType
ImGui.TextColored(color, str);

var help = command.Local();
if (ability != null)
{
help = help + "\n" + $"({ability.Name})";
}
string baseId = "ImgButton" + command.ToString();

ImGui.SetCursorPosX(ImGui.GetCursorPosX() + Math.Max(0, strWidth / 2 - width / 2));
Expand Down
43 changes: 7 additions & 36 deletions RotationSolver/UI/RotationConfigWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,26 +308,6 @@ private void DrawSideBar()
}
}
}

if (wholeWidth <= 60 * Scale
? IconSet.GetTexture("https://storage.ko-fi.com/cdn/brandasset/kofi_s_logo_nolabel.png", out var texture)
: IconSet.GetTexture("https://storage.ko-fi.com/cdn/brandasset/kofi_bg_tag_dark.png", out texture))
{
var width = Math.Min(150 * Scale, Math.Max(Scale * MIN_COLUMN_WIDTH, Math.Min(wholeWidth, texture.Width)));
var size = new Vector2(width, width * texture.Height / texture.Width);
size *= MathF.Max(Scale * MIN_COLUMN_WIDTH / size.Y, 1);
var result = false;
ImGuiHelper.DrawItemMiddle(() =>
{
ImGui.SetCursorPosY(ImGui.GetWindowSize().Y + ImGui.GetScrollY() - size.Y);
result = ImGuiHelper.NoPaddingNoColorImageButton(texture.ImGuiHandle, size, "Donate Plugin");
}, wholeWidth, size.X);

if (result)
{
Util.OpenLink("https://ko-fi.com/B0B0IN5DX");
}
}
}
}

Expand Down Expand Up @@ -542,12 +522,13 @@ private static void DrawRotationCombo(float comboSize, Type[] rotations, ICustom
{
if( DataCenter.IsPvP)
{
Service.Config.PvPRotationChoice = r.GetType().FullName;
Service.Config.PvPRotationChoice = r.FullName;
}
else
{
Service.Config.RotationChoice = r.GetType().FullName;
Service.Config.RotationChoice = r.FullName;
}
Service.Config.Save();
}
ImguiTooltips.HoveredTooltip(rAttr.Description);
ImGui.PopStyleColor();
Expand Down Expand Up @@ -698,19 +679,6 @@ private static void DrawAbout()
}
}
}

var sayHelloCount = OtherConfiguration.RotationSolverRecord.SayingHelloCount;
if (sayHelloCount > 0)
{
using var color = ImRaii.PushColor(ImGuiCol.Text, new Vector4(0.2f, 0.8f, 0.95f, 1));
var countStr = string.Format(UiString.ConfigWindow_About_SayHelloCount.Local(), sayHelloCount);

ImGuiHelper.DrawItemMiddle(() =>
{
ImGui.TextWrapped(countStr);
}, width, ImGui.CalcTextSize(countStr).X);
}

_aboutHeaders.Draw();
}

Expand Down Expand Up @@ -1724,7 +1692,9 @@ private static void DrawRotationsLoaded()
if (IconSet.GetTexture(IconSet.GetJobIcon(jobs.Key, IconType.Framed), out var texture, 62574))
ImGui.Image(texture.ImGuiHandle, Vector2.One * 30 * Scale);

ImguiTooltips.HoveredTooltip(string.Join('\n', jobs.Select(t => t.GetCustomAttribute<UIAttribute>()?.Name ?? t.Name)));
ImguiTooltips.HoveredTooltip(string.Join('\n', jobs.Select(t => t.GetCustomAttribute<UIAttribute>()?.Name ?? t.Name)) +
Environment.NewLine +
string.Join('\n', jobs.Select(t => t.GetCustomAttribute<RotationAttribute>()?.Type ?? CombatType.None)));
}

ImGui.TableNextColumn();
Expand Down Expand Up @@ -2562,6 +2532,7 @@ private static void DrawNextAction()
ImGui.Text("Ability Remain: " + DataCenter.AbilityRemain.ToString());
ImGui.Text("Action Remain: " + DataCenter.AnimationLocktime.ToString());
ImGui.Text("Weapon Remain: " + DataCenter.WeaponRemain.ToString());
ImGui.Text("Animation Lock Delay: " + ActionManagerHelper.GetCurrentAnimationLock().ToString());
}

private static void DrawLastAction()
Expand Down
23 changes: 0 additions & 23 deletions RotationSolver/UI/RotationConfigWindow_Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -268,29 +268,6 @@ private static void DrawBasicNamedConditions()
private static void DrawBasicOthers()
{
_allSearchable.DrawItems(Configs.BasicParams);

if (Service.Config.SayHelloToAll)
{
var str = Player.Object.EncryptString();
ImGui.SetNextItemWidth(ImGui.CalcTextSize(str).X + 10);
ImGui.InputText("That is your HASH:", ref str, 100);

if (!DataCenter.ContributorsHash.Contains(str)
&& !DownloadHelper.UsersHash.Contains(str)
&& !DataCenter.AuthorHashes.ContainsKey(str))
{
if (ImGui.Button("DM your Hash to ArchiTed for being greeted."))
{
ImGui.SetClipboardText(str);
Notify.Success($"Your hash \"{str}\" copied to clipboard.");
Util.OpenLink("https://discord.com/users/1007293294100877322");
}
}
}
else
{
ImGui.TextColored(ImGuiColors.DalamudRed, "The author of RS loves being greeted by you!");
}
}
#endregion

Expand Down
12 changes: 7 additions & 5 deletions RotationSolver/Updaters/MajorUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ private static void UpdateWork()

try
{
TargetUpdater.UpdateTarget();
StateUpdater.UpdateState();

if (Service.Config.AutoLoadCustomRotations)
Expand All @@ -180,10 +179,13 @@ private static void UpdateWork()
}

RotationUpdater.UpdateRotation();

RaidTimeUpdater.UpdateTimeline();
ActionSequencerUpdater.UpdateActionSequencerAction();
ActionUpdater.UpdateNextAction();
if (DataCenter.IsActivated())
{
TargetUpdater.UpdateTarget();
RaidTimeUpdater.UpdateTimeline();
ActionSequencerUpdater.UpdateActionSequencerAction();
ActionUpdater.UpdateNextAction();
}

RSCommands.UpdateRotationState();
PainterManager.UpdateSettings();
Expand Down
1 change: 1 addition & 0 deletions RotationSolver/Updaters/PreviewUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ private static void UpdateEntry()
new IconPayload(BitmapFontIcon.DPS),
new TextPayload(showStr)
);
_dtrEntry.OnClick = RSCommands.IncrementState;
}
else if (_dtrEntry != null && _dtrEntry.Shown)
{
Expand Down
6 changes: 3 additions & 3 deletions RotationSolver/Updaters/RotationUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -553,11 +553,11 @@ private static void UpdateCustomRotation()

private static Type? GetChosenType(IEnumerable<Type> types, string name)
{
var rotation = types.FirstOrDefault(r => r.GetType().FullName == name);
var rotation = types.FirstOrDefault(r => r.FullName == name);

rotation ??= types.FirstOrDefault(r => r.GetType().Assembly.FullName!.Contains("SupportersRotations", StringComparison.OrdinalIgnoreCase));
rotation ??= types.FirstOrDefault(r => r.Assembly.FullName!.Contains("SupportersRotations", StringComparison.OrdinalIgnoreCase));

rotation ??= types.FirstOrDefault(r => r.GetType().Assembly.FullName!.Contains("DefaultRotations", StringComparison.OrdinalIgnoreCase));
rotation ??= types.FirstOrDefault(r => r.Assembly.FullName!.Contains("DefaultRotations", StringComparison.OrdinalIgnoreCase));

rotation ??= types.FirstOrDefault();

Expand Down
67 changes: 0 additions & 67 deletions RotationSolver/Updaters/SocialUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,73 +139,10 @@ internal static async void UpdateSocial()
_canSaying = false;
Service.Config.DutyStart.AddMacro();
await Task.Delay(new Random().Next(1000, 1500));

SayHelloToUsers();
}
}

private static readonly ChatEntityComparer _comparer = new();
private static async void SayHelloToUsers()
{
if (!Service.Config.SayHelloToAll)
{
return;
}

var players = DataCenter.AllianceMembers.OfType<PlayerCharacter>()
#if DEBUG
#else
.Where(c => c.ObjectId != Player.Object.ObjectId)
#endif
.Select(player => (player, player.EncryptString()))
.Where(pair => !saidAuthors.Contains(pair.Item2)
&& !OtherConfiguration.RotationSolverRecord.SaidUsers.Contains(pair.Item2));

IEnumerable<ChatEntity> entities = players
.Select(c =>
{
if (!DataCenter.AuthorHashes.TryGetValue(c.Item2, out var nameDesc)) nameDesc = string.Empty;
return (c.player, nameDesc);
})
.Where(p => !string.IsNullOrEmpty(p.nameDesc))
.Select(p => new RotationAuthorChatEntity(p.player, p.nameDesc));

entities = entities.Union(players
.Where(p => DataCenter.ContributorsHash.Contains(p.Item2))
.Select(p => new ContributorChatEntity(p.player)), _comparer);

if (Service.Config.SayHelloToUsers)
{
entities = entities.Union(players
.Where(p => DownloadHelper.UsersHash.Contains(p.Item2))
.Select(p => new UserChatEntity(p.player)), _comparer);
}

foreach (var entity in entities)
{
while (!entity.CanTarget && !DataCenter.InCombat)
{
await Task.Delay(100);
}

#if DEBUG
#else
Svc.Targets.Target = entity.player;
ECommons.Automation.Chat.Instance.SendMessage($"/{_macroToAuthor[new Random().Next(_macroToAuthor.Count)]} <t>");
#endif
Svc.Chat.Print(new Dalamud.Game.Text.XivChatEntry()
{
Message = entity.GetMessage(),
Type = Dalamud.Game.Text.XivChatType.Notice,
});
UIModule.PlaySound(20, 0, 0, 0);
entity.Dispose();

await Task.Delay(new Random().Next(800, 1200));
Svc.Targets.Target = null;
await Task.Delay(new Random().Next(800, 1200));
}
}

internal abstract class ChatEntity(PlayerCharacter character) : IDisposable
{
Expand Down Expand Up @@ -247,10 +184,6 @@ public void Dispose()
OtherConfiguration.RotationSolverRecord.SayingHelloCount++;
var hash = player.EncryptString();
saidAuthors.Add(hash);
if (Service.Config.JustSayHelloOnce)
{
OtherConfiguration.RotationSolverRecord.SaidUsers.Add(hash);
}
}
}

Expand Down
10 changes: 7 additions & 3 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
{
"Author": "ArchiTed",
"Author": "The FFXIV-CombatReborn Team",
"Name": "Rotation Solver",
"InternalName": "RotationSolver",
"Description": "Analyses combat information every frame and finds the best action.\n\nThis means almost all the information available in one frame in combat, including the status of all players in the party, the status of any hostile targets, skill cooldowns, the MP and HP of characters, the location of characters, casting status of the hostile target, combo, combat duration, player level, etc.\nThen, it will highlight the best action on the hot bar, or help you to click on it.\nIt is designed for `general combat`, not for savage or ultimate. Use it carefully.",
"ApplicableVersion": "any",
"Tags": [
"combat",
"rotation"
"rotation",
"auto",
"solver",
"pve",
"pvp"
],
"CategoryTags": [
"jobs"
Expand All @@ -17,7 +21,7 @@
"CanUnloadAsync": false,
"LoadPriority": 0,
"IsTestingExclusive": false,
"IconUrl": "https://raw.githubusercontent.com/ArchiDog1998/RotationSolver/main/Images/Logo.png",
"IconUrl": "https://raw.githubusercontent.com/FFXIV-CombatReborn/RotationSolverReborn/main/Images/Logo.png",
"Punchline": "Analyses combat information every frame and finds the best action.",
"AcceptsFeedback": true
}