1
0
forked from liza/Questionable

Moonfire Faire + add logic for skipping steps depending on (un)locked aetherytes

This commit is contained in:
Liza 2024-08-09 00:53:05 +02:00
parent c9d9cfb787
commit d7ce9051f4
Signed by: liza
GPG Key ID: 7199F8D727D55F67
13 changed files with 385 additions and 6 deletions

View File

@ -0,0 +1,171 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "JerryWester",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1050816,
"Position": {
"X": 14.328186,
"Y": 45.665993,
"Z": 131.33435
},
"TerritoryId": 128,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "Limsa Lominsa",
"AethernetShortcut": [
"[Limsa Lominsa] Aetheryte Plaza",
"[Limsa Lominsa] The Aftcastle"
],
"SkipConditions": {
"AetheryteShortcutIf": {
"InSameTerritory": true,
"InTerritory": [
129
]
}
}
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1000868,
"Position": {
"X": -192.00433,
"Y": 0.9999907,
"Z": 211.68835
},
"TerritoryId": 129,
"InteractionType": "Interact",
"AethernetShortcut": [
"[Limsa Lominsa] The Aftcastle",
"[Limsa Lominsa] Fishermens' Guild"
],
"SkipConditions": {
"StepIf": {
"AetheryteUnlocked": "Eastern La Noscea - Costa Del Sol",
"InTerritory": [137]
},
"AethernetShortcutIf": {
"AetheryteUnlocked": "Eastern La Noscea - Costa Del Sol"
}
},
"TargetTerritoryId": 137
},
{
"TerritoryId": 137,
"InteractionType": "AttuneAetheryte",
"Aetheryte": "Eastern La Noscea - Costa Del Sol",
"SkipConditions": {
"StepIf": {
"AetheryteUnlocked": "Eastern La Noscea - Costa Del Sol"
}
}
},
{
"Position": {
"X": 732.0986,
"Y": 11.349089,
"Z": 262.19138
},
"TerritoryId": 137,
"InteractionType": "WalkTo"
},
{
"DataId": 1050817,
"Position": {
"X": 735.25586,
"Y": 11.306824,
"Z": 261.8601
},
"StopDistance": 5,
"TerritoryId": 137,
"InteractionType": "Interact",
"AetheryteShortcut": "Eastern La Noscea - Costa Del Sol",
"Fly": true
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1050818,
"Position": {
"X": 681.3915,
"Y": 9.601691,
"Z": 202.86865
},
"StopDistance": 5,
"TerritoryId": 137,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1050819,
"Position": {
"X": 770.13806,
"Y": 9.687993,
"Z": 246.29578
},
"TerritoryId": 137,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 4,
"Steps": [
{
"DataId": 2014098,
"Position": {
"X": 769.0698,
"Y": 9.719971,
"Z": 246.99768
},
"TerritoryId": 137,
"InteractionType": "Interact",
"DialogueChoices": [
{
"Type": "List",
"Prompt": "TEXT_FESSUX001_05182_Q1_000_000",
"Answer": "TEXT_FESSUX001_05182_A1_000_001"
}
]
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1050820,
"Position": {
"X": 695.46045,
"Y": 9.614362,
"Z": 295.70447
},
"TerritoryId": 137,
"InteractionType": "CompleteQuest",
"DialogueChoices": [
{
"Type": "List",
"Prompt": "TEXT_FESSUX001_05182_Q2_000_000",
"Answer": "TEXT_FESSUX001_05182_A2_000_001"
}
],
"NextQuestId": 5183
}
]
}
]
}

View File

