feat: try to randomise weapons

This commit is contained in:
Anna 2022-05-10 16:27:08 -04:00
parent f6696f2dcf
commit 09a0077623
2 changed files with 84 additions and 0 deletions

View File

@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using Dalamud;
using Dalamud.Logging;
using Lumina.Excel.GeneratedSheets;
@ -42,6 +45,9 @@ internal class AppearanceRepository {
"Hildibrand",
"Godbert",
};
internal IReadOnlyDictionary<uint, IReadOnlyList<Item>> JobMainHands { get; }
internal IReadOnlyDictionary<uint, IReadOnlyList<Item>> JobOffHands { get; }
internal AppearanceRepository(Plugin plugin) {
this.Plugin = plugin;
@ -56,6 +62,62 @@ internal class AppearanceRepository {
.ToList();
this.RefilterPersonal();
PluginLog.Log($"npcs: {this.Npcs.Count}");
var jobMainHands = new Dictionary<uint, List<Item>>();
var jobOffHands = new Dictionary<uint, List<Item>>();
var allMainHands = this.Plugin.DataManager.GetExcelSheet<Item>()!
.Where(row => row.EquipSlotCategory.Value!.MainHand != 0)
// let's not give people ultimate weapons and shit
.Where(row => !row.IsUnique && !row.IsUntradable)
.ToList();
var allOffHands = this.Plugin.DataManager.GetExcelSheet<Item>()!
.Where(row => row.EquipSlotCategory.Value!.OffHand != 0)
.Where(row => !row.IsUnique && !row.IsUntradable)
.ToList();
foreach (var job in this.Plugin.DataManager.GetExcelSheet<ClassJob>(ClientLanguage.English)!) {
if (job.RowId == 0) {
continue;
}
if (!jobMainHands.ContainsKey(job.RowId)) {
jobMainHands[job.RowId] = new List<Item>();
}
if (!jobOffHands.ContainsKey(job.RowId)) {
jobOffHands[job.RowId] = new List<Item>();
}
var engAbbr = job.Abbreviation.RawString;
foreach (var mainHand in allMainHands) {
var mainHandCategory = mainHand.ClassJobCategory.Value!;
var canUseMainHand = (bool?) mainHandCategory.GetType()
.GetProperty(engAbbr, BindingFlags.Instance | BindingFlags.Public)!
.GetValue(mainHandCategory);
if (canUseMainHand == true) {
jobMainHands[job.RowId].Add(mainHand);
}
}
foreach (var offHand in allOffHands) {
var offHandCategory = offHand.ClassJobCategory.Value!;
var canUseOffHand = (bool?) offHandCategory.GetType()
.GetProperty(engAbbr, BindingFlags.Instance | BindingFlags.Public)!
.GetValue(offHandCategory);
if (canUseOffHand == true) {
jobOffHands[job.RowId].Add(offHand);
}
}
}
this.JobMainHands = jobMainHands
.Select(entry => (entry.Key, (IReadOnlyList<Item>) entry.Value.ToImmutableList()))
.ToImmutableDictionary(entry => entry.Key, entry => entry.Item2);
this.JobOffHands = jobOffHands
.Select(entry => (entry.Key, (IReadOnlyList<Item>) entry.Value.ToImmutableList()))
.ToImmutableDictionary(entry => entry.Key, entry => entry.Item2);
}
internal void Reset() {
@ -94,4 +156,21 @@ internal class AppearanceRepository {
return this.Npcs[this.GetNpcIndex(objectId)];
}
internal (Item, Item?) GetHands(uint jobId, uint objectId) {
var random = new Random((int) (objectId + this.Salt));
var usesOffHand = this.JobOffHands[jobId].Count > 0;
var mainHand = this.JobMainHands[jobId][random.Next(0, this.JobMainHands[jobId].Count)];
var mainEquipCategory = mainHand.EquipSlotCategory.Value!;
var offHand =
mainEquipCategory.MainHand != 0 && mainEquipCategory.OffHand != 0
? null
: usesOffHand
? this.JobOffHands[jobId][random.Next(0, this.JobOffHands[jobId].Count)]
: null;
return (mainHand, offHand);
}
}

View File

@ -175,6 +175,9 @@ internal class Obscurer : IDisposable {
if (!this.ShouldObscureAppearance(gameObj)) {
return;
}
var chara = (FFXIVClientStructs.FFXIV.Client.Game.Character.Character*) gameObj;
var (mainHand, offHand) = this.Plugin.AppearanceRepository.GetHands(chara->ClassJob, gameObj->ObjectID);
var npc = this.Plugin.AppearanceRepository.GetNpc(gameObj->ObjectID);
var itemSlot = (EquipSlot) slot;
@ -189,6 +192,8 @@ internal class Obscurer : IDisposable {
EquipSlot.Wrists => (npc.ModelWrists, npc.DyeWrists.Row),
EquipSlot.RightRing => (npc.ModelRightRing, npc.DyeRightRing.Row),
EquipSlot.LeftRing => (npc.ModelLeftRing, npc.DyeLeftRing.Row),
EquipSlot.MainHand => (mainHand.ModelMain, npc.DyeMainHand.Row),
EquipSlot.OffHand => (mainHand.ModelSub != 0 ? mainHand.ModelSub : offHand?.ModelMain ?? 0, npc.DyeOffHand.Row),
_ => (uint.MaxValue, uint.MaxValue),
};