.AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.Status), step.Status, emptyStep.Status)
.AsSyntaxNodeOrToken(),
+ Assignment(nameof(QuestStep.TargetClass), step.TargetClass,
+ emptyStep.TargetClass)
+ .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.EnemySpawnType), step.EnemySpawnType,
emptyStep.EnemySpawnType)
.AsSyntaxNodeOrToken(),
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 478,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 478,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 478,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 478,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 613,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 613,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 635,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 635,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 886,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 886,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 886,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 886,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 820,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 820,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 962,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 962,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 816,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 816,
"InteractionType": "Gather",
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 956,
+ "InteractionType": "SwitchClass",
+ "TargetClass": "Blue Mage"
+ },
{
"TerritoryId": 956,
"InteractionType": "Gather",
"Craft",
"Gather",
"Snipe",
+ "SwitchClass",
"Instruction",
"AcceptQuest",
"CompleteQuest",
"Comment"
]
}
+ },
+ {
+ "if": {
+ "properties": {
+ "InteractionType": {
+ "const": "SwitchClass"
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "TargetClass": {
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/ClassJob"
+ }
+ },
+ "required": [
+ "TargetClass"
+ ]
+ }
}
]
}
{
private static readonly Dictionary<EExtendedClassJob, string> Values = new()
{
+ { EExtendedClassJob.None, "None" },
{ EExtendedClassJob.Gladiator, "Gladiator" },
{ EExtendedClassJob.Pugilist, "Pugilist" },
{ EExtendedClassJob.Marauder, "Marauder" },
{ EInteractionType.Craft, "Craft" },
{ EInteractionType.Gather, "Gather" },
{ EInteractionType.Snipe, "Snipe" },
+ { EInteractionType.SwitchClass, "SwitchClass" },
{ EInteractionType.Instruction, "Instruction" },
{ EInteractionType.AcceptQuest, "AcceptQuest" },
{ EInteractionType.CompleteQuest, "CompleteQuest" },
[JsonConverter(typeof(ExtendedClassJobConverter))]
public enum EExtendedClassJob
{
+ None,
Gladiator,
Pugilist,
Marauder,
DoH,
DoL,
}
+
Craft,
Gather,
Snipe,
+ SwitchClass,
/// <summary>
/// Needs to be manually continued.
public ChatMessage? ChatMessage { get; set; }
public EAction? Action { get; set; }
public EStatus? Status { get; set; }
+ public EExtendedClassJob TargetClass { get; set; } = EExtendedClassJob.None;
public EEnemySpawnType? EnemySpawnType { get; set; }
public List<uint> KillEnemyDataIds { get; set; } = [];
if (_gatheringData.TryGetCustomDeliveryNpc(itemId, out uint npcId))
{
- AddContextMenuEntry(args, itemId, npcId, EClassJob.Miner, "Mine");
- AddContextMenuEntry(args, itemId, npcId, EClassJob.Botanist, "Harvest");
+ AddContextMenuEntry(args, itemId, npcId, EExtendedClassJob.Miner, "Mine");
+ AddContextMenuEntry(args, itemId, npcId, EExtendedClassJob.Botanist, "Harvest");
}
}
- private void AddContextMenuEntry(IMenuOpenedArgs args, uint itemId, uint npcId, EClassJob classJob, string verb)
+ private void AddContextMenuEntry(IMenuOpenedArgs args, uint itemId, uint npcId, EExtendedClassJob extendedClassJob,
+ string verb)
{
EClassJob currentClassJob = (EClassJob)_clientState.LocalPlayer!.ClassJob.Id;
+ EClassJob classJob = ClassJobUtils.AsIndividualJobs(extendedClassJob).Single();
if (classJob != currentClassJob && currentClassJob is EClassJob.Miner or EClassJob.Botanist)
return;
Prefix = SeIconChar.Hyadelyn,
PrefixColor = 52,
Name = name,
- OnClicked = _ => StartGathering(npcId, itemId, quantityToGather, collectability),
+ OnClicked = _ => StartGathering(npcId, itemId, quantityToGather, collectability, extendedClassJob),
IsEnabled = string.IsNullOrEmpty(lockedReasonn),
});
}
- private void StartGathering(uint npcId, uint itemId, int quantity, ushort collectability)
+ private void StartGathering(uint npcId, uint itemId, int quantity, ushort collectability,
+ EExtendedClassJob extendedClassJob)
{
var info = (SatisfactionSupplyInfo)_questData.GetAllByIssuerDataId(npcId)
.Single(x => x is SatisfactionSupplyInfo);
if (_questRegistry.TryGetQuest(info.QuestId, out Quest? quest))
{
- var step = quest.FindSequence(0)!.Steps.Single(x => x.InteractionType == EInteractionType.Gather);
- step.ItemsToGather =
+ var sequence = quest.FindSequence(0)!;
+
+ var switchClassStep = sequence.Steps.Single(x => x.InteractionType == EInteractionType.SwitchClass);
+ switchClassStep.TargetClass = extendedClassJob;
+
+ var gatherStep = sequence.Steps.Single(x => x.InteractionType == EInteractionType.Gather);
+ gatherStep.ItemsToGather =
[
new GatheredItem
{
-using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Client.Game;
+using System.Linq;
+using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using LLib.GameData;
using Questionable.Controller.Steps.Common;
+using Questionable.Data;
+using Questionable.Model;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Shared;
internal static class SwitchClassJob
{
+ internal sealed class Factory : SimpleTaskFactory
+ {
+ public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
+ {
+ if (step.InteractionType != EInteractionType.SwitchClass)
+ return null;
+
+ EClassJob classJob = ClassJobUtils.AsIndividualJobs(step.TargetClass).Single();
+ return new Task(classJob);
+ }
+ }
internal sealed record Task(EClassJob ClassJob) : ITask
{
public override string ToString() => $"SwitchJob({ClassJob})";
.AddTaskExecutor<MoveToLandingLocation.Task, MoveToLandingLocation.MoveToLandingLocationExecutor>();
serviceCollection.AddTaskExecutor<DoGather.Task, DoGather.GatherExecutor>();
serviceCollection.AddTaskExecutor<DoGatherCollectable.Task, DoGatherCollectable.GatherCollectableExecutor>();
- serviceCollection.AddTaskExecutor<SwitchClassJob.Task, SwitchClassJob.SwitchClassJobExecutor>();
+ serviceCollection.AddTaskFactoryAndExecutor<SwitchClassJob.Task, SwitchClassJob.Factory,
+ SwitchClassJob.SwitchClassJobExecutor>();
serviceCollection.AddTaskExecutor<Mount.MountTask, Mount.MountExecutor>();
serviceCollection.AddTaskExecutor<Mount.UnmountTask, Mount.UnmountExecutor>();