@ -0,0 +1,115 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "JerryWester",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1050828,
"Position": {
"X": 694.5753,
"Y": 9.578133,
"Z": 297.59656
},
"StopDistance": 5,
"TerritoryId": 137,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1050824,
"Position": {
"X": 507.68274,
"Y": 9.541115,
"Z": 428.54944
},
"TerritoryId": 137,
"InteractionType": "Emote",
"Emote": "uchiwasshoi",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 1050825,
"Position": {
"X": 641.44336,
"Y": 11.697773,
"Z": 526.604
},
"TerritoryId": 137,
"InteractionType": "Emote",
"Emote": "uchiwasshoi",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1050829,
"Position": {
"X": 694.2092,
"Y": 9.619679,
"Z": 294.81946
},
"TerritoryId": 137,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 255,
"Steps": [
{
"Position": {
"X": 732.0986,
"Y": 11.349089,
"Z": 262.19138
},
"TerritoryId": 137,
"InteractionType": "WalkTo"
},
{
"DataId": 1050817,
"Position": {
"X": 735.25586,
"Y": 11.306824,
"Z": 261.8601
},
"TerritoryId": 137,
"InteractionType": "CompleteQuest",
"StopDistance": 5,
"DialogueChoices": [
{
"Type": "List",
"Prompt": "TEXT_FESSUX002_05183_Q1_000_000",
"Answer": "TEXT_FESSUX002_05183_A1_000_002"
}
]
}
]
}
]
}

View File

@ -236,6 +236,12 @@
"type": "number" "type": "number"
} }
}, },
"AetheryteLocked": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"AetheryteUnlocked": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"ExtraCondition": { "ExtraCondition": {
"type": "string", "type": "string",
"enum": [ "enum": [
@ -259,6 +265,12 @@
"items": { "items": {
"type": "integer" "type": "integer"
} }
},
"AetheryteLocked": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"AetheryteUnlocked": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
} }
}, },
"additionalProperties": false "additionalProperties": false
@ -271,6 +283,12 @@
}, },
"InSameTerritory": { "InSameTerritory": {
"type": "boolean" "type": "boolean"
},
"AetheryteLocked": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"AetheryteUnlocked": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
} }
}, },
"additionalProperties": false "additionalProperties": false
@ -694,7 +712,8 @@
"respect", "respect",
"lookout", "lookout",
"kneel", "kneel",
"bow" "bow",
"uchiwasshoi"
] ]
} }
} }

View File

@ -29,5 +29,6 @@ public sealed class EmoteConverter() : EnumConverter<EEmote>(Values)
{ EEmote.Lookout, "lookout" }, { EEmote.Lookout, "lookout" },
{ EEmote.Kneel, "kneel" }, { EEmote.Kneel, "kneel" },
{ EEmote.Bow, "bow" }, { EEmote.Bow, "bow" },
{ EEmote.Uchiwasshoi, "uchiwasshoi" },
}; };
} }

View File

@ -30,4 +30,5 @@ public enum EEmote
Lookout = 22, Lookout = 22,
Kneel = 19, Kneel = 19,
Bow = 5, Bow = 5,
Uchiwasshoi = 278,
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using Questionable.Model.Common;
namespace Questionable.Model.Questing; namespace Questionable.Model.Questing;
@ -7,4 +8,6 @@ public sealed class SkipAetheryteCondition
public bool Never { get; set; } public bool Never { get; set; }
public bool InSameTerritory { get; set; } public bool InSameTerritory { get; set; }
public List<ushort> InTerritory { get; set; } = new(); public List<ushort> InTerritory { get; set; } = new();
public EAetheryteLocation? AetheryteLocked { get; set; }
public EAetheryteLocation? AetheryteUnlocked { get; set; }
} }

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Questionable.Model.Common;
namespace Questionable.Model.Questing; namespace Questionable.Model.Questing;
@ -15,6 +16,8 @@ public sealed class SkipStepConditions
public SkipItemConditions? Item { get; set; } public SkipItemConditions? Item { get; set; }
public List<ElementId> QuestsAccepted { get; set; } = new(); public List<ElementId> QuestsAccepted { get; set; } = new();
public List<ElementId> QuestsCompleted { get; set; } = new(); public List<ElementId> QuestsCompleted { get; set; } = new();
public EAetheryteLocation? AetheryteLocked { get; set; }
public EAetheryteLocation? AetheryteUnlocked { get; set; }
public EExtraSkipCondition? ExtraCondition { get; set; } public EExtraSkipCondition? ExtraCondition { get; set; }
public bool HasSkipConditions() public bool HasSkipConditions()
@ -30,6 +33,8 @@ public sealed class SkipStepConditions
Item != null || Item != null ||
QuestsAccepted.Count > 0 || QuestsAccepted.Count > 0 ||
QuestsCompleted.Count > 0 || QuestsCompleted.Count > 0 ||
AetheryteLocked != null ||
AetheryteUnlocked != null ||
ExtraCondition != null; ExtraCondition != null;
} }

View File

@ -786,9 +786,23 @@ internal sealed class GameUiController : IDisposable
string questName = addon->AtkTextNode250->NodeText.ToString(); string questName = addon->AtkTextNode250->NodeText.ToString();
if (_questController.CurrentQuest is { Quest.Id: LeveId } && if (_questController.CurrentQuest is { Quest.Id: LeveId } &&
GameFunctions.GameStringEquals(_questController.CurrentQuest.Quest.Info.Name, questName)) GameFunctions.GameStringEquals(_questController.CurrentQuest.Quest.Info.Name, questName))
{
_logger.LogInformation("JournalResult has the current leve, auto-accepting it");
addon->FireCallbackInt(0); addon->FireCallbackInt(0);
else }
addon->FireCallbackInt(1); else if (_targetManager.Target is { } target)
{
var issuedLeves = _questData.GetAllByIssuerDataId(target.DataId)
.Where(x => x.QuestId is LeveId)
.ToList();
if (issuedLeves.Any(x => GameFunctions.GameStringEquals(x.Name, questName)))
{
_logger.LogInformation(
"JournalResult has a leve but not the one we're currently on, auto-declining it");
addon->FireCallbackInt(1);
}
}
} }
} }

View File

@ -63,6 +63,27 @@ internal static class AethernetShortcut
logger.LogInformation("Skipping aethernet shortcut because the target is in the same territory"); logger.LogInformation("Skipping aethernet shortcut because the target is in the same territory");
return false; return false;
} }
if (SkipConditions.InTerritory.Contains(clientState.TerritoryType))
{
logger.LogInformation(
"Skipping aethernet shortcut because the target is in the specified territory");
return false;
}
if (SkipConditions.AetheryteLocked != null &&
!gameFunctions.IsAetheryteUnlocked(SkipConditions.AetheryteLocked.Value))
{
logger.LogInformation("Skipping aethernet shortcut because the target aetheryte is locked");
return false;
}
if (SkipConditions.AetheryteUnlocked != null &&
gameFunctions.IsAetheryteUnlocked(SkipConditions.AetheryteUnlocked.Value))
{
logger.LogInformation("Skipping aethernet shortcut because the target aetheryte is unlocked");
return false;
}
} }
if (gameFunctions.IsAetheryteUnlocked(From) && if (gameFunctions.IsAetheryteUnlocked(From) &&

View File

@ -71,13 +71,27 @@ internal static class AetheryteShortcut
if (Step != null) if (Step != null)
{ {
var skipConditions = Step.SkipConditions?.AetheryteShortcutIf ?? new(); var skipConditions = Step.SkipConditions?.AetheryteShortcutIf ?? new();
if (skipConditions is { Never: false, InTerritory.Count: > 0 }) if (skipConditions is { Never: false })
{ {
if (skipConditions.InTerritory.Contains(territoryType)) if (skipConditions.InTerritory.Contains(territoryType))
{ {
logger.LogInformation("Skipping aetheryte teleport due to SkipCondition (InTerritory)"); logger.LogInformation("Skipping aetheryte teleport due to SkipCondition (InTerritory)");
return false; return false;
} }
if (skipConditions.AetheryteLocked != null &&
!gameFunctions.IsAetheryteUnlocked(skipConditions.AetheryteLocked.Value))
{
logger.LogInformation("Skipping aetheryte teleport due to SkipCondition (AetheryteLocked)");
return false;
}
if (skipConditions.AetheryteUnlocked != null &&
gameFunctions.IsAetheryteUnlocked(skipConditions.AetheryteUnlocked.Value))
{
logger.LogInformation("Skipping aetheryte teleport due to SkipCondition (AetheryteUnlocked)");
return false;
}
} }
if (ExpectedTerritoryId == territoryType) if (ExpectedTerritoryId == territoryType)

View File

@ -151,6 +151,20 @@ internal static class SkipCondition
return true; return true;
} }
if (SkipConditions.AetheryteLocked != null &&
!gameFunctions.IsAetheryteUnlocked(SkipConditions.AetheryteLocked.Value))
{
logger.LogInformation("Skipping step, as aetheryte is locked");
return true;
}
if (SkipConditions.AetheryteUnlocked != null &&
gameFunctions.IsAetheryteUnlocked(SkipConditions.AetheryteUnlocked.Value))
{
logger.LogInformation("Skipping step, as aetheryte is unlocked");
return true;
}
if (Step is { DataId: not null, InteractionType: EInteractionType.AttuneAetherCurrent } && if (Step is { DataId: not null, InteractionType: EInteractionType.AttuneAetherCurrent } &&
gameFunctions.IsAetherCurrentUnlocked(Step.DataId.Value)) gameFunctions.IsAetherCurrentUnlocked(Step.DataId.Value))
{ {

View File

@ -20,7 +20,6 @@ internal sealed class QuestData
..dataManager.GetExcelSheet<Quest>()! ..dataManager.GetExcelSheet<Quest>()!
.Where(x => x.RowId > 0) .Where(x => x.RowId > 0)
.Where(x => x.IssuerLocation.Row > 0) .Where(x => x.IssuerLocation.Row > 0)
.Where(x => x.Festival.Row == 0)
.Select(x => new QuestInfo(x)), .Select(x => new QuestInfo(x)),
..dataManager.GetExcelSheet<SatisfactionNpc>()! ..dataManager.GetExcelSheet<SatisfactionNpc>()!
.Where(x => x.RowId > 0) .Where(x => x.RowId > 0)
@ -50,7 +49,7 @@ internal sealed class QuestData
public List<QuestInfo> GetAllByJournalGenre(uint journalGenre) public List<QuestInfo> GetAllByJournalGenre(uint journalGenre)
{ {
return _quests.Values return _quests.Values
.Where(x => x is QuestInfo) .Where(x => x is QuestInfo { IsSeasonalEvent: false })
.Cast<QuestInfo>() .Cast<QuestInfo>()
.Where(x => x.JournalGenre == journalGenre) .Where(x => x.JournalGenre == journalGenre)
.OrderBy(x => x.SortKey) .OrderBy(x => x.SortKey)

View File

@ -53,6 +53,7 @@ internal sealed class QuestInfo : IQuestInfo
GrandCompany = (GrandCompany)quest.GrandCompany.Row; GrandCompany = (GrandCompany)quest.GrandCompany.Row;
BeastTribe = (EBeastTribe)quest.BeastTribe.Row; BeastTribe = (EBeastTribe)quest.BeastTribe.Row;
ClassJobs = QuestInfoUtils.AsList(quest.ClassJobCategory0.Value!); ClassJobs = QuestInfoUtils.AsList(quest.ClassJobCategory0.Value!);
IsSeasonalEvent = quest.Festival.Row != 0;
} }
@ -74,6 +75,7 @@ internal sealed class QuestInfo : IQuestInfo
public GrandCompany GrandCompany { get; } public GrandCompany GrandCompany { get; }
public EBeastTribe BeastTribe { get; } public EBeastTribe BeastTribe { get; }
public IReadOnlyList<EClassJob> ClassJobs { get; } public IReadOnlyList<EClassJob> ClassJobs { get; }
public bool IsSeasonalEvent { get; }
[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.Members)] [UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.Members)]
public enum QuestJoin : byte public enum QuestJoin : byte