Skip to content

Commit

Permalink
feat: alliance swap feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Aireil committed Dec 25, 2024
1 parent 99cccd2 commit 125e80d
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 38 deletions.
6 changes: 5 additions & 1 deletion FFLogsViewer/GUI/Config/StyleTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ public static void Draw()

ImGui.Indent();

hasStyleChanged |= ImGui.Checkbox("Include yourself in the party view", ref style.IsLocalPlayerInPartyView);
if (ImGui.Checkbox("Include yourself in the party view", ref style.IsLocalPlayerInPartyView))
{
Service.CharDataManager.UpdatePartyMembers();
hasStyleChanged = true;
}

ImGui.Unindent();
if (hasStyleChanged)
Expand Down
13 changes: 12 additions & 1 deletion FFLogsViewer/GUI/Main/HeaderBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,27 @@ private void DrawPartyMembersPopup()
{
if (ImGui.BeginTable("##PartyListTable", 3, ImGuiTableFlags.RowBg))
{
uint? currentAllianceIndex = null;
for (var i = 0; i < partyList.Count; i++)
{
var partyMember = partyList[i];

if (i != 0)
{
ImGui.TableNextRow();

// mark the separation between alliances
if (partyMember.AllianceIndex != currentAllianceIndex)
{
ImGui.TableNextRow();
ImGui.TableNextRow();
}

currentAllianceIndex = partyMember.AllianceIndex;
}

ImGui.TableNextColumn();

var partyMember = partyList[i];
var iconSize = Util.Round(25 * ImGuiHelpers.GlobalScale);
var middleCursorPosY = ImGui.GetCursorPosY() + (iconSize / 2) - (ImGui.GetFontSize() / 2);

Expand Down
51 changes: 39 additions & 12 deletions FFLogsViewer/GUI/Main/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ private void DrawPartyView()

if (Util.DrawButtonIcon(FontAwesomeIcon.Redo))
{
Service.CharDataManager.UpdatePartyMembers();
Service.CharDataManager.UpdatePartyMembers(false);
}

Util.SetHoverTooltip("Refresh party state");
Expand Down Expand Up @@ -298,26 +298,37 @@ private void DrawEncounterLayout()

this.DrawEncounterHeader();

var nbColumns = Service.Configuration.Style.IsLocalPlayerInPartyView || Service.CharDataManager.IsCurrPartyAnAlliance ? 9 : 8;
var nbChars = nbColumns - 1;

if (ImGui.BeginTable(
"##MainWindowTablePartyViewEncounterLayout",
Service.Configuration.Style.IsLocalPlayerInPartyView ? 9 : 8,
nbColumns,
Service.Configuration.Style.MainTableFlags))
{
ImGui.TableNextColumn();

var separatorY = ImGui.GetCursorPosY();
if (Service.Configuration.Style.IsHeaderSeparatorDrawn && displayedEntries[0].Type != LayoutEntryType.Header)
var iconSize = Util.Round(25 * ImGuiHelpers.GlobalScale);

if (Service.TeamManager.HasAllianceMembers)
{
ImGui.Separator();
var posY = ImGui.GetCursorPosY() + (ImGui.GetStyle().ItemSpacing.Y + iconSize);
ImGui.SetCursorPosY(posY);

//  == mouse character from game's font
if (ImGui.Selectable("Alliance swap ##PartyViewAllianceSwapEncounterLayout"))
{
Service.CharDataManager.SwapAlliance();
}
}

for (var i = 0; i < (Service.Configuration.Style.IsLocalPlayerInPartyView ? 8 : 7); i++)
var firstLineAfterNamesCursorPosY = 0.0f;
for (var i = 0; i < nbChars; i++)
{
var charData = i < currentParty.Count ? currentParty[i] : null;

ImGui.TableNextColumn();

var iconSize = Util.Round(25 * ImGuiHelpers.GlobalScale);
Util.CenterCursor(iconSize);
ImGui.Image(Service.TextureProvider.GetFromGameIcon(new GameIconLookup(Util.GetJobIconId(charData?.JobId ?? 0))).GetWrapOrEmpty().ImGuiHandle, new Vector2(iconSize));

Expand Down Expand Up @@ -345,10 +356,18 @@ private void DrawEncounterLayout()
Util.CenterText("-");
}

ImGui.SetCursorPosY(separatorY);
if (Service.Configuration.Style.IsHeaderSeparatorDrawn && displayedEntries[0].Type != LayoutEntryType.Header)
firstLineAfterNamesCursorPosY = ImGui.GetCursorPosY();
}

if (Service.Configuration.Style.IsHeaderSeparatorDrawn && displayedEntries[0].Type != LayoutEntryType.Header)
{
ImGui.TableNextRow();
ImGui.TableNextColumn();
for (var i = 0; i < nbColumns; i++)
{
ImGui.SetCursorPosY(firstLineAfterNamesCursorPosY);
ImGui.Separator();
ImGui.TableNextColumn();
}
}

Expand All @@ -363,7 +382,7 @@ private void DrawEncounterLayout()
{
this.DrawStatAlias(entry, row);

for (var i = 0; i < (Service.Configuration.Style.IsLocalPlayerInPartyView ? 8 : 7); i++)
for (var i = 0; i < nbChars; i++)
{
ImGui.TableNextColumn();
var charData = i < currentParty.Count ? currentParty[i] : null;
Expand All @@ -374,7 +393,7 @@ private void DrawEncounterLayout()
{
this.DrawEncounterName(entry, entry.Alias == string.Empty ? entry.Encounter : entry.Alias, string.Empty, row);

for (var i = 0; i < (Service.Configuration.Style.IsLocalPlayerInPartyView ? 8 : 7); i++)
for (var i = 0; i < nbChars; i++)
{
ImGui.TableNextColumn();
var charData = i < currentParty.Count ? currentParty[i] : null;
Expand Down Expand Up @@ -531,6 +550,13 @@ private void DrawStatLayout()
ImGui.TableNextColumn();

var separatorY = ImGui.GetCursorPosY() + ImGui.GetFontSize() + ImGui.GetStyle().ItemSpacing.Y;

//  == mouse character from game's font
if (Service.TeamManager.HasAllianceMembers && ImGui.Selectable("Alliance swap ##PartyViewAllianceSwapStatLayout"))
{
Service.CharDataManager.SwapAlliance();
}

ImGui.SetCursorPosY(separatorY);
if (Service.Configuration.Style.IsHeaderSeparatorDrawn)
{
Expand All @@ -549,7 +575,8 @@ private void DrawStatLayout()
}
}

for (var i = 0; i < (Service.Configuration.Style.IsLocalPlayerInPartyView ? 8 : 7); i++)
var nbChars = Service.Configuration.Style.IsLocalPlayerInPartyView || Service.CharDataManager.IsCurrPartyAnAlliance ? 8 : 7;
for (var i = 0; i < nbChars; i++)
{
var charData = i < currentParty.Count ? currentParty[i] : null;

Expand Down
45 changes: 35 additions & 10 deletions FFLogsViewer/Manager/CharDataManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,35 @@ public class CharDataManager
{
public CharData DisplayedChar = new();
public List<CharData> PartyMembers = [];
public bool IsCurrPartyAnAlliance;
public string[] ValidWorlds;

public void UpdatePartyMembers(bool onlyFetchNewMembers = false)
private uint? currentAllianceIndex;

public void UpdatePartyMembers(bool forceLocalPlayerParty = true)
{
if (forceLocalPlayerParty)
{
this.currentAllianceIndex = null;
}

Service.TeamManager.UpdateTeamList();
var localPLayer = Service.ClientState.LocalPlayer;
var currPartyMembers = Service.TeamManager.TeamList.Where(teamMember => teamMember.IsInParty).ToList();
var currPartyMembers = Service.TeamManager.TeamList.Where(teamMember => teamMember.AllianceIndex == this.currentAllianceIndex).ToList();
this.IsCurrPartyAnAlliance = this.currentAllianceIndex != null;

if (!Service.Configuration.Style.IsLocalPlayerInPartyView)
// the alliance is empty, force local player party
if (this.IsCurrPartyAnAlliance && currPartyMembers.Count == 0)
{
this.currentAllianceIndex = null; // not needed, but just in case, careful when touching the code in this method /!\

// ReSharper disable once TailRecursiveCall
// ReSharper disable once RedundantArgumentDefaultValue
this.UpdatePartyMembers(true);
return;
}

if (!Service.Configuration.Style.IsLocalPlayerInPartyView && !this.IsCurrPartyAnAlliance)
{
var index = currPartyMembers.FindIndex(member => $"{member.FirstName} {member.LastName}" == localPLayer?.Name.TextValue
&& member.World == localPLayer.HomeWorld.ValueNullable?.Name);
Expand Down Expand Up @@ -54,7 +74,7 @@ public void UpdatePartyMembers(bool onlyFetchNewMembers = false)
member.LastName == charData.LastName &&
member.World == charData.WorldName)).ToList();

this.FetchLogs(onlyFetchNewMembers);
this.FetchLogs();
}

public CharDataManager()
Expand Down Expand Up @@ -118,17 +138,16 @@ public static void OpenCharInBrowser(string name)
}
}

public void FetchLogs(bool onlyFetchNewMembers = false)
public void FetchLogs()
{
if (Service.MainWindow.IsPartyView)
{
foreach (var partyMember in this.PartyMembers)
{
if (partyMember.IsInfoSet() && (!onlyFetchNewMembers
|| (!partyMember.IsDataReady
&& (partyMember.CharError == null
|| (partyMember.CharError != CharacterError.CharacterNotFoundFFLogs
&& partyMember.CharError != CharacterError.HiddenLogs)))))
if (partyMember.IsInfoSet() && !partyMember.IsDataReady
&& (partyMember.CharError == null
|| (partyMember.CharError != CharacterError.CharacterNotFoundFFLogs
&& partyMember.CharError != CharacterError.HiddenLogs)))
{
partyMember.FetchLogs();
}
Expand All @@ -154,4 +173,10 @@ public void Reset()
this.DisplayedChar = new CharData();
}
}

public void SwapAlliance()
{
this.currentAllianceIndex = Service.TeamManager.GetNextAllianceIndex(this.currentAllianceIndex);
this.UpdatePartyMembers(false);
}
}
51 changes: 38 additions & 13 deletions FFLogsViewer/Manager/TeamManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ namespace FFLogsViewer.Manager;
public class TeamManager
{
public List<TeamMember> TeamList = [];
public bool HasAllianceMembers;

public unsafe void UpdateTeamList()
{
this.TeamList = [];
this.HasAllianceMembers = false;

var groupManager = GroupManager.Instance()->MainGroup;
if (groupManager.MemberCount > 0)
Expand All @@ -28,7 +30,7 @@ public unsafe void UpdateTeamList()
if (cwProxy->IsInCrossRealmParty != 0)
{
var localIndex = cwProxy->LocalPlayerGroupIndex;
this.AddMembersFromCRGroup(cwProxy->CrossRealmGroups[localIndex], true);
this.AddMembersFromCRGroup(cwProxy->CrossRealmGroups[localIndex]);

for (var i = 0; i < cwProxy->CrossRealmGroups.Length; i++)
{
Expand All @@ -37,7 +39,8 @@ public unsafe void UpdateTeamList()
continue;
}

this.AddMembersFromCRGroup(cwProxy->CrossRealmGroups[i]);
this.AddMembersFromCRGroup(cwProxy->CrossRealmGroups[i], (uint)i);
this.HasAllianceMembers = true;
}
}
}
Expand All @@ -48,16 +51,34 @@ public unsafe void UpdateTeamList()
var selfName = Service.ClientState.LocalPlayer.Name.TextValue;
var selfWorldId = Service.ClientState.LocalPlayer.HomeWorld.RowId;
var selfJobId = Service.ClientState.LocalPlayer.ClassJob.RowId;
this.AddTeamMember(selfName, (ushort)selfWorldId, selfJobId, true);
this.AddTeamMember(selfName, (ushort)selfWorldId, selfJobId);
}
}

private void AddMembersFromCRGroup(CrossRealmGroup crossRealmGroup, bool isLocalPlayerGroup = false)
public uint? GetNextAllianceIndex(uint? currentAllianceIndex)
{
var allianceIndices = this.TeamList
.Select(member => member.AllianceIndex)
.Distinct()
.ToList();

if (allianceIndices.Count == 0)
{
return null;
}

var currentIndex = allianceIndices.IndexOf(currentAllianceIndex);
var nextIndex = (currentIndex + 1) % allianceIndices.Count;

return allianceIndices[nextIndex];
}

private void AddMembersFromCRGroup(CrossRealmGroup crossRealmGroup, uint? groupIndex = null)
{
for (var i = 0; i < crossRealmGroup.GroupMemberCount; i++)
{
var groupMember = crossRealmGroup.GroupMembers[i];
this.AddTeamMember(groupMember.NameString, (ushort)groupMember.HomeWorld, groupMember.ClassJobId, isLocalPlayerGroup);
this.AddTeamMember(groupMember.NameString, (ushort)groupMember.HomeWorld, groupMember.ClassJobId, groupIndex);
}
}

Expand Down Expand Up @@ -87,7 +108,7 @@ private unsafe void AddMembersFromPartyHud(GroupManager.Group group)
var partyMemberName = partyMember->NameString;
if (hudPartyMemberName.Equals(partyMemberName))
{
this.AddTeamMember(partyMemberName, partyMember->HomeWorld, partyMember->ClassJob, true);
this.AddTeamMember(partyMemberName, partyMember->HomeWorld, partyMember->ClassJob);
groupManagerIndexLeft.Remove(j);
break;
}
Expand All @@ -112,22 +133,26 @@ private unsafe void AddMembersFromGroupManager(GroupManager.Group group)
var partyMember = group.GetPartyMemberByIndex(i);
if (partyMember != null)
{
this.AddTeamMember(partyMember->NameString, partyMember->HomeWorld, partyMember->ClassJob, true);
this.AddTeamMember(partyMember->NameString, partyMember->HomeWorld, partyMember->ClassJob);
}
}
}

for (var i = 0; i < 20; i++)
for (var groupIndex = 0; groupIndex < 5; groupIndex++)
{
var allianceMember = group.GetAllianceMemberByIndex(i);
if (allianceMember != null)
for (var memberIndex = 0; memberIndex < 8; memberIndex++)
{
this.AddTeamMember(allianceMember->NameString, allianceMember->HomeWorld, allianceMember->ClassJob, false);
var allianceMember = group.GetAllianceMemberByGroupAndIndex(groupIndex, memberIndex);
if (allianceMember != null)
{
this.AddTeamMember(allianceMember->NameString, allianceMember->HomeWorld, allianceMember->ClassJob, (uint)groupIndex);
this.HasAllianceMembers = true;
}
}
}
}

private void AddTeamMember(string fullName, ushort worldId, uint jobId, bool isInParty)
private void AddTeamMember(string fullName, ushort worldId, uint jobId, uint? groupIndex = null)
{
var world = Util.GetWorld(worldId);
if (!Util.IsWorldValid(world))
Expand All @@ -146,6 +171,6 @@ private void AddTeamMember(string fullName, ushort worldId, uint jobId, bool isI
return;
}

this.TeamList.Add(new TeamMember { FirstName = splitName[0], LastName = splitName[1], World = world.Name.ToString(), JobId = jobId, IsInParty = isInParty });
this.TeamList.Add(new TeamMember { FirstName = splitName[0], LastName = splitName[1], World = world.Name.ToString(), JobId = jobId, AllianceIndex = groupIndex });
}
}
6 changes: 5 additions & 1 deletion FFLogsViewer/Model/TeamMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ public class TeamMember
public string LastName = null!;
public string World = null!;
public uint JobId;
public bool IsInParty;

/// <summary>
/// Null if in the local player party.
/// </summary>
public uint? AllianceIndex;
}

0 comments on commit 125e80d

Please sign in to comment.