forked from liza/Questionable
Add dubious free fantasia handling
This commit is contained in:
parent
caf336c078
commit
b46d0868bf
@ -152,6 +152,10 @@ internal static class SkipConditionsExtensions
|
||||
emptyAetheryte.RequiredQuestVariablesNotMet)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(skipAetheryteCondition.NearPosition), skipAetheryteCondition.NearPosition,
|
||||
emptyAetheryte.NearPosition).AsSyntaxNodeOrToken()))));
|
||||
emptyAetheryte.NearPosition)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(skipAetheryteCondition.ExtraCondition), skipAetheryteCondition.ExtraCondition,
|
||||
emptyAetheryte.ExtraCondition)
|
||||
.AsSyntaxNodeOrToken()))));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,33 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1052475,
|
||||
"Position": {
|
||||
"X": -22.354492,
|
||||
"Y": 10.13581,
|
||||
"Z": -241.41296
|
||||
},
|
||||
"TerritoryId": 133,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Gridania",
|
||||
"AethernetShortcut": [
|
||||
"[Gridania] Aetheryte Plaza",
|
||||
"[Gridania] Mih Khetto's Amphitheatre"
|
||||
],
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"ExtraCondition": "SkipFreeFantasia",
|
||||
"InSameTerritory": true,
|
||||
"InTerritory": [
|
||||
133
|
||||
]
|
||||
},
|
||||
"StepIf": {
|
||||
"ExtraCondition": "SkipFreeFantasia"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"DataId": 1051889,
|
||||
"Position": {
|
||||
@ -35,10 +62,16 @@
|
||||
},
|
||||
"TerritoryId": 131,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ul'dah",
|
||||
"AethernetShortcut": [
|
||||
"[Ul'dah] Adventurers' Guild",
|
||||
"[Ul'dah] Aetheryte Plaza",
|
||||
"[Ul'dah] Goldsmiths' Guild"
|
||||
]
|
||||
],
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -303,7 +303,8 @@
|
||||
"RisingStonesSolar",
|
||||
"RoguesGuild",
|
||||
"NotRoguesGuild",
|
||||
"DockStorehouse"
|
||||
"DockStorehouse",
|
||||
"SkipFreeFantasia"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -370,6 +371,12 @@
|
||||
"TerritoryId"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ExtraCondition": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"SkipFreeFantasia"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
@ -13,5 +13,6 @@ public sealed class SkipConditionConverter() : EnumConverter<EExtraSkipCondition
|
||||
{ EExtraSkipCondition.RoguesGuild, "RoguesGuild"},
|
||||
{ EExtraSkipCondition.NotRoguesGuild, "NotRoguesGuild"},
|
||||
{ EExtraSkipCondition.DockStorehouse, "DockStorehouse"},
|
||||
{ EExtraSkipCondition.SkipFreeFantasia, "SkipFreeFantasia" },
|
||||
};
|
||||
}
|
||||
|
@ -21,4 +21,6 @@ public enum EExtraSkipCondition
|
||||
/// Location for NIN quests in Eastern La Noscea; located far underneath the actual zone.
|
||||
/// </summary>
|
||||
DockStorehouse,
|
||||
|
||||
SkipFreeFantasia,
|
||||
}
|
||||
|
@ -21,4 +21,5 @@ public sealed class SkipAetheryteCondition
|
||||
public EAetheryteLocation? AetheryteUnlocked { get; set; }
|
||||
public bool RequiredQuestVariablesNotMet { get; set; }
|
||||
public NearPositionCondition? NearPosition { get; set; }
|
||||
public EExtraSkipCondition? ExtraCondition { get; set; }
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ internal sealed class Configuration : IPluginConfiguration
|
||||
public bool UseEscToCancelQuesting { get; set; } = true;
|
||||
public bool ShowIncompleteSeasonalEvents { get; set; } = true;
|
||||
public bool ConfigureTextAdvance { get; set; } = true;
|
||||
|
||||
// TODO Temporary setting for 7.1
|
||||
public bool PickUpFreeFantasia { get; set; } = true;
|
||||
}
|
||||
|
||||
internal sealed class DutyConfiguration
|
||||
|
@ -58,7 +58,7 @@ internal static class Interact
|
||||
|
||||
yield return new Task(step.DataId.Value, quest, step.InteractionType,
|
||||
step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId ||
|
||||
step.SkipConditions is { StepIf.Never: true } || step.InteractionType == EInteractionType.PurchaseItem,
|
||||
step.SkipConditions is { StepIf.Never: true } || step.InteractionType == EInteractionType.PurchaseItem || step.DataId == 1052475,
|
||||
step.PickUpItemId, step.SkipConditions?.StepIf, step.CompletionQuestVariablesFlags);
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,8 @@ internal static class AetheryteShortcut
|
||||
IClientState clientState,
|
||||
IChatGui chatGui,
|
||||
ICondition condition,
|
||||
AetheryteData aetheryteData) : TaskExecutor<Task>
|
||||
AetheryteData aetheryteData,
|
||||
ExtraConditionUtils extraConditionUtils) : TaskExecutor<Task>
|
||||
{
|
||||
private bool _teleported;
|
||||
private DateTime _continueAt;
|
||||
@ -148,6 +149,13 @@ internal static class AetheryteShortcut
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (skipConditions.ExtraCondition != null && skipConditions.ExtraCondition != EExtraSkipCondition.None &&
|
||||
extraConditionUtils.MatchesExtraCondition(skipConditions.ExtraCondition.Value))
|
||||
{
|
||||
logger.LogInformation("Skipping step, extra condition {} matches", skipConditions.ExtraCondition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Task.ExpectedTerritoryId == territoryType)
|
||||
|
75
Questionable/Controller/Steps/Shared/ExtraConditionUtils.cs
Normal file
75
Questionable/Controller/Steps/Shared/ExtraConditionUtils.cs
Normal file
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
namespace Questionable.Controller.Steps.Shared;
|
||||
|
||||
internal sealed class ExtraConditionUtils
|
||||
{
|
||||
private readonly Configuration _configuration;
|
||||
private readonly IClientState _clientState;
|
||||
private readonly ILogger<ExtraConditionUtils> _logger;
|
||||
|
||||
public ExtraConditionUtils(
|
||||
Configuration configuration,
|
||||
IClientState clientState,
|
||||
ILogger<ExtraConditionUtils> logger)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_clientState = clientState;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool MatchesExtraCondition(EExtraSkipCondition skipCondition)
|
||||
{
|
||||
var position = _clientState.LocalPlayer?.Position;
|
||||
return position != null &&
|
||||
_clientState.TerritoryType != 0 &&
|
||||
MatchesExtraCondition(skipCondition, position.Value, _clientState.TerritoryType);
|
||||
}
|
||||
|
||||
public bool MatchesExtraCondition(EExtraSkipCondition skipCondition, Vector3 position, ushort territoryType)
|
||||
{
|
||||
return skipCondition switch
|
||||
{
|
||||
EExtraSkipCondition.WakingSandsMainArea => territoryType == 212 && position.X < 24,
|
||||
EExtraSkipCondition.WakingSandsSolar => territoryType == 212 && position.X >= 24,
|
||||
EExtraSkipCondition.RisingStonesSolar => territoryType == 351 && position.Z <= -28,
|
||||
EExtraSkipCondition.RoguesGuild => territoryType == 129 && position.Y <= -115,
|
||||
EExtraSkipCondition.NotRoguesGuild => territoryType == 129 && position.Y > -115,
|
||||
EExtraSkipCondition.DockStorehouse => territoryType == 137 && position.Y <= -20,
|
||||
EExtraSkipCondition.SkipFreeFantasia => ShouldSkipFreeFantasia(),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(skipCondition), skipCondition, null)
|
||||
};
|
||||
}
|
||||
|
||||
private unsafe bool ShouldSkipFreeFantasia()
|
||||
{
|
||||
if (!_configuration.General.PickUpFreeFantasia)
|
||||
{
|
||||
_logger.LogInformation("Skipping fantasia step, as free fantasia is disabled in the configuration");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool foundFestival = false;
|
||||
for (int i = 0; i < GameMain.Instance()->ActiveFestivals.Length; ++i)
|
||||
{
|
||||
if (GameMain.Instance()->ActiveFestivals[i].Id == 160)
|
||||
{
|
||||
foundFestival = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundFestival)
|
||||
{
|
||||
_logger.LogInformation("Skipping fantasia step, as free fantasia moogle is not available");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
@ -56,9 +55,10 @@ internal static class SkipCondition
|
||||
GameFunctions gameFunctions,
|
||||
QuestFunctions questFunctions,
|
||||
IClientState clientState,
|
||||
ICondition condition) : TaskExecutor<SkipTask>
|
||||
ICondition condition,
|
||||
ExtraConditionUtils extraConditionUtils) : TaskExecutor<SkipTask>
|
||||
{
|
||||
protected override unsafe bool Start()
|
||||
protected override bool Start()
|
||||
{
|
||||
var skipConditions = Task.SkipConditions;
|
||||
var step = Task.Step;
|
||||
@ -66,6 +66,60 @@ internal static class SkipCondition
|
||||
|
||||
logger.LogInformation("Checking skip conditions; {ConfiguredConditions}", string.Join(",", skipConditions));
|
||||
|
||||
if (CheckFlyingCondition(step, skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckUnlockedMountCondition(skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckDivingCondition(skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckTerritoryCondition(skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckQuestConditions(skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckTargetableCondition(step, skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckNameplateCondition(step, skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckItemCondition(step, skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckAetheryteCondition(step, skipConditions))
|
||||
return true;
|
||||
|
||||
if (CheckAethernetCondition(step))
|
||||
return true;
|
||||
|
||||
if (CheckQuestWorkConditions(elementId, step))
|
||||
return true;
|
||||
|
||||
if (CheckJobCondition(step))
|
||||
return true;
|
||||
|
||||
if (CheckPositionCondition(skipConditions))
|
||||
return true;
|
||||
|
||||
if (skipConditions.ExtraCondition != null && skipConditions.ExtraCondition != EExtraSkipCondition.None &&
|
||||
extraConditionUtils.MatchesExtraCondition(skipConditions.ExtraCondition.Value))
|
||||
{
|
||||
logger.LogInformation("Skipping step, extra condition {} matches", skipConditions.ExtraCondition);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckPickUpTurnInQuestIds(step))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckFlyingCondition(QuestStep step, SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.Flying == ELockedSkipCondition.Unlocked &&
|
||||
gameFunctions.IsFlyingUnlocked(step.TerritoryId))
|
||||
{
|
||||
@ -80,6 +134,11 @@ internal static class SkipCondition
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private unsafe bool CheckUnlockedMountCondition(SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.Chocobo == ELockedSkipCondition.Unlocked &&
|
||||
PlayerState.Instance()->IsMountUnlocked(1))
|
||||
{
|
||||
@ -87,18 +146,11 @@ internal static class SkipCondition
|
||||
return true;
|
||||
}
|
||||
|
||||
if (skipConditions.Diving == true && condition[ConditionFlag.Diving])
|
||||
{
|
||||
logger.LogInformation("Skipping step, as you're currently diving underwater");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (skipConditions.Diving == false && !condition[ConditionFlag.Diving])
|
||||
{
|
||||
logger.LogInformation("Skipping step, as you're not currently diving underwater");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckTerritoryCondition(SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.InTerritory.Count > 0 &&
|
||||
skipConditions.InTerritory.Contains(clientState.TerritoryType))
|
||||
{
|
||||
@ -113,6 +165,28 @@ internal static class SkipCondition
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckDivingCondition(SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.Diving == true && condition[ConditionFlag.Diving])
|
||||
{
|
||||
logger.LogInformation("Skipping step, as you're currently diving underwater");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (skipConditions.Diving == false && !condition[ConditionFlag.Diving])
|
||||
{
|
||||
logger.LogInformation("Skipping step, as you're not currently diving underwater");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckQuestConditions(SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.QuestsCompleted.Count > 0 &&
|
||||
skipConditions.QuestsCompleted.All(questFunctions.IsQuestComplete))
|
||||
{
|
||||
@ -127,6 +201,11 @@ internal static class SkipCondition
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckTargetableCondition(QuestStep step, SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.NotTargetable &&
|
||||
step is { DataId: not null })
|
||||
{
|
||||
@ -146,6 +225,11 @@ internal static class SkipCondition
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private unsafe bool CheckNameplateCondition(QuestStep step, SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.NotNamePlateIconId.Count > 0 &&
|
||||
step is { DataId: not null })
|
||||
{
|
||||
@ -162,6 +246,11 @@ internal static class SkipCondition
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private unsafe bool CheckItemCondition(QuestStep step, SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.Item is { NotInInventory: true } && step is { ItemId: not null })
|
||||
{
|
||||
InventoryManager* inventoryManager = InventoryManager.Instance();
|
||||
@ -174,6 +263,11 @@ internal static class SkipCondition
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckAetheryteCondition(QuestStep step, SkipStepConditions skipConditions)
|
||||
{
|
||||
if (step is
|
||||
{
|
||||
DataId: not null,
|
||||
@ -199,6 +293,11 @@ internal static class SkipCondition
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckAethernetCondition(QuestStep step)
|
||||
{
|
||||
if (step is { DataId: not null, InteractionType: EInteractionType.AttuneAetherCurrent } &&
|
||||
gameFunctions.IsAetherCurrentUnlocked(step.DataId.Value))
|
||||
{
|
||||
@ -206,6 +305,11 @@ internal static class SkipCondition
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckQuestWorkConditions(ElementId elementId, QuestStep step)
|
||||
{
|
||||
QuestProgressInfo? questWork = questFunctions.GetQuestProgressInfo(elementId);
|
||||
if (questWork != null)
|
||||
{
|
||||
@ -249,6 +353,11 @@ internal static class SkipCondition
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckJobCondition(QuestStep step)
|
||||
{
|
||||
if (step is { RequiredCurrentJob.Count: > 0 })
|
||||
{
|
||||
List<EClassJob> expectedJobs =
|
||||
@ -263,6 +372,11 @@ internal static class SkipCondition
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckPositionCondition(SkipStepConditions skipConditions)
|
||||
{
|
||||
if (skipConditions.NearPosition is { } nearPosition &&
|
||||
clientState.TerritoryType == nearPosition.TerritoryId)
|
||||
{
|
||||
@ -274,19 +388,11 @@ internal static class SkipCondition
|
||||
}
|
||||
}
|
||||
|
||||
if (skipConditions.ExtraCondition != null && skipConditions.ExtraCondition != EExtraSkipCondition.None)
|
||||
{
|
||||
var position = clientState.LocalPlayer?.Position;
|
||||
if (position != null &&
|
||||
clientState.TerritoryType != 0 &&
|
||||
MatchesExtraCondition(skipConditions.ExtraCondition.Value, position.Value,
|
||||
clientState.TerritoryType))
|
||||
{
|
||||
logger.LogInformation("Skipping step, extra condition {} matches", skipConditions.ExtraCondition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckPickUpTurnInQuestIds(QuestStep step)
|
||||
{
|
||||
if (step.PickUpQuestId != null && questFunctions.IsQuestAcceptedOrComplete(step.PickUpQuestId))
|
||||
{
|
||||
logger.LogInformation("Skipping step, as we have already picked up the relevant quest");
|
||||
@ -302,20 +408,6 @@ internal static class SkipCondition
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool MatchesExtraCondition(EExtraSkipCondition condition, Vector3 position, ushort territoryType)
|
||||
{
|
||||
return condition switch
|
||||
{
|
||||
EExtraSkipCondition.WakingSandsMainArea => territoryType == 212 && position.X < 24,
|
||||
EExtraSkipCondition.WakingSandsSolar => territoryType == 212 && position.X >= 24,
|
||||
EExtraSkipCondition.RisingStonesSolar => territoryType == 351 && position.Z <= -28,
|
||||
EExtraSkipCondition.RoguesGuild => territoryType == 129 && position.Y <= -115,
|
||||
EExtraSkipCondition.NotRoguesGuild => territoryType == 129 && position.Y > -115,
|
||||
EExtraSkipCondition.DockStorehouse => territoryType == 137 && position.Y <= -20,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(condition), condition, null)
|
||||
};
|
||||
}
|
||||
|
||||
public override ETaskResult Update() => ETaskResult.SkipRemainingTasksForStep;
|
||||
|
||||
public override bool ShouldInterruptOnDamage() => false;
|
||||
|
@ -247,6 +247,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
||||
serviceCollection.AddTaskExecutor<WaitAtEnd.EndAutomation, WaitAtEnd.EndAutomationExecutor>();
|
||||
|
||||
serviceCollection.AddSingleton<TaskCreator>();
|
||||
serviceCollection.AddSingleton<ExtraConditionUtils>();
|
||||
}
|
||||
|
||||
private static void AddControllers(ServiceCollection serviceCollection)
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
@ -110,5 +111,18 @@ internal sealed class GeneralConfigComponent : ConfigComponent
|
||||
Configuration.General.ConfigureTextAdvance = configureTextAdvance;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.TextColored(ImGuiColors.DalamudYellow, "Patch 7.1 exclusive content");
|
||||
using (_ = ImRaii.PushIndent())
|
||||
{
|
||||
bool pickUpFreeFantasia = Configuration.General.PickUpFreeFantasia;
|
||||
if (ImGui.Checkbox("Try to pick up free limited-time fantasia during 'Little Ladies' Day' quests",
|
||||
ref pickUpFreeFantasia))
|
||||
{
|
||||
Configuration.General.PickUpFreeFantasia = pickUpFreeFantasia;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ internal sealed class EventInfoComponent
|
||||
[SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")]
|
||||
private readonly List<EventQuest> _eventQuests =
|
||||
[
|
||||
new("Valentione's Day", [new(5251)], AtDailyReset(new(2025, 2, 17))),
|
||||
new("Valentione's Day", [new(5237), new(5238)], AtDailyReset(new(2025, 3, 17))),
|
||||
];
|
||||
|
||||
private readonly QuestData _questData;
|
||||
|
Loading…
x
Reference in New Issue
Block a user