feat: add job filtering
This commit is contained in:
parent
d910f5fbe6
commit
0f93fca760
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BetterPartyFinder {
|
||||
|
@ -74,6 +75,60 @@ namespace BetterPartyFinder {
|
|||
return false;
|
||||
}
|
||||
|
||||
// filter based on jobs (slow?)
|
||||
if (filter.Jobs.Count > 0) {
|
||||
var slots = listing.Slots.ToArray();
|
||||
var present = listing.RawJobsPresent.ToArray();
|
||||
|
||||
// create a list of sets containing the slots each job is able to join
|
||||
var jobs = new HashSet<int>[filter.Jobs.Count];
|
||||
for (var i = 0; i < jobs.Length; i++) {
|
||||
jobs[i] = new HashSet<int>();
|
||||
}
|
||||
|
||||
for (var idx = 0; idx < filter.Jobs.Count; idx++) {
|
||||
var wanted = filter.Jobs[idx];
|
||||
|
||||
for (var i = 0; i < listing.SlotsAvailable; i++) {
|
||||
// if the slot isn't already full and the job can fit into it, add it to the set
|
||||
if (present[i] == 0 && slots[i][wanted]) {
|
||||
jobs[idx].Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
// if this job couldn't match any slot, can't join the party
|
||||
if (jobs[idx].Count == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// loop through each unique pair of jobs
|
||||
for (var i = 0; i < jobs.Length; i++) {
|
||||
// ReSharper disable once LoopCanBeConvertedToQuery
|
||||
for (var j = 0; j < jobs.Length; j++) {
|
||||
if (i >= j) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var a = jobs[i];
|
||||
var b = jobs[j];
|
||||
|
||||
// check if the slots either job can join have overlap
|
||||
var overlap = a.Intersect(b);
|
||||
if (!overlap.Any()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if there is overlap, check the difference between the sets
|
||||
// if there is no difference, the party can't be joined
|
||||
var difference = a.Except(b);
|
||||
if (!difference.Any()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace BetterPartyFinder {
|
|||
public bool BeginnersWelcome { get; }
|
||||
public ushort SecondsRemaining { get; }
|
||||
public ushort MinimumItemLevel { get; }
|
||||
public byte SlotsAvailable { get; }
|
||||
public IReadOnlyCollection<PartyFinderSlot> Slots => this._slots;
|
||||
|
||||
private readonly byte _objective;
|
||||
|
@ -67,6 +68,7 @@ namespace BetterPartyFinder {
|
|||
this.BeginnersWelcome = listing.beginnersWelcome == 1;
|
||||
this.SecondsRemaining = listing.secondsRemaining;
|
||||
this.MinimumItemLevel = listing.minimumItemLevel;
|
||||
this.SlotsAvailable = listing.numSlots;
|
||||
|
||||
this._objective = listing.objective;
|
||||
this._conditions = listing.conditions;
|
||||
|
@ -127,7 +129,7 @@ namespace BetterPartyFinder {
|
|||
Lancer = 1 << 4,
|
||||
Archer = 1 << 5,
|
||||
Conjurer = 1 << 6,
|
||||
Thamaturge = 1 << 7,
|
||||
Thaumaturge = 1 << 7,
|
||||
Paladin = 1 << 8,
|
||||
Monk = 1 << 9,
|
||||
Warrior = 1 << 10,
|
||||
|
@ -150,6 +152,45 @@ namespace BetterPartyFinder {
|
|||
Dancer = 1 << 27,
|
||||
}
|
||||
|
||||
internal static class JobFlagsExt {
|
||||
internal static ClassJob? ClassJob(this JobFlags job, DataManager data) {
|
||||
var jobs = data.GetExcelSheet<ClassJob>();
|
||||
|
||||
uint? row = job switch {
|
||||
JobFlags.Gladiator => 1,
|
||||
JobFlags.Pugilist => 2,
|
||||
JobFlags.Marauder => 3,
|
||||
JobFlags.Lancer => 4,
|
||||
JobFlags.Archer => 5,
|
||||
JobFlags.Conjurer => 6,
|
||||
JobFlags.Thaumaturge => 7,
|
||||
JobFlags.Paladin => 19,
|
||||
JobFlags.Monk => 20,
|
||||
JobFlags.Warrior => 21,
|
||||
JobFlags.Dragoon => 22,
|
||||
JobFlags.Bard => 23,
|
||||
JobFlags.WhiteMage => 24,
|
||||
JobFlags.BlackMage => 25,
|
||||
JobFlags.Arcanist => 26,
|
||||
JobFlags.Summoner => 27,
|
||||
JobFlags.Scholar => 28,
|
||||
JobFlags.Rogue => 29,
|
||||
JobFlags.Ninja => 30,
|
||||
JobFlags.Machinist => 31,
|
||||
JobFlags.DarkKnight => 32,
|
||||
JobFlags.Astrologian => 33,
|
||||
JobFlags.Samurai => 34,
|
||||
JobFlags.RedMage => 35,
|
||||
JobFlags.BlueMage => 36,
|
||||
JobFlags.Gunbreaker => 37,
|
||||
JobFlags.Dancer => 38,
|
||||
_ => null,
|
||||
};
|
||||
|
||||
return row == null ? null : jobs.GetRow((uint) row);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ObjectiveFlags : uint {
|
||||
None = 0,
|
||||
|
|
|
@ -71,13 +71,17 @@ namespace BetterPartyFinder {
|
|||
internal readonly ushort homeWorld;
|
||||
internal readonly ushort currentWorld;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
private readonly byte[] header9; // 02 XX 01 00 in every pf I've examined
|
||||
private readonly byte header9;
|
||||
|
||||
internal readonly byte numSlots;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
private readonly byte[] header10;
|
||||
|
||||
internal readonly byte searchArea;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
private readonly byte[] header10; // 00 01 00 00 00 for every pf except alliance raids where it's 01 03 00 00 00 (second byte # parties?)
|
||||
private readonly byte[] header11; // 00 01 00 00 00 for every pf except alliance raids where it's 01 03 00 00 00 (second byte # parties?)
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
internal readonly uint[] slots;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Data;
|
||||
|
@ -26,6 +27,8 @@ namespace BetterPartyFinder {
|
|||
|
||||
private string PresetName { get; set; } = string.Empty;
|
||||
|
||||
private bool[] _openSlots = new bool[8];
|
||||
|
||||
internal PluginUi(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
|
||||
|
@ -295,7 +298,65 @@ namespace BetterPartyFinder {
|
|||
return;
|
||||
}
|
||||
|
||||
ImGui.TextUnformatted("Nothing here yet");
|
||||
if (ImGui.Button("Add slot")) {
|
||||
filter.Jobs.Add(0);
|
||||
this.Plugin.Config.Save();
|
||||
}
|
||||
|
||||
var toRemove = new HashSet<int>();
|
||||
|
||||
for (var i = 0; i < filter.Jobs.Count; i++) {
|
||||
var slot = filter.Jobs[i];
|
||||
|
||||
if (!ImGui.CollapsingHeader($"Slot {i + 1}")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ImGui.Button("Select all")) {
|
||||
filter.Jobs[i] = Enum.GetValues(typeof(JobFlags))
|
||||
.Cast<JobFlags>()
|
||||
.Aggregate(slot, (current, job) => current | job);
|
||||
this.Plugin.Config.Save();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Clear")) {
|
||||
filter.Jobs[i] = 0;
|
||||
this.Plugin.Config.Save();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Delete")) {
|
||||
toRemove.Add(i);
|
||||
}
|
||||
|
||||
foreach (var job in (JobFlags[]) Enum.GetValues(typeof(JobFlags))) {
|
||||
var selected = (slot & job) > 0;
|
||||
if (!ImGui.Selectable(job.ClassJob(this.Plugin.Interface.Data)?.Name ?? "???", ref selected)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
slot |= job;
|
||||
} else {
|
||||
slot &= ~job;
|
||||
}
|
||||
|
||||
filter.Jobs[i] = slot;
|
||||
|
||||
this.Plugin.Config.Save();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var idx in toRemove) {
|
||||
filter.Jobs.RemoveAt(idx);
|
||||
}
|
||||
|
||||
if (toRemove.Count > 0) {
|
||||
this.Plugin.Config.Save();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue