f37369cdda
Co-authored-by: Cursor <cursoragent@cursor.com>
172 lines
6.6 KiB
C#
172 lines
6.6 KiB
C#
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<IPartyFramesMember> 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<IPartyFramesMember> 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<JobRoles, Dictionary<PartySortingSetting, PartyRoles>> RoleWeights = new Dictionary<JobRoles, Dictionary<PartySortingSetting, PartyRoles>>()
|
|
{
|
|
[JobRoles.Tank] = new Dictionary<PartySortingSetting, PartyRoles>()
|
|
{
|
|
[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, PartyRoles>()
|
|
{
|
|
[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, PartyRoles>()
|
|
{
|
|
[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()
|
|
}
|
|
};
|
|
}
|
|
}
|