using Dalamud.Game.ClientState.Objects.SubKinds; using HSUI.Helpers; using FFXIVClientStructs.FFXIV.Client.System.Framework; using FFXIVClientStructs.FFXIV.Client.UI.Misc; using System.Collections.Generic; namespace HSUI.Interface.Party { public static class PartyOrderHelper { private enum PartySortingSetting { Tank_Healer_DPS = 0, Tank_DPS_Healer = 1, Healer_Tank_DPS = 2, Healer_DPS_Tank = 3, DPS_Tank_Healer = 4, DPS_Healer_Tank = 5, Count = 6 } private class PartyRoles { internal int Tank; internal int Healer; internal int DPS; internal int Other; public PartyRoles() { Tank = 0; Healer = 0; DPS = 0; Other = 0; } public PartyRoles(int tank, int healer, int dps, int other) { Tank = tank; Healer = healer; DPS = dps; Other = other; } } // calcualates the position for the player if they select the // option to always appear as the first of their current role // in the party frames public static int? GetRoleFirstOrder(List members) { IPlayerCharacter? player = Plugin.ObjectTable.LocalPlayer; if (player == null) { return null; } JobRoles role = JobsHelper.RoleForJob(player.ClassJob.RowId); PartySortingSetting? setting = GetPartySortingSetting(role); if (!setting.HasValue) { return null; } PartyRoles rolesCount = GetPartyCountByRole(members); PartyRoles roleWeights = GetRoleWeights(role, setting.Value); return rolesCount.Tank * roleWeights.Tank + rolesCount.Healer * roleWeights.Healer + rolesCount.DPS * roleWeights.DPS + rolesCount.Other * roleWeights.Other; } private static unsafe PartySortingSetting? GetPartySortingSetting(JobRoles role) { ConfigModule* config = ConfigModule.Instance(); if (config == null) { return null; } ConfigOption option; switch (role) { case JobRoles.Tank: option = ConfigOption.PartyListSortTypeTank; break; case JobRoles.Healer: option = ConfigOption.PartyListSortTypeHealer; break; case JobRoles.DPSMelee: case JobRoles.DPSRanged: case JobRoles.DPSCaster: option = ConfigOption.PartyListSortTypeDps; break; default: option = ConfigOption.PartyListSortTypeOther; break; } Framework* framework = Framework.Instance(); if (framework == null || framework->SystemConfig.SystemConfigBase.UiConfig.ConfigCount <= (int)option) { return PartySortingSetting.Tank_Healer_DPS; } uint value = framework->SystemConfig.SystemConfigBase.UiConfig.ConfigEntry[(int)option].Value.UInt; if (value < 0 || value > (int)PartySortingSetting.Count) { return null; } return (PartySortingSetting)value; } private static unsafe PartyRoles GetPartyCountByRole(List members) { PartyRoles rolesCount = new PartyRoles(); IPlayerCharacter? player = Plugin.ObjectTable.LocalPlayer; if (player == null) { return rolesCount; } foreach (IPartyFramesMember member in members) { if (member.ObjectId == player.GameObjectId) { continue; } JobRoles role = JobsHelper.RoleForJob(member.JobId); switch (role) { case JobRoles.Tank: rolesCount.Tank++; break; case JobRoles.Healer: rolesCount.Healer++; break; case JobRoles.DPSMelee: case JobRoles.DPSRanged: case JobRoles.DPSCaster: rolesCount.DPS++; break; default: rolesCount.Other++; break; } } return rolesCount; } private static unsafe PartyRoles GetRoleWeights(JobRoles role, PartySortingSetting setting) { if (role == JobRoles.Crafter || role == JobRoles.Gatherer || role == JobRoles.Unknown) { return new PartyRoles(1, 1, 1, 0); } JobRoles mapRole = role == JobRoles.DPSRanged || role == JobRoles.DPSCaster ? JobRoles.DPSMelee : role; return RoleWeights[mapRole][setting]; } private static Dictionary> RoleWeights = new Dictionary>() { [JobRoles.Tank] = new Dictionary() { [PartySortingSetting.Tank_Healer_DPS] = new PartyRoles(), [PartySortingSetting.Tank_DPS_Healer] = new PartyRoles(), [PartySortingSetting.Healer_Tank_DPS] = new PartyRoles(0, 1, 0, 0), [PartySortingSetting.Healer_DPS_Tank] = new PartyRoles(0, 1, 1, 0), [PartySortingSetting.DPS_Tank_Healer] = new PartyRoles(0, 0, 1, 0), [PartySortingSetting.DPS_Healer_Tank] = new PartyRoles(0, 1, 1, 0) }, [JobRoles.Healer] = new Dictionary() { [PartySortingSetting.Tank_Healer_DPS] = new PartyRoles(1, 0, 0, 0), [PartySortingSetting.Tank_DPS_Healer] = new PartyRoles(1, 0, 1, 0), [PartySortingSetting.Healer_Tank_DPS] = new PartyRoles(), [PartySortingSetting.Healer_DPS_Tank] = new PartyRoles(), [PartySortingSetting.DPS_Tank_Healer] = new PartyRoles(1, 0, 1, 0), [PartySortingSetting.DPS_Healer_Tank] = new PartyRoles(0, 0, 1, 0) }, [JobRoles.DPSMelee] = new Dictionary() { [PartySortingSetting.Tank_Healer_DPS] = new PartyRoles(1, 1, 0, 0), [PartySortingSetting.Tank_DPS_Healer] = new PartyRoles(1, 0, 0, 0), [PartySortingSetting.Healer_Tank_DPS] = new PartyRoles(1, 1, 0, 0), [PartySortingSetting.Healer_DPS_Tank] = new PartyRoles(0, 1, 0, 0), [PartySortingSetting.DPS_Tank_Healer] = new PartyRoles(), [PartySortingSetting.DPS_Healer_Tank] = new PartyRoles() } }; } }