punish v6.8.18.0
This commit is contained in:
commit
cfb4dea47e
316 changed files with 554088 additions and 0 deletions
|
@ -0,0 +1,239 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using LLib;
|
||||
using Lumina.Excel.Sheets;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class EquipItem
|
||||
{
|
||||
internal sealed class Factory : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Questionable.Model.Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (step.InteractionType != EInteractionType.EquipItem)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(step.ItemId, "step.ItemId");
|
||||
return new Task(step.ItemId.Value);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed record Task(uint ItemId) : ITask
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Equip({ItemId})";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DoEquip(IDataManager dataManager, ILogger<DoEquip> logger) : TaskExecutor<Task>(), IToastAware, ITaskExecutor
|
||||
{
|
||||
private const int MaxAttempts = 3;
|
||||
|
||||
private static readonly IReadOnlyList<InventoryType> SourceInventoryTypes = new global::_003C_003Ez__ReadOnlyArray<InventoryType>(new InventoryType[16]
|
||||
{
|
||||
InventoryType.ArmoryMainHand,
|
||||
InventoryType.ArmoryOffHand,
|
||||
InventoryType.ArmoryHead,
|
||||
InventoryType.ArmoryBody,
|
||||
InventoryType.ArmoryHands,
|
||||
InventoryType.ArmoryLegs,
|
||||
InventoryType.ArmoryFeets,
|
||||
InventoryType.ArmoryEar,
|
||||
InventoryType.ArmoryNeck,
|
||||
InventoryType.ArmoryWrist,
|
||||
InventoryType.ArmoryRings,
|
||||
InventoryType.ArmorySoulCrystal,
|
||||
InventoryType.Inventory1,
|
||||
InventoryType.Inventory2,
|
||||
InventoryType.Inventory3,
|
||||
InventoryType.Inventory4
|
||||
});
|
||||
|
||||
private int _attempts;
|
||||
|
||||
private Item? _item;
|
||||
|
||||
private List<ushort> _targetSlots;
|
||||
|
||||
private DateTime _continueAt = DateTime.MaxValue;
|
||||
|
||||
protected override bool Start()
|
||||
{
|
||||
_item = dataManager.GetExcelSheet<Item>().GetRowOrDefault(base.Task.ItemId) ?? throw new ArgumentOutOfRangeException("ItemId");
|
||||
_targetSlots = GetEquipSlot(_item) ?? throw new InvalidOperationException("Not a piece of equipment");
|
||||
Equip();
|
||||
_continueAt = DateTime.Now.AddSeconds(1.0);
|
||||
return true;
|
||||
}
|
||||
|
||||
public unsafe override ETaskResult Update()
|
||||
{
|
||||
if (DateTime.Now < _continueAt)
|
||||
{
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
InventoryManager* ptr = InventoryManager.Instance();
|
||||
if (ptr == null)
|
||||
{
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
foreach (ushort targetSlot in _targetSlots)
|
||||
{
|
||||
InventoryItem* inventorySlot = ptr->GetInventorySlot(InventoryType.EquippedItems, targetSlot);
|
||||
if (inventorySlot != null && inventorySlot->ItemId == base.Task.ItemId)
|
||||
{
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
}
|
||||
Equip();
|
||||
_continueAt = DateTime.Now.AddSeconds(1.0);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
private unsafe void Equip()
|
||||
{
|
||||
_attempts++;
|
||||
if (_attempts > 3)
|
||||
{
|
||||
throw new TaskException("Unable to equip gear.");
|
||||
}
|
||||
InventoryManager* inventoryManager = InventoryManager.Instance();
|
||||
if (inventoryManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
InventoryContainer* inventoryContainer = inventoryManager->GetInventoryContainer(InventoryType.EquippedItems);
|
||||
if (inventoryContainer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (ushort targetSlot in _targetSlots)
|
||||
{
|
||||
InventoryItem* inventorySlot = inventoryContainer->GetInventorySlot(targetSlot);
|
||||
if (inventorySlot != null && inventorySlot->ItemId == base.Task.ItemId)
|
||||
{
|
||||
logger.LogInformation("Already equipped {Item}, skipping step", _item?.Name.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
foreach (InventoryType sourceInventoryType in SourceInventoryTypes)
|
||||
{
|
||||
InventoryContainer* inventoryContainer2 = inventoryManager->GetInventoryContainer(sourceInventoryType);
|
||||
if (inventoryContainer2 == null || (inventoryManager->GetItemCountInContainer(base.Task.ItemId, sourceInventoryType, isHq: true, 0) == 0 && inventoryManager->GetItemCountInContainer(base.Task.ItemId, sourceInventoryType, isHq: false, 0) == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (ushort num = 0; num < inventoryContainer2->Size; num++)
|
||||
{
|
||||
InventoryItem* inventorySlot2 = inventoryContainer2->GetInventorySlot(num);
|
||||
if (inventorySlot2 != null && inventorySlot2->ItemId == base.Task.ItemId)
|
||||
{
|
||||
ushort num2 = _targetSlots.Where(delegate(ushort x)
|
||||
{
|
||||
InventoryItem* inventorySlot3 = inventoryManager->GetInventorySlot(InventoryType.EquippedItems, x);
|
||||
return inventorySlot3 == null || inventorySlot3->ItemId == 0;
|
||||
}).Concat(_targetSlots).First();
|
||||
logger.LogInformation("Equipping item from {SourceInventory}, {SourceSlot} to {TargetInventory}, {TargetSlot}", sourceInventoryType, num, InventoryType.EquippedItems, num2);
|
||||
int num3 = inventoryManager->MoveItemSlot(sourceInventoryType, num, InventoryType.EquippedItems, num2, a6: true);
|
||||
logger.LogInformation("MoveItemSlot result: {Result}", num3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new TaskException($"Could not equip item {base.Task.ItemId}.");
|
||||
}
|
||||
|
||||
private static List<ushort>? GetEquipSlot(Item? item)
|
||||
{
|
||||
if (!item.HasValue)
|
||||
{
|
||||
return new List<ushort>();
|
||||
}
|
||||
Span<ushort> span;
|
||||
switch (item.Value.EquipSlotCategory.RowId)
|
||||
{
|
||||
case 1u:
|
||||
case 2u:
|
||||
case 3u:
|
||||
case 4u:
|
||||
case 5u:
|
||||
case 6u:
|
||||
case 7u:
|
||||
case 8u:
|
||||
case 9u:
|
||||
case 10u:
|
||||
case 11u:
|
||||
{
|
||||
int index = 1;
|
||||
List<ushort> list4 = new List<ushort>(index);
|
||||
CollectionsMarshal.SetCount(list4, index);
|
||||
span = CollectionsMarshal.AsSpan(list4);
|
||||
int num = 0;
|
||||
span[num] = (ushort)(item.Value.EquipSlotCategory.RowId - 1);
|
||||
return list4;
|
||||
}
|
||||
case 12u:
|
||||
{
|
||||
int num = 2;
|
||||
List<ushort> list3 = new List<ushort>(num);
|
||||
CollectionsMarshal.SetCount(list3, num);
|
||||
span = CollectionsMarshal.AsSpan(list3);
|
||||
int index = 0;
|
||||
span[index] = 11;
|
||||
index++;
|
||||
span[index] = 12;
|
||||
return list3;
|
||||
}
|
||||
case 13u:
|
||||
{
|
||||
int index = 1;
|
||||
List<ushort> list2 = new List<ushort>(index);
|
||||
CollectionsMarshal.SetCount(list2, index);
|
||||
span = CollectionsMarshal.AsSpan(list2);
|
||||
int num = 0;
|
||||
span[num] = 0;
|
||||
return list2;
|
||||
}
|
||||
case 17u:
|
||||
{
|
||||
int num = 1;
|
||||
List<ushort> list = new List<ushort>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
span = CollectionsMarshal.AsSpan(list);
|
||||
int index = 0;
|
||||
span[index] = 13;
|
||||
return list;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool OnErrorToast(SeString message)
|
||||
{
|
||||
string b = dataManager.GetString(709u, (LogMessage x) => x.Text);
|
||||
if (GameFunctions.GameStringEquals(message.TextValue, b))
|
||||
{
|
||||
_attempts = 3;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool ShouldInterruptOnDamage()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue