muffin v7.4.15
This commit is contained in:
parent
9bf3dbdf69
commit
0b1b2d38c7
14 changed files with 1215 additions and 1057 deletions
|
|
@ -52,6 +52,11 @@
|
|||
},
|
||||
"minItems": 1
|
||||
},
|
||||
"RequiredQuestId": {
|
||||
"description": "Quest ID that must be completed before this FATE can be farmed",
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"RequiredStatusId": {
|
||||
"description": "Status effect required to participate in the FATE",
|
||||
"type": "string"
|
||||
|
|
@ -65,6 +70,10 @@
|
|||
"description": "Position of the transform NPC",
|
||||
"$ref": "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/Questionable.Model/common-vector3.json"
|
||||
},
|
||||
"StopAction": {
|
||||
"description": "Action to use when stopping FATE farming (e.g. to remove a transformation debuff). Only used if the player has RequiredStatusId.",
|
||||
"type": "string"
|
||||
},
|
||||
"EventExpiry": {
|
||||
"description": "If this is a seasonal/event FATE, the date and time (in UTC) when it is no longer available. Date-only values are treated as ending at daily reset (14:59:59 UTC).",
|
||||
"format": "date-time",
|
||||
|
|
|
|||
|
|
@ -478824,10 +478824,7 @@ public static class AssemblyQuestLoader
|
|||
reference212 = obj228;
|
||||
index2++;
|
||||
ref QuestStep reference213 = ref span297[index2];
|
||||
QuestStep obj229 = new QuestStep(EInteractionType.FateAction, null, new Vector3(-38.322124f, 3.9999998f, -144.23155f), 130)
|
||||
{
|
||||
Comment = "Use correct Cheer Rhythm color on each randomly-appearing performer NPC"
|
||||
};
|
||||
QuestStep questStep20 = new QuestStep(EInteractionType.FateAction, null, new Vector3(-38.322124f, 3.9999998f, -144.23155f), 130);
|
||||
index3 = 4;
|
||||
List<FateActionTarget> list299 = new List<FateActionTarget>(index3);
|
||||
CollectionsMarshal.SetCount(list299, index3);
|
||||
|
|
@ -478856,13 +478853,13 @@ public static class AssemblyQuestLoader
|
|||
DataId = 18859u,
|
||||
Action = EAction.CheerRhythmRed
|
||||
};
|
||||
obj229.FateActionTargets = list299;
|
||||
reference213 = obj229;
|
||||
questStep20.FateActionTargets = list299;
|
||||
reference213 = questStep20;
|
||||
obj227.Steps = list297;
|
||||
reference211 = obj227;
|
||||
num++;
|
||||
ref QuestSequence reference214 = ref span287[num];
|
||||
QuestSequence obj230 = new QuestSequence
|
||||
QuestSequence obj229 = new QuestSequence
|
||||
{
|
||||
Sequence = byte.MaxValue
|
||||
};
|
||||
|
|
@ -478875,8 +478872,8 @@ public static class AssemblyQuestLoader
|
|||
{
|
||||
NextQuestId = new QuestId(5445)
|
||||
};
|
||||
obj230.Steps = list300;
|
||||
reference214 = obj230;
|
||||
obj229.Steps = list300;
|
||||
reference214 = obj229;
|
||||
questRoot25.QuestSequence = list287;
|
||||
AddQuest(questId25, questRoot25);
|
||||
QuestId questId26 = new QuestId(5445);
|
||||
|
|
@ -478896,7 +478893,7 @@ public static class AssemblyQuestLoader
|
|||
Span<QuestSequence> span302 = CollectionsMarshal.AsSpan(list302);
|
||||
num = 0;
|
||||
ref QuestSequence reference215 = ref span302[num];
|
||||
QuestSequence obj231 = new QuestSequence
|
||||
QuestSequence obj230 = new QuestSequence
|
||||
{
|
||||
Sequence = 0
|
||||
};
|
||||
|
|
@ -478916,11 +478913,11 @@ public static class AssemblyQuestLoader
|
|||
}
|
||||
}
|
||||
};
|
||||
obj231.Steps = list303;
|
||||
reference215 = obj231;
|
||||
obj230.Steps = list303;
|
||||
reference215 = obj230;
|
||||
num++;
|
||||
ref QuestSequence reference216 = ref span302[num];
|
||||
QuestSequence obj232 = new QuestSequence
|
||||
QuestSequence obj231 = new QuestSequence
|
||||
{
|
||||
Sequence = 1
|
||||
};
|
||||
|
|
@ -478930,11 +478927,11 @@ public static class AssemblyQuestLoader
|
|||
Span<QuestStep> span304 = CollectionsMarshal.AsSpan(list304);
|
||||
num2 = 0;
|
||||
span304[num2] = new QuestStep(EInteractionType.Interact, 1056476u, new Vector3(-35.1416f, 5.000001f, -130.38837f), 130);
|
||||
obj232.Steps = list304;
|
||||
reference216 = obj232;
|
||||
obj231.Steps = list304;
|
||||
reference216 = obj231;
|
||||
num++;
|
||||
ref QuestSequence reference217 = ref span302[num];
|
||||
QuestSequence obj233 = new QuestSequence
|
||||
QuestSequence obj232 = new QuestSequence
|
||||
{
|
||||
Sequence = byte.MaxValue
|
||||
};
|
||||
|
|
@ -478944,8 +478941,8 @@ public static class AssemblyQuestLoader
|
|||
Span<QuestStep> span305 = CollectionsMarshal.AsSpan(list305);
|
||||
index2 = 0;
|
||||
span305[index2] = new QuestStep(EInteractionType.CompleteQuest, 1056476u, new Vector3(-35.1416f, 5.000001f, -130.38837f), 130);
|
||||
obj233.Steps = list305;
|
||||
reference217 = obj233;
|
||||
obj232.Steps = list305;
|
||||
reference217 = obj232;
|
||||
questRoot26.QuestSequence = list302;
|
||||
AddQuest(questId26, questRoot26);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,6 +218,10 @@ public sealed class ActionConverter : EnumConverter<EAction>
|
|||
{
|
||||
EAction.CheerRhythmYellow,
|
||||
"Cheer Rhythm: Yellow"
|
||||
},
|
||||
{
|
||||
EAction.CurtainCall,
|
||||
"Curtain Call"
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ public enum EAction
|
|||
CheerRhythmBlue = 44502,
|
||||
CheerRhythmGreen = 44503,
|
||||
CheerRhythmYellow = 44504,
|
||||
CurtainCall = 11063,
|
||||
Prospect = 227,
|
||||
CollectMiner = 240,
|
||||
LuckOfTheMountaineer = 4081,
|
||||
|
|
|
|||
|
|
@ -31,5 +31,9 @@ public sealed class FateDefinition
|
|||
|
||||
public List<DialogueChoice>? TransformDialogueChoices { get; set; }
|
||||
|
||||
public ushort? RequiredQuestId { get; set; }
|
||||
|
||||
public EAction? StopAction { get; set; }
|
||||
|
||||
public DateTime? EventExpiry { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ internal static class FateAction
|
|||
}
|
||||
foreach (FateActionTarget target in base.Task.Targets)
|
||||
{
|
||||
IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId);
|
||||
IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId, null, warnIfMissing: false);
|
||||
if (gameObject != null && gameObject.IsTargetable)
|
||||
{
|
||||
bool flag = gameFunctions.UseAction(gameObject, target.Action);
|
||||
|
|
|
|||
|
|
@ -21,9 +21,12 @@ internal static class FateFarming
|
|||
{
|
||||
private DateTime _nextPollAt = DateTime.MinValue;
|
||||
|
||||
private bool _loggedWaitingForFate;
|
||||
|
||||
protected override bool Start()
|
||||
{
|
||||
logger.LogInformation("Waiting for FATE targets to appear ({Count} targets)", base.Task.Targets.Count);
|
||||
_loggedWaitingForFate = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -33,12 +36,24 @@ internal static class FateFarming
|
|||
{
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
ushort currentFateId = gameFunctions.GetCurrentFateId();
|
||||
if (currentFateId == 0)
|
||||
{
|
||||
if (!_loggedWaitingForFate)
|
||||
{
|
||||
logger.LogInformation("No active FATE yet, waiting for FATE to start before checking targets");
|
||||
_loggedWaitingForFate = true;
|
||||
}
|
||||
_nextPollAt = DateTime.Now.AddSeconds(1.0);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
_loggedWaitingForFate = false;
|
||||
foreach (FateActionTarget target in base.Task.Targets)
|
||||
{
|
||||
IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId);
|
||||
IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId, null, warnIfMissing: false);
|
||||
if (gameObject != null && gameObject.IsTargetable)
|
||||
{
|
||||
logger.LogInformation("FATE target {DataId} is now targetable", target.DataId);
|
||||
logger.LogInformation("FATE {FateId} active and target {DataId} is targetable", currentFateId, target.DataId);
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +101,7 @@ internal static class FateFarming
|
|||
}
|
||||
}
|
||||
|
||||
internal sealed record FateActionLoop(IReadOnlyList<FateActionTarget> Targets) : ITask
|
||||
internal sealed record FateActionLoop(IReadOnlyList<FateActionTarget> Targets, EStatus? RequiredStatusId = null) : ITask
|
||||
{
|
||||
public bool ShouldRedoOnInterrupt()
|
||||
{
|
||||
|
|
@ -103,12 +118,12 @@ internal static class FateFarming
|
|||
{
|
||||
private DateTime _nextActionAt = DateTime.MinValue;
|
||||
|
||||
private bool _fateWasActive;
|
||||
private ushort _trackedFateId;
|
||||
|
||||
protected override bool Start()
|
||||
{
|
||||
logger.LogInformation("Starting FATE action loop with {Count} targets", base.Task.Targets.Count);
|
||||
_fateWasActive = gameFunctions.GetCurrentFateId() != 0;
|
||||
_trackedFateId = gameFunctions.GetCurrentFateId();
|
||||
logger.LogInformation("Starting FATE action loop with {Count} targets, tracking FATE {FateId}", base.Task.Targets.Count, _trackedFateId);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -118,33 +133,31 @@ internal static class FateFarming
|
|||
{
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
bool flag = gameFunctions.GetCurrentFateId() != 0;
|
||||
if (_fateWasActive && !flag)
|
||||
if (base.Task.RequiredStatusId.HasValue && !gameFunctions.HasStatus(base.Task.RequiredStatusId.Value))
|
||||
{
|
||||
bool flag2 = false;
|
||||
foreach (FateActionTarget target in base.Task.Targets)
|
||||
logger.LogInformation("Required status {StatusId} lost during FATE action loop, ending cycle to re-apply", base.Task.RequiredStatusId.Value);
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
if (_trackedFateId == 0)
|
||||
{
|
||||
_trackedFateId = gameFunctions.GetCurrentFateId();
|
||||
if (_trackedFateId != 0)
|
||||
{
|
||||
IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId);
|
||||
if (gameObject != null && gameObject.IsTargetable)
|
||||
{
|
||||
flag2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag2)
|
||||
{
|
||||
logger.LogInformation("FATE completed (was active, now inactive, no targetable NPCs)");
|
||||
return ETaskResult.TaskComplete;
|
||||
logger.LogInformation("Now tracking FATE {FateId}", _trackedFateId);
|
||||
}
|
||||
}
|
||||
_fateWasActive = flag;
|
||||
foreach (FateActionTarget target2 in base.Task.Targets)
|
||||
if (_trackedFateId != 0 && !gameFunctions.IsFateStillActive(_trackedFateId))
|
||||
{
|
||||
IGameObject gameObject2 = gameFunctions.FindObjectByDataId(target2.DataId);
|
||||
if (gameObject2 != null && gameObject2.IsTargetable)
|
||||
logger.LogInformation("FATE {FateId} is no longer running, cycle complete", _trackedFateId);
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
foreach (FateActionTarget target in base.Task.Targets)
|
||||
{
|
||||
IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId, null, warnIfMissing: false);
|
||||
if (gameObject != null && gameObject.IsTargetable)
|
||||
{
|
||||
bool flag3 = gameFunctions.UseAction(gameObject2, target2.Action);
|
||||
_nextActionAt = (flag3 ? DateTime.Now.AddSeconds(2.5) : DateTime.Now.AddSeconds(0.5));
|
||||
bool flag = gameFunctions.UseAction(gameObject, target.Action);
|
||||
_nextActionAt = (flag ? DateTime.Now.AddSeconds(2.5) : DateTime.Now.AddSeconds(0.5));
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,13 +107,13 @@ internal static class Interact
|
|||
|
||||
public SkipStepConditions? SkipConditions { get; init; }
|
||||
|
||||
public EStatus? RequiredStatusId { get; init; }
|
||||
public EStatus? CompletionStatusId { get; init; }
|
||||
|
||||
public List<QuestWorkValue?> CompletionQuestVariablesFlags { get; }
|
||||
|
||||
public bool HasCompletionQuestVariablesFlags { get; }
|
||||
|
||||
public Task(uint DataId, Quest? Quest, EInteractionType InteractionType, bool SkipMarkerCheck = false, uint? PickUpItemId = null, byte? TaxiStandId = null, SkipStepConditions? SkipConditions = null, List<QuestWorkValue?>? CompletionQuestVariablesFlags = null, EStatus? RequiredStatusId = null)
|
||||
public Task(uint DataId, Quest? Quest, EInteractionType InteractionType, bool SkipMarkerCheck = false, uint? PickUpItemId = null, byte? TaxiStandId = null, SkipStepConditions? SkipConditions = null, List<QuestWorkValue?>? CompletionQuestVariablesFlags = null, EStatus? CompletionStatusId = null)
|
||||
{
|
||||
this.DataId = DataId;
|
||||
this.Quest = Quest;
|
||||
|
|
@ -122,7 +122,7 @@ internal static class Interact
|
|||
this.PickUpItemId = PickUpItemId;
|
||||
this.TaxiStandId = TaxiStandId;
|
||||
this.SkipConditions = SkipConditions;
|
||||
this.RequiredStatusId = RequiredStatusId;
|
||||
this.CompletionStatusId = CompletionStatusId;
|
||||
this.CompletionQuestVariablesFlags = CompletionQuestVariablesFlags ?? new List<QuestWorkValue>();
|
||||
HasCompletionQuestVariablesFlags = Quest != null && CompletionQuestVariablesFlags != null && QuestWorkUtils.HasCompletionFlags(CompletionQuestVariablesFlags);
|
||||
base._002Ector();
|
||||
|
|
@ -139,7 +139,7 @@ internal static class Interact
|
|||
}
|
||||
|
||||
[CompilerGenerated]
|
||||
public void Deconstruct(out uint DataId, out Quest? Quest, out EInteractionType InteractionType, out bool SkipMarkerCheck, out uint? PickUpItemId, out byte? TaxiStandId, out SkipStepConditions? SkipConditions, out List<QuestWorkValue?>? CompletionQuestVariablesFlags, out EStatus? RequiredStatusId)
|
||||
public void Deconstruct(out uint DataId, out Quest? Quest, out EInteractionType InteractionType, out bool SkipMarkerCheck, out uint? PickUpItemId, out byte? TaxiStandId, out SkipStepConditions? SkipConditions, out List<QuestWorkValue?>? CompletionQuestVariablesFlags, out EStatus? CompletionStatusId)
|
||||
{
|
||||
DataId = this.DataId;
|
||||
Quest = this.Quest;
|
||||
|
|
@ -149,7 +149,7 @@ internal static class Interact
|
|||
TaxiStandId = this.TaxiStandId;
|
||||
SkipConditions = this.SkipConditions;
|
||||
CompletionQuestVariablesFlags = this.CompletionQuestVariablesFlags;
|
||||
RequiredStatusId = this.RequiredStatusId;
|
||||
CompletionStatusId = this.CompletionStatusId;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,10 +228,10 @@ internal static class Interact
|
|||
}
|
||||
_needsUnmount = false;
|
||||
}
|
||||
EStatus? requiredStatusId = base.Task.RequiredStatusId;
|
||||
if (requiredStatusId.HasValue)
|
||||
EStatus? completionStatusId = base.Task.CompletionStatusId;
|
||||
if (completionStatusId.HasValue)
|
||||
{
|
||||
EStatus valueOrDefault = requiredStatusId.GetValueOrDefault();
|
||||
EStatus valueOrDefault = completionStatusId.GetValueOrDefault();
|
||||
if (gameFunctions.HasStatus(valueOrDefault))
|
||||
{
|
||||
return ETaskResult.TaskComplete;
|
||||
|
|
|
|||
|
|
@ -102,16 +102,12 @@ internal sealed class FateController : MiniTaskController<FateController>
|
|||
}
|
||||
if (_currentFate.RequiredStatusId.HasValue && _currentFate.TransformNpcDataId.HasValue && _currentFate.TransformNpcPosition.HasValue && !_gameFunctions.HasStatus(_currentFate.RequiredStatusId.Value))
|
||||
{
|
||||
ILogger<FateController> logger = _logger;
|
||||
object[] array = new object[1];
|
||||
EStatus? requiredStatusId = _currentFate.RequiredStatusId;
|
||||
array[0] = requiredStatusId.Value;
|
||||
logger.LogInformation("Player missing required status {StatusId}, enqueuing transform", array);
|
||||
_logger.LogInformation("Player missing required status {StatusId}, enqueuing transform", _currentFate.RequiredStatusId.Value);
|
||||
_taskQueue.Enqueue(new MoveTask(_currentFate.TerritoryId, _currentFate.TransformNpcPosition.Value, null, 3f));
|
||||
_taskQueue.Enqueue(new Mount.UnmountTask());
|
||||
TaskQueue taskQueue = _taskQueue;
|
||||
uint value = _currentFate.TransformNpcDataId.Value;
|
||||
requiredStatusId = _currentFate.RequiredStatusId.Value;
|
||||
EStatus? requiredStatusId = _currentFate.RequiredStatusId;
|
||||
taskQueue.Enqueue(new Interact.Task(value, null, EInteractionType.Interact, SkipMarkerCheck: true, null, null, null, null, requiredStatusId));
|
||||
_taskQueue.Enqueue(new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(2L)));
|
||||
}
|
||||
|
|
@ -119,7 +115,7 @@ internal sealed class FateController : MiniTaskController<FateController>
|
|||
_taskQueue.Enqueue(new Mount.UnmountTask());
|
||||
_taskQueue.Enqueue(new FateFarming.WaitForFateTargets(_currentFate.Targets));
|
||||
_taskQueue.Enqueue(new FateFarming.SyncFateLevel());
|
||||
_taskQueue.Enqueue(new FateFarming.FateActionLoop(_currentFate.Targets));
|
||||
_taskQueue.Enqueue(new FateFarming.FateActionLoop(_currentFate.Targets, _currentFate.RequiredStatusId));
|
||||
_taskQueue.Enqueue(new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(3L)));
|
||||
}
|
||||
}
|
||||
|
|
@ -129,6 +125,11 @@ internal sealed class FateController : MiniTaskController<FateController>
|
|||
if (_currentFate != null)
|
||||
{
|
||||
_logger.LogInformation("Stopping FATE farming: {Label} (completed {Cycles} cycles)", label, _completedCycles);
|
||||
if (_currentFate.StopAction.HasValue && _currentFate.RequiredStatusId.HasValue && _gameFunctions.HasStatus(_currentFate.RequiredStatusId.Value))
|
||||
{
|
||||
_logger.LogInformation("Using stop action {Action} to remove transformation", _currentFate.StopAction.Value);
|
||||
_gameFunctions.UseAction(_currentFate.StopAction.Value);
|
||||
}
|
||||
_currentFate = null;
|
||||
_completedCycles = 0;
|
||||
_cycleLimit = null;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -121,7 +121,7 @@ internal sealed class GameFunctions
|
|||
return false;
|
||||
}
|
||||
|
||||
public IGameObject? FindObjectByDataId(uint dataId, Dalamud.Game.ClientState.Objects.Enums.ObjectKind? kind = null)
|
||||
public IGameObject? FindObjectByDataId(uint dataId, Dalamud.Game.ClientState.Objects.Enums.ObjectKind? kind = null, bool warnIfMissing = true)
|
||||
{
|
||||
foreach (IGameObject item in _objectTable)
|
||||
{
|
||||
|
|
@ -132,7 +132,10 @@ internal sealed class GameFunctions
|
|||
return item;
|
||||
}
|
||||
}
|
||||
_logger.LogWarning("Could not find GameObject with dataId {DataId}", dataId);
|
||||
if (warnIfMissing)
|
||||
{
|
||||
_logger.LogWarning("Could not find GameObject with dataId {DataId}", dataId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -581,6 +584,25 @@ internal sealed class GameFunctions
|
|||
return ptr->CurrentFate->FateId;
|
||||
}
|
||||
|
||||
public unsafe bool IsFateStillActive(ushort fateId)
|
||||
{
|
||||
if (fateId == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FateManager* ptr = FateManager.Instance();
|
||||
if (ptr == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FateContext* fateById = ptr->GetFateById(fateId);
|
||||
if (fateById == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return fateById->State == FateState.Running;
|
||||
}
|
||||
|
||||
public uint GetItemLevel(uint itemId)
|
||||
{
|
||||
return (_dataManager.GetExcelSheet<Item>()?.GetRowOrDefault(itemId))?.LevelItem.RowId ?? 0;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,11 @@ internal sealed class ActiveQuestComponent
|
|||
|
||||
public void Draw(bool isMinimized)
|
||||
{
|
||||
if (_fateController.IsRunning)
|
||||
{
|
||||
DrawFateActive(isMinimized);
|
||||
return;
|
||||
}
|
||||
(QuestController.QuestProgress, QuestController.ECurrentQuestType)? currentQuestDetails = _questController.CurrentQuestDetails;
|
||||
QuestController.QuestProgress questProgress = currentQuestDetails?.Item1;
|
||||
QuestController.ECurrentQuestType? currentQuestType = currentQuestDetails?.Item2;
|
||||
|
|
@ -131,12 +136,12 @@ internal sealed class ActiveQuestComponent
|
|||
if (interactionType == EInteractionType.WaitForManualProgress || interactionType == EInteractionType.Snipe || interactionType == EInteractionType.Instruction)
|
||||
{
|
||||
flag = true;
|
||||
goto IL_0154;
|
||||
goto IL_0169;
|
||||
}
|
||||
}
|
||||
flag = false;
|
||||
goto IL_0154;
|
||||
IL_0154:
|
||||
goto IL_0169;
|
||||
IL_0169:
|
||||
if (flag)
|
||||
{
|
||||
color.Push(ImGuiCol.Text, ImGuiColors.DalamudOrange);
|
||||
|
|
@ -178,7 +183,7 @@ internal sealed class ActiveQuestComponent
|
|||
text2.AppendFormatted((item2 == 1) ? string.Empty : "s");
|
||||
text2.AppendLiteral(" - Leveling mode will start automatically");
|
||||
ImGui.TextColored(in col, text2);
|
||||
using (ImRaii.Disabled(_questController.IsRunning || !_autoDutyIpc.IsStopped()))
|
||||
using (ImRaii.Disabled(_questController.IsRunning || _fateController.IsRunning || !_autoDutyIpc.IsStopped()))
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
|
||||
{
|
||||
|
|
@ -247,6 +252,32 @@ internal sealed class ActiveQuestComponent
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawFateActive(bool isMinimized)
|
||||
{
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.ParsedGold))
|
||||
{
|
||||
ImU8String text = new ImU8String(6, 1);
|
||||
text.AppendLiteral("FATE: ");
|
||||
text.AppendFormatted(Shorten(_fateController.CurrentFate.Name));
|
||||
ImGui.TextUnformatted(text);
|
||||
}
|
||||
IList<string> remainingTaskNames = _fateController.GetRemainingTaskNames();
|
||||
if (remainingTaskNames.Count > 0)
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey, remainingTaskNames[0]);
|
||||
}
|
||||
if (!isMinimized)
|
||||
{
|
||||
string text2 = (_fateController.CycleLimit.HasValue ? $"Cycle {_fateController.CompletedCycles + 1} / {_fateController.CycleLimit}" : $"Cycle {_fateController.CompletedCycles + 1}");
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, text2);
|
||||
}
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop))
|
||||
{
|
||||
_fateController.Stop("UI stop");
|
||||
_movementController.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawQuestNames(QuestController.QuestProgress currentQuest, QuestController.ECurrentQuestType? currentQuestType)
|
||||
{
|
||||
if (currentQuestType == QuestController.ECurrentQuestType.Simulated)
|
||||
|
|
@ -563,7 +594,7 @@ internal sealed class ActiveQuestComponent
|
|||
|
||||
private void DrawQuestButtons(QuestController.QuestProgress currentQuest, QuestStep? currentStep, QuestProgressInfo? questProgressInfo, bool isMinimized)
|
||||
{
|
||||
using (ImRaii.Disabled(_questController.IsRunning))
|
||||
using (ImRaii.Disabled(_questController.IsRunning || _fateController.IsRunning))
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ using Dalamud.Interface.Windowing;
|
|||
using LLib.ImGui;
|
||||
using Questionable.Controller;
|
||||
using Questionable.Data;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
using Questionable.Windows.QuestComponents;
|
||||
|
||||
|
|
@ -28,17 +30,23 @@ internal sealed class FateSelectionWindow : LWindow
|
|||
|
||||
private readonly MovementController _movementController;
|
||||
|
||||
private readonly QuestFunctions _questFunctions;
|
||||
|
||||
private readonly QuestData _questData;
|
||||
|
||||
private readonly TerritoryData _territoryData;
|
||||
|
||||
private int _cycleLimit;
|
||||
|
||||
public FateSelectionWindow(FateController fateController, FateDefinitionRegistry fateDefinitionRegistry, QuestController questController, MovementController movementController, TerritoryData territoryData)
|
||||
public FateSelectionWindow(FateController fateController, FateDefinitionRegistry fateDefinitionRegistry, QuestController questController, MovementController movementController, QuestFunctions questFunctions, QuestData questData, TerritoryData territoryData)
|
||||
: base("FATE Farming###QuestionableFateFarming")
|
||||
{
|
||||
_fateController = fateController;
|
||||
_fateDefinitionRegistry = fateDefinitionRegistry;
|
||||
_questController = questController;
|
||||
_movementController = movementController;
|
||||
_questFunctions = questFunctions;
|
||||
_questData = questData;
|
||||
_territoryData = territoryData;
|
||||
base.Size = new Vector2(600f, 400f);
|
||||
base.SizeCondition = ImGuiCond.FirstUseEver;
|
||||
|
|
@ -335,12 +343,31 @@ internal sealed class FateSelectionWindow : LWindow
|
|||
|
||||
private void DrawFateRowActions(FateDefinition fate, bool disabled)
|
||||
{
|
||||
using (ImRaii.Disabled(disabled))
|
||||
bool flag = fate.RequiredQuestId.HasValue && !_questFunctions.IsQuestComplete(new QuestId(fate.RequiredQuestId.Value));
|
||||
ImU8String id = new ImU8String(5, 1);
|
||||
id.AppendLiteral("fate_");
|
||||
id.AppendFormatted(fate.Name);
|
||||
using (ImRaii.PushId(id))
|
||||
{
|
||||
ImU8String id = new ImU8String(5, 1);
|
||||
id.AppendLiteral("fate_");
|
||||
id.AppendFormatted(fate.Name);
|
||||
using (ImRaii.PushId(id))
|
||||
if (flag)
|
||||
{
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed, FontAwesomeIcon.Times.ToIconString());
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
IQuestInfo questInfo;
|
||||
string value = (_questData.TryGetQuestInfo(new QuestId(fate.RequiredQuestId.Value), out questInfo) ? questInfo.Name : fate.RequiredQuestId.Value.ToString(CultureInfo.InvariantCulture));
|
||||
ImU8String tooltip = new ImU8String(33, 1);
|
||||
tooltip.AppendLiteral("Requires \"");
|
||||
tooltip.AppendFormatted(value);
|
||||
tooltip.AppendLiteral("\" to be completed first");
|
||||
ImGui.SetTooltip(tooltip);
|
||||
}
|
||||
return;
|
||||
}
|
||||
using (ImRaii.Disabled(disabled))
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
|
||||
{
|
||||
|
|
@ -350,16 +377,16 @@ internal sealed class FateSelectionWindow : LWindow
|
|||
_fateController.Start(fate, cycleLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disabled && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||
{
|
||||
if (_fateController.IsRunning)
|
||||
if (disabled && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||
{
|
||||
ImGui.SetTooltip("Already farming a FATE");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.SetTooltip("Stop quest automation first");
|
||||
if (_fateController.IsRunning)
|
||||
{
|
||||
ImGui.SetTooltip("Already farming a FATE");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.SetTooltip("Stop quest automation first");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
|||
{
|
||||
private static readonly Version PluginVersion = typeof(QuestionablePlugin).Assembly.GetName().Version;
|
||||
|
||||
private const string TestingSuffix = "";
|
||||
|
||||
private readonly IDalamudPluginInterface _pluginInterface;
|
||||
|
||||
private readonly QuestController _questController;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue