master #3

Open
cacahuetes wants to merge 673 commits from liza/Questionable:master into cacahuetes-ShB-Healer
24 changed files with 387 additions and 44 deletions
Showing only changes of commit 6eddca6931 - Show all commits

View File

@ -128,6 +128,10 @@ internal static class SkipConditionsExtensions
skipAetheryteCondition.InSameTerritory, emptyAetheryte.InSameTerritory), skipAetheryteCondition.InSameTerritory, emptyAetheryte.InSameTerritory),
AssignmentList(nameof(SkipAetheryteCondition.InTerritory), AssignmentList(nameof(SkipAetheryteCondition.InTerritory),
skipAetheryteCondition.InTerritory), skipAetheryteCondition.InTerritory),
AssignmentList(nameof(SkipAetheryteCondition.QuestsAccepted),
skipAetheryteCondition.QuestsAccepted),
AssignmentList(nameof(skipAetheryteCondition.QuestsCompleted),
skipAetheryteCondition.QuestsCompleted),
Assignment(nameof(SkipAetheryteCondition.AetheryteLocked), Assignment(nameof(SkipAetheryteCondition.AetheryteLocked),
skipAetheryteCondition.AetheryteLocked, emptyAetheryte.AetheryteLocked) skipAetheryteCondition.AetheryteLocked, emptyAetheryte.AetheryteLocked)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),

View File

@ -102,7 +102,8 @@
"Z": 342.85498 "Z": 342.85498
}, },
"TerritoryId": 1188, "TerritoryId": 1188,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest",
"Mount": true
} }
] ]
} }

View File

@ -20,6 +20,15 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"Position": {
"X": 323.5058,
"Y": -16.330368,
"Z": -254.18399
},
"TerritoryId": 1190,
"InteractionType": "WalkTo"
},
{ {
"DataId": 1050656, "DataId": 1050656,
"Position": { "Position": {

View File

@ -28,7 +28,8 @@
"Z": 427.2068 "Z": 427.2068
}, },
"TerritoryId": 1190, "TerritoryId": 1190,
"InteractionType": "Interact" "InteractionType": "Interact",
"Mount": true
} }
] ]
}, },
@ -50,6 +51,27 @@
{ {
"Sequence": 3, "Sequence": 3,
"Steps": [ "Steps": [
{
"Position": {
"X": 369.3906,
"Y": 5.9371996,
"Z": 417.16574
},
"TerritoryId": 1190,
"InteractionType": "WalkTo",
"$": "Shaaloani Hhusatahwi Saloon Stairs (top)"
},
{
"Position": {
"X": 359.11545,
"Y": 1.9823306,
"Z": 419.5714
},
"TerritoryId": 1190,
"InteractionType": "WalkTo",
"$": "Shaaloani Hhusatahwi Saloon Stairs (bottom)",
"DisableNavmesh": true
},
{ {
"DataId": 1051286, "DataId": 1051286,
"Position": { "Position": {

View File

@ -174,6 +174,17 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"DataId": 2013948,
"Position": {
"X": 610.7728,
"Y": 9.597839,
"Z": 233.05103
},
"TerritoryId": 1189,
"InteractionType": "AttuneAetherCurrent",
"AetherCurrentId": 2818440
},
{ {
"DataId": 1051073, "DataId": 1051073,
"Position": { "Position": {

View File

@ -151,13 +151,21 @@
"Steps": [ "Steps": [
{ {
"Position": { "Position": {
"X": -510.96463, "X": -510.37933,
"Y": -0.47684515, "Y": -0.39999998,
"Z": -305.96155 "Z": -277.78192
}, },
"TerritoryId": 1188, "TerritoryId": 1188,
"InteractionType": "WalkTo", "InteractionType": "WalkTo"
"Comment": "Waypoint after swimming through the river" },
{
"Position": {
"X": -521.0261,
"Y": -0.40000004,
"Z": -329.19336
},
"TerritoryId": 1188,
"InteractionType": "WalkTo"
}, },
{ {
"DataId": 2013936, "DataId": 2013936,

View File

@ -12,7 +12,7 @@
"Y": 9.773315, "Y": 9.773315,
"Z": -533.135 "Z": -533.135
}, },
"StopDistance": 5, "StopDistance": 7,
"TerritoryId": 1188, "TerritoryId": 1188,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }
@ -135,6 +135,28 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"DataId": 1048782,
"Position": {
"X": -68.52832,
"Y": 6.536739,
"Z": -486.53394
},
"TerritoryId": 1188,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5064
},
{
"DataId": 1051237,
"Position": {
"X": -251.20929,
"Y": 5.5572896,
"Z": -554.89435
},
"TerritoryId": 1188,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5081
},
{ {
"DataId": 1046537, "DataId": 1046537,
"Position": { "Position": {

View File

@ -21,6 +21,11 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"TerritoryId": 1187,
"InteractionType": "AttuneAetheryte",
"Aetheryte": "Urqopacha - Wachunpelo"
},
{ {
"DataId": 1046557, "DataId": 1046557,
"Position": { "Position": {
@ -39,11 +44,6 @@
128 128
] ]
}, },
{
"TerritoryId": 1187,
"InteractionType": "AttuneAetheryte",
"Aetheryte": "Urqopacha - Wachunpelo"
},
{ {
"DataId": 1046559, "DataId": 1046559,
"Position": { "Position": {

View File

@ -52,6 +52,30 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"DataId": 1050684,
"Position": {
"X": 391.37854,
"Y": -156.07434,
"Z": -388.50995
},
"TerritoryId": 1187,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5039,
"Comment": "Traveler to the Rescue"
},
{
"DataId": 1051195,
"Position": {
"X": 383.29138,
"Y": -154.50243,
"Z": -420.49292
},
"TerritoryId": 1187,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5051,
"Comment": "Crisis of Corruption"
},
{ {
"DataId": 1046537, "DataId": 1046537,
"Position": { "Position": {

View File

@ -100,7 +100,7 @@
"Y": -19.725424, "Y": -19.725424,
"Z": 203.72314 "Z": 203.72314
}, },
"StopDistance": 5, "StopDistance": 7,
"TerritoryId": 1185, "TerritoryId": 1185,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest"
} }

View File

@ -15,6 +15,7 @@
"Y": -19.725424, "Y": -19.725424,
"Z": 203.72314 "Z": 203.72314
}, },
"StopDistance": 7,
"TerritoryId": 1185, "TerritoryId": 1185,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }

View File

@ -63,6 +63,28 @@
{ {
"Sequence": 3, "Sequence": 3,
"Steps": [ "Steps": [
{
"DataId": 1051263,
"Position": {
"X": -521.0193,
"Y": 121.63345,
"Z": 319.38647
},
"TerritoryId": 1188,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5085
},
{
"DataId": 1048855,
"Position": {
"X": -491.63043,
"Y": 121.63846,
"Z": 271.50366
},
"TerritoryId": 1188,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5074
},
{ {
"DataId": 1046876, "DataId": 1046876,
"Position": { "Position": {

View File

@ -12,6 +12,7 @@
"Y": 119.49004, "Y": 119.49004,
"Z": 190.72253 "Z": 190.72253
}, },
"StopDistance": 5,
"TerritoryId": 1188, "TerritoryId": 1188,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }
@ -29,7 +30,8 @@
}, },
"TerritoryId": 1188, "TerritoryId": 1188,
"InteractionType": "Interact", "InteractionType": "Interact",
"AetheryteShortcut": "Kozama'uka - Earthenshire" "AetheryteShortcut": "Kozama'uka - Earthenshire",
"Fly": true
} }
] ]
}, },
@ -44,7 +46,8 @@
}, },
"TerritoryId": 1188, "TerritoryId": 1188,
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"TargetTerritoryId": 1187 "TargetTerritoryId": 1187,
"Fly": true
}, },
{ {
"DataId": 1046814, "DataId": 1046814,

View File

@ -21,6 +21,30 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1051207,
"Position": {
"X": 425.07043,
"Y": 118.935005,
"Z": 606.13403
},
"StopDistance": 5,
"TerritoryId": 1187,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5055
},
{
"DataId": 1048730,
"Position": {
"X": 399.0692,
"Y": 122.53533,
"Z": 542.9922
},
"StopDistance": 5,
"TerritoryId": 1187,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5047
},
{ {
"DataId": 1046926, "DataId": 1046926,
"Position": { "Position": {

View File

@ -21,6 +21,36 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1050872,
"Position": {
"X": -408.71295,
"Y": 20.420113,
"Z": -398.8861
},
"TerritoryId": 1189,
"InteractionType": "AcceptQuest",
"DialogueChoices": [
{
"Type": "List",
"ExcelSheet": "quest/051/KinGzd201_05110",
"Prompt": "TEXT_KINGZD201_05110_Q1_000_000",
"Answer": "TEXT_KINGZD201_05110_A1_000_001"
}
],
"PickUpQuestId": 5110
},
{
"DataId": 1051073,
"Position": {
"X": 41.09253,
"Y": 8.205902,
"Z": -629.8467
},
"TerritoryId": 1189,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5094
},
{ {
"DataId": 1047577, "DataId": 1047577,
"Position": { "Position": {
@ -36,28 +66,6 @@
{ {
"Sequence": 2, "Sequence": 2,
"Steps": [ "Steps": [
{
"DataId": 2013948,
"Position": {
"X": 610.7728,
"Y": 9.597839,
"Z": 233.05103
},
"TerritoryId": 1189,
"InteractionType": "AttuneAetherCurrent",
"AetherCurrentId": 2818440
},
{
"Position": {
"X": 614.25964,
"Y": -29.554798,
"Z": 202.75368
},
"TerritoryId": 1189,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"Mount": false
},
{ {
"DataId": 1048230, "DataId": 1048230,
"Position": { "Position": {
@ -66,8 +74,7 @@
"Z": 214.83167 "Z": 214.83167
}, },
"TerritoryId": 1189, "TerritoryId": 1189,
"InteractionType": "Interact", "InteractionType": "Interact"
"DisableNavmesh": true
} }
] ]
}, },

View File

@ -24,6 +24,28 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1051052,
"Position": {
"X": 585.90063,
"Y": -142.49187,
"Z": 510.21594
},
"TerritoryId": 1189,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5103
},
{
"DataId": 1050884,
"Position": {
"X": 531.0597,
"Y": -142.49185,
"Z": 492.0271
},
"TerritoryId": 1189,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5114
},
{ {
"DataId": 1047701, "DataId": 1047701,
"Position": { "Position": {

View File

@ -52,6 +52,62 @@
{ {
"Sequence": 3, "Sequence": 3,
"Steps": [ "Steps": [
{
"DataId": 1050655,
"Position": {
"X": 289.02112,
"Y": -15.566031,
"Z": -478.78235
},
"TerritoryId": 1190,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5138
},
{
"Position": {
"X": 386.84927,
"Y": -0.84392637,
"Z": 435.0579
},
"TerritoryId": 1190,
"InteractionType": "WalkTo",
"AetheryteShortcut": "Shaaloani - Hhusatahwi",
"SkipConditions": {
"StepIf": {
"QuestsCompleted": [
5140
]
},
"AetheryteShortcutIf": {
"QuestsCompleted": [
5140
]
}
}
},
{
"DataId": 1051283,
"Position": {
"X": 374.19702,
"Y": -0.24794838,
"Z": 437.2472
},
"StopDistance": 6,
"TerritoryId": 1190,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5140
},
{
"DataId": 1049324,
"Position": {
"X": -108.659546,
"Y": 4.055336,
"Z": 319.5697
},
"TerritoryId": 1190,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5130
},
{ {
"DataId": 1047001, "DataId": 1047001,
"Position": { "Position": {
@ -61,6 +117,7 @@
}, },
"TerritoryId": 1190, "TerritoryId": 1190,
"InteractionType": "Interact", "InteractionType": "Interact",
"AetheryteShortcut": "Shaaloani - Sheshenewezi Springs",
"DialogueChoices": [ "DialogueChoices": [
{ {
"Type": "YesNo", "Type": "YesNo",

View File

@ -161,6 +161,17 @@
{ {
"Sequence": 7, "Sequence": 7,
"Steps": [ "Steps": [
{
"DataId": 1051316,
"Position": {
"X": -380.30066,
"Y": 18.718708,
"Z": -114.24432
},
"TerritoryId": 1190,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5144
},
{ {
"DataId": 1047082, "DataId": 1047082,
"Position": { "Position": {

View File

@ -234,13 +234,13 @@
"QuestsAccepted": { "QuestsAccepted": {
"type": "array", "type": "array",
"items": { "items": {
"type": "number" "type": ["number", "string"]
} }
}, },
"QuestsCompleted": { "QuestsCompleted": {
"type": "array", "type": "array",
"items": { "items": {
"type": "number" "type": ["number", "string"]
} }
}, },
"AetheryteLocked": { "AetheryteLocked": {
@ -290,6 +290,18 @@
"type": "integer" "type": "integer"
} }
}, },
"QuestsAccepted": {
"type": "array",
"items": {
"type": ["number", "string"]
}
},
"QuestsCompleted": {
"type": "array",
"items": {
"type": ["number", "string"]
}
},
"AetheryteLocked": { "AetheryteLocked": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte" "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
}, },

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Questionable.Model.Questing.Converter;
public sealed class ElementIdListConverter : JsonConverter<List<ElementId>>
{
public override List<ElementId> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException();
reader.Read();
List<ElementId> values = [];
while (reader.TokenType != JsonTokenType.EndArray)
{
if (reader.TokenType == JsonTokenType.Number)
values.Add(new QuestId(reader.GetUInt16()));
else
values.Add(ElementId.FromString(reader.GetString() ?? throw new JsonException()));
reader.Read();
}
return values;
}
public override void Write(Utf8JsonWriter writer, List<ElementId> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}

View File

@ -1,5 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization;
using Questionable.Model.Common; using Questionable.Model.Common;
using Questionable.Model.Questing.Converter;
namespace Questionable.Model.Questing; namespace Questionable.Model.Questing;
@ -8,6 +10,13 @@ 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();
[JsonConverter(typeof(ElementIdListConverter))]
public List<ElementId> QuestsAccepted { get; set; } = new();
[JsonConverter(typeof(ElementIdListConverter))]
public List<ElementId> QuestsCompleted { get; set; } = new();
public EAetheryteLocation? AetheryteLocked { get; set; } public EAetheryteLocation? AetheryteLocked { get; set; }
public EAetheryteLocation? AetheryteUnlocked { get; set; } public EAetheryteLocation? AetheryteUnlocked { get; set; }
public bool RequiredQuestVariablesNotMet { get; set; } public bool RequiredQuestVariablesNotMet { get; set; }

View File

@ -1,6 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.Json.Serialization;
using Questionable.Model.Common; using Questionable.Model.Common;
using Questionable.Model.Questing.Converter;
namespace Questionable.Model.Questing; namespace Questionable.Model.Questing;
@ -14,8 +16,13 @@ public sealed class SkipStepConditions
public List<ushort> InTerritory { get; set; } = new(); public List<ushort> InTerritory { get; set; } = new();
public List<ushort> NotInTerritory { get; set; } = new(); public List<ushort> NotInTerritory { get; set; } = new();
public SkipItemConditions? Item { get; set; } public SkipItemConditions? Item { get; set; }
[JsonConverter(typeof(ElementIdListConverter))]
public List<ElementId> QuestsAccepted { get; set; } = new(); public List<ElementId> QuestsAccepted { get; set; } = new();
[JsonConverter(typeof(ElementIdListConverter))]
public List<ElementId> QuestsCompleted { get; set; } = new(); public List<ElementId> QuestsCompleted { get; set; } = new();
public EAetheryteLocation? AetheryteLocked { get; set; } public EAetheryteLocation? AetheryteLocked { get; set; }
public EAetheryteLocation? AetheryteUnlocked { get; set; } public EAetheryteLocation? AetheryteUnlocked { get; set; }
public NearPositionCondition? NearPosition { get; set; } public NearPositionCondition? NearPosition { get; set; }

View File

@ -24,6 +24,7 @@ internal static class AethernetShortcut
MovementController movementController, MovementController movementController,
AetheryteFunctions aetheryteFunctions, AetheryteFunctions aetheryteFunctions,
GameFunctions gameFunctions, GameFunctions gameFunctions,
QuestFunctions questFunctions,
IClientState clientState, IClientState clientState,
AetheryteData aetheryteData, AetheryteData aetheryteData,
TerritoryData territoryData, TerritoryData territoryData,
@ -46,8 +47,8 @@ internal static class AethernetShortcut
public ITask Use(EAetheryteLocation from, EAetheryteLocation to, SkipAetheryteCondition? skipConditions = null) public ITask Use(EAetheryteLocation from, EAetheryteLocation to, SkipAetheryteCondition? skipConditions = null)
{ {
return new UseAethernetShortcut(from, to, skipConditions ?? new(), return new UseAethernetShortcut(from, to, skipConditions ?? new(),
loggerFactory.CreateLogger<UseAethernetShortcut>(), aetheryteFunctions, gameFunctions, clientState, loggerFactory.CreateLogger<UseAethernetShortcut>(), aetheryteFunctions, gameFunctions, questFunctions,
aetheryteData, territoryData, lifestreamIpc, movementController, condition); clientState, aetheryteData, territoryData, lifestreamIpc, movementController, condition);
} }
} }
@ -58,6 +59,7 @@ internal static class AethernetShortcut
ILogger<UseAethernetShortcut> logger, ILogger<UseAethernetShortcut> logger,
AetheryteFunctions aetheryteFunctions, AetheryteFunctions aetheryteFunctions,
GameFunctions gameFunctions, GameFunctions gameFunctions,
QuestFunctions questFunctions,
IClientState clientState, IClientState clientState,
AetheryteData aetheryteData, AetheryteData aetheryteData,
TerritoryData territoryData, TerritoryData territoryData,
@ -90,6 +92,20 @@ internal static class AethernetShortcut
return false; return false;
} }
if (skipConditions.QuestsCompleted.Count > 0 &&
skipConditions.QuestsCompleted.All(questFunctions.IsQuestComplete))
{
logger.LogInformation("Skipping aethernet shortcut, all prequisite quests are complete");
return true;
}
if (skipConditions.QuestsAccepted.Count > 0 &&
skipConditions.QuestsAccepted.All(questFunctions.IsQuestAccepted))
{
logger.LogInformation("Skipping aethernet shortcut, all prequisite quests are accepted");
return true;
}
if (skipConditions.AetheryteLocked != null && if (skipConditions.AetheryteLocked != null &&
!aetheryteFunctions.IsAetheryteUnlocked(skipConditions.AetheryteLocked.Value)) !aetheryteFunctions.IsAetheryteUnlocked(skipConditions.AetheryteLocked.Value))
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions; using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
@ -93,6 +94,20 @@ internal static class AetheryteShortcut
return true; return true;
} }
if (skipConditions.QuestsCompleted.Count > 0 &&
skipConditions.QuestsCompleted.All(questFunctions.IsQuestComplete))
{
logger.LogInformation("Skipping aetheryte, all prequisite quests are complete");
return true;
}
if (skipConditions.QuestsAccepted.Count > 0 &&
skipConditions.QuestsAccepted.All(questFunctions.IsQuestAccepted))
{
logger.LogInformation("Skipping aetheryte, all prequisite quests are accepted");
return true;
}
if (skipConditions.AetheryteLocked != null && if (skipConditions.AetheryteLocked != null &&
!aetheryteFunctions.IsAetheryteUnlocked(skipConditions.AetheryteLocked.Value)) !aetheryteFunctions.IsAetheryteUnlocked(skipConditions.AetheryteLocked.Value))
{ {