forked from liza/Questionable
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
59793d19dc | |||
2ada2fa9dc | |||
fe1d86bf5b | |||
71b40496fb | |||
224825b071 | |||
ed797143b3 | |||
22aa81cf75 | |||
dcdc288b08 | |||
a70e195a93 | |||
71e0b01dbc | |||
31eb121cf0 | |||
a75286e927 | |||
3820647827 | |||
097c67ed5d | |||
92873554cc | |||
b35ee13704 | |||
11cde2a2d6 | |||
04ab38cc59 | |||
c89b81f478 |
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,9 +1,9 @@
|
|||||||
[submodule "LLib"]
|
[submodule "LLib"]
|
||||||
path = LLib
|
path = LLib
|
||||||
url = https://git.carvel.li/liza/LLib.git
|
url = https://git.carvel.li/liza/LLib.git
|
||||||
[submodule "vendor/ECommons"]
|
|
||||||
path = vendor/ECommons
|
|
||||||
url = https://github.com/NightmareXIV/ECommons.git
|
|
||||||
[submodule "vendor/NotificationMasterAPI"]
|
[submodule "vendor/NotificationMasterAPI"]
|
||||||
path = vendor/NotificationMasterAPI
|
path = vendor/NotificationMasterAPI
|
||||||
url = https://github.com/NightmareXIV/NotificationMasterAPI.git
|
url = https://github.com/NightmareXIV/NotificationMasterAPI.git
|
||||||
|
[submodule "vendor/pictomancy"]
|
||||||
|
path = vendor/pictomancy
|
||||||
|
url = https://github.com/sourpuh/ffxiv_pictomancy
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup Condition="$(MSBuildProjectName) != 'GatheringPathRenderer'">
|
<PropertyGroup Condition="$(MSBuildProjectName) != 'GatheringPathRenderer'">
|
||||||
<Version>4.19</Version>
|
<Version>4.20</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\LLib\LLib.csproj" />
|
<ProjectReference Include="..\LLib\LLib.csproj" />
|
||||||
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj" />
|
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj" />
|
||||||
<ProjectReference Include="..\vendor\ECommons\ECommons\ECommons.csproj" />
|
<ProjectReference Include="..\vendor\pictomancy\Pictomancy\Pictomancy.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="..\LLib\LLib.targets"/>
|
<Import Project="..\LLib\LLib.targets"/>
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
"Name": "GatheringPathRenderer",
|
"Name": "GatheringPathRenderer",
|
||||||
"Author": "Liza Carvelli",
|
"Author": "Liza Carvelli",
|
||||||
"Punchline": "[Questionable dev plugin]: Renders gathering location.",
|
"Punchline": "[Questionable dev plugin]: Renders gathering location.",
|
||||||
"Description": "[Questionable dev plugin]: Renders gathering location using Splatoon.",
|
"Description": "[Questionable dev plugin]: Renders gathering location using Pictomancy.",
|
||||||
"RepoUrl": "https://git.carvel.li/liza/Questionable/src/branch/master/GatheringPathRenderer"
|
"RepoUrl": "https://git.carvel.li/liza/Questionable/src/branch/master/GatheringPathRenderer"
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
@ -13,11 +14,9 @@ using Dalamud.Game.ClientState.Objects;
|
|||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using ECommons;
|
|
||||||
using ECommons.Schedulers;
|
|
||||||
using ECommons.SplatoonAPI;
|
|
||||||
using GatheringPathRenderer.Windows;
|
using GatheringPathRenderer.Windows;
|
||||||
using LLib.GameData;
|
using LLib.GameData;
|
||||||
|
using Pictomancy;
|
||||||
using Questionable.Model.Gathering;
|
using Questionable.Model.Gathering;
|
||||||
|
|
||||||
namespace GatheringPathRenderer;
|
namespace GatheringPathRenderer;
|
||||||
@ -25,10 +24,8 @@ namespace GatheringPathRenderer;
|
|||||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||||
public sealed class RendererPlugin : IDalamudPlugin
|
public sealed class RendererPlugin : IDalamudPlugin
|
||||||
{
|
{
|
||||||
private const long OnTerritoryChange = -2;
|
|
||||||
|
|
||||||
private readonly WindowSystem _windowSystem = new(nameof(RendererPlugin));
|
private readonly WindowSystem _windowSystem = new(nameof(RendererPlugin));
|
||||||
private readonly List<uint> _colors = [0xFFFF2020, 0xFF20FF20, 0xFF2020FF, 0xFFFFFF20, 0xFFFF20FF, 0xFF20FFFF];
|
private readonly List<uint> _colors = [0x40FF2020, 0x4020FF20, 0x402020FF, 0x40FFFF20, 0x40FF20FF, 0x4020FFFF];
|
||||||
|
|
||||||
private readonly IDalamudPluginInterface _pluginInterface;
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
private readonly IClientState _clientState;
|
private readonly IClientState _clientState;
|
||||||
@ -58,7 +55,8 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
_editorCommands = new EditorCommands(this, dataManager, commandManager, targetManager, clientState, chatGui,
|
_editorCommands = new EditorCommands(this, dataManager, commandManager, targetManager, clientState, chatGui,
|
||||||
configuration);
|
configuration);
|
||||||
var configWindow = new ConfigWindow(pluginInterface, configuration);
|
var configWindow = new ConfigWindow(pluginInterface, configuration);
|
||||||
_editorWindow = new EditorWindow(this, _editorCommands, dataManager, targetManager, clientState, objectTable, configWindow)
|
_editorWindow = new EditorWindow(this, _editorCommands, dataManager, targetManager, clientState, objectTable,
|
||||||
|
configWindow)
|
||||||
{ IsOpen = true };
|
{ IsOpen = true };
|
||||||
_windowSystem.AddWindow(configWindow);
|
_windowSystem.AddWindow(configWindow);
|
||||||
_windowSystem.AddWindow(_editorWindow);
|
_windowSystem.AddWindow(_editorWindow);
|
||||||
@ -67,14 +65,12 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
_pluginInterface.GetIpcSubscriber<object>("Questionable.ReloadData")
|
_pluginInterface.GetIpcSubscriber<object>("Questionable.ReloadData")
|
||||||
.Subscribe(Reload);
|
.Subscribe(Reload);
|
||||||
|
|
||||||
ECommonsMain.Init(pluginInterface, this, Module.SplatoonAPI);
|
PictoService.Initialize(pluginInterface);
|
||||||
LoadGatheringLocationsFromDirectory();
|
LoadGatheringLocationsFromDirectory();
|
||||||
|
|
||||||
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
||||||
_clientState.TerritoryChanged += TerritoryChanged;
|
_pluginInterface.UiBuilder.Draw += Draw;
|
||||||
_clientState.ClassJobChanged += ClassJobChanged;
|
_clientState.ClassJobChanged += ClassJobChanged;
|
||||||
if (_clientState.IsLoggedIn)
|
|
||||||
TerritoryChanged(_clientState.TerritoryType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DirectoryInfo PathsDirectory
|
internal DirectoryInfo PathsDirectory
|
||||||
@ -93,7 +89,8 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
|
|
||||||
throw new Exception($"Unable to resolve project path ({_pluginInterface.AssemblyLocation.Directory})");
|
throw new Exception($"Unable to resolve project path ({_pluginInterface.AssemblyLocation.Directory})");
|
||||||
#else
|
#else
|
||||||
var allPluginsDirectory = _pluginInterface.ConfigFile.Directory ?? throw new Exception("Unknown directory for plugin configs");
|
var allPluginsDirectory =
|
||||||
|
_pluginInterface.ConfigFile.Directory ?? throw new Exception("Unknown directory for plugin configs");
|
||||||
return allPluginsDirectory
|
return allPluginsDirectory
|
||||||
.CreateSubdirectory("Questionable")
|
.CreateSubdirectory("Questionable")
|
||||||
.CreateSubdirectory("GatheringPaths");
|
.CreateSubdirectory("GatheringPaths");
|
||||||
@ -104,7 +101,6 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
internal void Reload()
|
internal void Reload()
|
||||||
{
|
{
|
||||||
LoadGatheringLocationsFromDirectory();
|
LoadGatheringLocationsFromDirectory();
|
||||||
Redraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadGatheringLocationsFromDirectory()
|
private void LoadGatheringLocationsFromDirectory()
|
||||||
@ -124,7 +120,6 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
_pluginLog.Information(
|
_pluginLog.Information(
|
||||||
$"Loaded {_gatheringLocations.Count} gathering root locations from {PathsDirectory.FullName} directory");
|
$"Loaded {_gatheringLocations.Count} gathering root locations from {PathsDirectory.FullName} directory");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -209,32 +204,39 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TerritoryChanged(ushort territoryId) => Redraw();
|
|
||||||
|
|
||||||
private void ClassJobChanged(uint classJobId)
|
private void ClassJobChanged(uint classJobId)
|
||||||
{
|
{
|
||||||
_currentClassJob = (EClassJob)classJobId;
|
_currentClassJob = (EClassJob)classJobId;
|
||||||
Redraw(_currentClassJob);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Redraw() => Redraw(_currentClassJob);
|
private void Draw()
|
||||||
|
|
||||||
private void Redraw(EClassJob classJob)
|
|
||||||
{
|
{
|
||||||
Splatoon.RemoveDynamicElements("GatheringPathRenderer");
|
if (!_currentClassJob.IsGatherer())
|
||||||
if (!classJob.IsGatherer())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var elements = GetLocationsInTerritory(_clientState.TerritoryType)
|
using var drawList = PictoService.Draw();
|
||||||
.SelectMany(location =>
|
if (drawList == null)
|
||||||
location.Root.Groups.SelectMany(group =>
|
return;
|
||||||
group.Nodes.SelectMany(node => node.Locations
|
|
||||||
.SelectMany(x =>
|
Vector3 position = _clientState.LocalPlayer?.Position ?? Vector3.Zero;
|
||||||
|
foreach (var location in GetLocationsInTerritory(_clientState.TerritoryType))
|
||||||
|
{
|
||||||
|
if (!location.Root.Groups.Any(gr =>
|
||||||
|
gr.Nodes.Any(
|
||||||
|
no => no.Locations.Any(
|
||||||
|
loc => Vector3.Distance(loc.Position, position) < 200f))))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var group in location.Root.Groups)
|
||||||
|
{
|
||||||
|
foreach (GatheringNode node in group.Nodes)
|
||||||
|
{
|
||||||
|
foreach (var x in node.Locations)
|
||||||
{
|
{
|
||||||
bool isUnsaved = false;
|
bool isUnsaved = false;
|
||||||
bool isCone = false;
|
bool isCone = false;
|
||||||
int minimumAngle = 0;
|
float minimumAngle = 0;
|
||||||
int maximumAngle = 0;
|
float maximumAngle = 0;
|
||||||
if (_editorWindow.TryGetOverride(x.InternalId, out LocationOverride? locationOverride) &&
|
if (_editorWindow.TryGetOverride(x.InternalId, out LocationOverride? locationOverride) &&
|
||||||
locationOverride != null)
|
locationOverride != null)
|
||||||
{
|
{
|
||||||
@ -254,42 +256,28 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
maximumAngle = x.MaximumAngle.GetValueOrDefault();
|
maximumAngle = x.MaximumAngle.GetValueOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
minimumAngle *= (float)Math.PI / 180;
|
||||||
|
maximumAngle *= (float)Math.PI / 180;
|
||||||
|
if (!isCone || maximumAngle - minimumAngle >= 2 * Math.PI)
|
||||||
|
{
|
||||||
|
minimumAngle = 0;
|
||||||
|
maximumAngle = (float)Math.PI * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint color = _colors[location.Root.Groups.IndexOf(group) % _colors.Count];
|
||||||
|
drawList.AddFanFilled(x.Position,
|
||||||
|
locationOverride?.MinimumDistance ?? x.CalculateMinimumDistance(),
|
||||||
|
locationOverride?.MaximumDistance ?? x.CalculateMaximumDistance(),
|
||||||
|
minimumAngle, maximumAngle, color);
|
||||||
|
drawList.AddFan(x.Position,
|
||||||
|
locationOverride?.MinimumDistance ?? x.CalculateMinimumDistance(),
|
||||||
|
locationOverride?.MaximumDistance ?? x.CalculateMaximumDistance(),
|
||||||
|
minimumAngle, maximumAngle, color | 0xFF000000);
|
||||||
|
|
||||||
|
drawList.AddText(x.Position, isUnsaved ? 0xFFFF0000 : 0xFFFFFFFF, $"{location.Root.Groups.IndexOf(group)} // {node.DataId} / {node.Locations.IndexOf(x)} || {minimumAngle}, {maximumAngle}", 1f);
|
||||||
#if false
|
#if false
|
||||||
var a = GatheringMath.CalculateLandingLocation(x, 0, 0);
|
var a = GatheringMath.CalculateLandingLocation(x, 0, 0);
|
||||||
var b = GatheringMath.CalculateLandingLocation(x, 1, 1);
|
var b = GatheringMath.CalculateLandingLocation(x, 1, 1);
|
||||||
#endif
|
|
||||||
return new List<Element>
|
|
||||||
{
|
|
||||||
new Element(isCone
|
|
||||||
? ElementType.ConeAtFixedCoordinates
|
|
||||||
: ElementType.CircleAtFixedCoordinates)
|
|
||||||
{
|
|
||||||
refX = x.Position.X,
|
|
||||||
refY = x.Position.Z,
|
|
||||||
refZ = x.Position.Y,
|
|
||||||
Filled = true,
|
|
||||||
radius = locationOverride?.MinimumDistance ?? x.CalculateMinimumDistance(),
|
|
||||||
Donut = (locationOverride?.MaximumDistance ?? x.CalculateMaximumDistance()) -
|
|
||||||
(locationOverride?.MinimumDistance ?? x.CalculateMinimumDistance()),
|
|
||||||
color = _colors[location.Root.Groups.IndexOf(group) % _colors.Count],
|
|
||||||
Enabled = true,
|
|
||||||
coneAngleMin = minimumAngle,
|
|
||||||
coneAngleMax = maximumAngle,
|
|
||||||
tether = false,
|
|
||||||
},
|
|
||||||
new Element(ElementType.CircleAtFixedCoordinates)
|
|
||||||
{
|
|
||||||
refX = x.Position.X,
|
|
||||||
refY = x.Position.Z,
|
|
||||||
refZ = x.Position.Y,
|
|
||||||
color = 0xFFFFFFFF,
|
|
||||||
radius = 0.1f,
|
|
||||||
Enabled = true,
|
|
||||||
overlayText =
|
|
||||||
$"{location.Root.Groups.IndexOf(group)} // {node.DataId} / {node.Locations.IndexOf(x)}",
|
|
||||||
overlayBGColor = isUnsaved ? 0xFF2020FF : 0xFF000000,
|
|
||||||
},
|
|
||||||
#if false
|
|
||||||
new Element(ElementType.CircleAtFixedCoordinates)
|
new Element(ElementType.CircleAtFixedCoordinates)
|
||||||
{
|
{
|
||||||
refX = a.X,
|
refX = a.X,
|
||||||
@ -311,40 +299,19 @@ public sealed class RendererPlugin : IDalamudPlugin
|
|||||||
overlayText = "Max Angle"
|
overlayText = "Max Angle"
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
|
||||||
}))))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (elements.Count == 0)
|
|
||||||
{
|
|
||||||
_pluginLog.Information("No new elements to render.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = new TickScheduler(delegate
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Splatoon.AddDynamicElements("GatheringPathRenderer",
|
|
||||||
elements.ToArray(),
|
|
||||||
new[] { OnTerritoryChange });
|
|
||||||
_pluginLog.Information($"Created {elements.Count} splatoon elements.");
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_pluginLog.Error(e, "Unable to create splatoon layer");
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_clientState.ClassJobChanged -= ClassJobChanged;
|
_clientState.ClassJobChanged -= ClassJobChanged;
|
||||||
_clientState.TerritoryChanged -= TerritoryChanged;
|
_pluginInterface.UiBuilder.Draw -= Draw;
|
||||||
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
|
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
|
||||||
|
|
||||||
Splatoon.RemoveDynamicElements("GatheringPathRenderer");
|
PictoService.Dispose();
|
||||||
ECommonsMain.Dispose();
|
|
||||||
|
|
||||||
_pluginInterface.GetIpcSubscriber<object>("Questionable.ReloadData")
|
_pluginInterface.GetIpcSubscriber<object>("Questionable.ReloadData")
|
||||||
.Unsubscribe(Reload);
|
.Unsubscribe(Reload);
|
||||||
|
@ -154,7 +154,6 @@ internal sealed class EditorWindow : Window
|
|||||||
{
|
{
|
||||||
locationOverride.MinimumAngle = minAngle;
|
locationOverride.MinimumAngle = minAngle;
|
||||||
locationOverride.MaximumAngle = maxAngle;
|
locationOverride.MaximumAngle = maxAngle;
|
||||||
_plugin.Redraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float minDistance = locationOverride.MinimumDistance ?? location.CalculateMinimumDistance();
|
float minDistance = locationOverride.MinimumDistance ?? location.CalculateMinimumDistance();
|
||||||
@ -163,7 +162,6 @@ internal sealed class EditorWindow : Window
|
|||||||
{
|
{
|
||||||
locationOverride.MinimumDistance = minDistance;
|
locationOverride.MinimumDistance = minDistance;
|
||||||
locationOverride.MaximumDistance = maxDistance;
|
locationOverride.MaximumDistance = maxDistance;
|
||||||
_plugin.Redraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unsaved = locationOverride.NeedsSave();
|
bool unsaved = locationOverride.NeedsSave();
|
||||||
@ -194,7 +192,6 @@ internal sealed class EditorWindow : Window
|
|||||||
if (ImGui.Button("Reset"))
|
if (ImGui.Button("Reset"))
|
||||||
{
|
{
|
||||||
_changes[location.InternalId] = new LocationOverride();
|
_changes[location.InternalId] = new LocationOverride();
|
||||||
_plugin.Redraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndDisabled();
|
ImGui.EndDisabled();
|
||||||
|
@ -35,6 +35,16 @@
|
|||||||
"resolved": "8.0.0",
|
"resolved": "8.0.0",
|
||||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||||
},
|
},
|
||||||
|
"Microsoft.NETCore.Platforms": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "1.1.0",
|
||||||
|
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||||
|
},
|
||||||
|
"Microsoft.NETCore.Targets": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "1.1.0",
|
||||||
|
"contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
|
||||||
|
},
|
||||||
"Microsoft.SourceLink.AzureRepos.Git": {
|
"Microsoft.SourceLink.AzureRepos.Git": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.1.1",
|
"resolved": "1.1.1",
|
||||||
@ -76,13 +86,944 @@
|
|||||||
"Microsoft.SourceLink.Common": "1.1.1"
|
"Microsoft.SourceLink.Common": "1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Microsoft.Win32.Primitives": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NETStandard.Library": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "1.6.1",
|
||||||
|
"contentHash": "WcSp3+vP+yHNgS8EV5J7pZ9IRpeDuARBPN28by8zqff1wJQXm26PVU8L3/fYLBJVU7BtDyqNVWq2KlCVvSSR4A==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.Win32.Primitives": "4.3.0",
|
||||||
|
"System.AppContext": "4.3.0",
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Collections.Concurrent": "4.3.0",
|
||||||
|
"System.Console": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Diagnostics.Tools": "4.3.0",
|
||||||
|
"System.Diagnostics.Tracing": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Globalization.Calendars": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.IO.Compression": "4.3.0",
|
||||||
|
"System.IO.Compression.ZipFile": "4.3.0",
|
||||||
|
"System.IO.FileSystem": "4.3.0",
|
||||||
|
"System.IO.FileSystem.Primitives": "4.3.0",
|
||||||
|
"System.Linq": "4.3.0",
|
||||||
|
"System.Linq.Expressions": "4.3.0",
|
||||||
|
"System.Net.Http": "4.3.0",
|
||||||
|
"System.Net.Primitives": "4.3.0",
|
||||||
|
"System.Net.Sockets": "4.3.0",
|
||||||
|
"System.ObjectModel": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Reflection.Extensions": "4.3.0",
|
||||||
|
"System.Reflection.Primitives": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices.RuntimeInformation": "4.3.0",
|
||||||
|
"System.Runtime.Numerics": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Security.Cryptography.X509Certificates": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Text.Encoding.Extensions": "4.3.0",
|
||||||
|
"System.Text.RegularExpressions": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0",
|
||||||
|
"System.Threading.Timer": "4.3.0",
|
||||||
|
"System.Xml.ReaderWriter": "4.3.0",
|
||||||
|
"System.Xml.XDocument": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q=="
|
||||||
|
},
|
||||||
|
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA=="
|
||||||
|
},
|
||||||
|
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw=="
|
||||||
|
},
|
||||||
|
"runtime.native.System": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime.native.System.IO.Compression": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "INBPonS5QPEgn7naufQFXJEp3zX6L4bwHgJ/ZH78aBTpeNfQMtf7C6VrAFhlq2xxWBveIOWyFzQjJ8XzHMhdOQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime.native.System.Net.Http": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime.native.System.Security.Cryptography.Apple": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A=="
|
||||||
|
},
|
||||||
|
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ=="
|
||||||
|
},
|
||||||
|
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ=="
|
||||||
|
},
|
||||||
|
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g=="
|
||||||
|
},
|
||||||
|
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg=="
|
||||||
|
},
|
||||||
|
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ=="
|
||||||
|
},
|
||||||
|
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A=="
|
||||||
|
},
|
||||||
|
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg=="
|
||||||
|
},
|
||||||
|
"SharpDX": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.2.0",
|
||||||
|
"contentHash": "3pv0LFMvfK/dv1qISJnn8xBeeT6R/FRvr0EV4KI2DGsL84Qlv6P7isWqxGyU0LCwlSVCJN3jgHJ4Bl0KI2PJww==",
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SharpDX.D3DCompiler": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.2.0",
|
||||||
|
"contentHash": "Rnsd6Ilp127xbXqhTit8WKFQUrXwWxqVGpglyWDNkIBCk0tWXNQEjrJpsl0KAObzyZaa33+EXAikLVt5fnd3GA==",
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.6.1",
|
||||||
|
"SharpDX": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SharpDX.Direct2D1": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.2.0",
|
||||||
|
"contentHash": "Qs8LzDMaQf1u3KB8ArHu9pDv6itZ++QXs99a/bVAG+nKr0Hx5NG4mcN5vsfE0mVR2TkeHfeUm4PksRah6VUPtA==",
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.6.1",
|
||||||
|
"SharpDX": "4.2.0",
|
||||||
|
"SharpDX.DXGI": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SharpDX.Direct3D11": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.2.0",
|
||||||
|
"contentHash": "oTm/iT5X/IIuJ8kNYP+DTC/MhBhqtRF5dbgPPFgLBdQv0BKzNTzXQQXd7SveBFjQg6hXEAJ2jGCAzNYvGFc9LA==",
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.6.1",
|
||||||
|
"SharpDX": "4.2.0",
|
||||||
|
"SharpDX.DXGI": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SharpDX.DXGI": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.2.0",
|
||||||
|
"contentHash": "UjKqkgWc8U+SP+j3LBzFP6OB6Ntapjih7Xo+g1rLcsGbIb5KwewBrBChaUu7sil8rWoeVU/k0EJd3SMN4VqNZw==",
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.6.1",
|
||||||
|
"SharpDX": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.AppContext": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "fKC+rmaLfeIzUhagxY17Q9siv/sPrjjKcfNg1Ic8IlQkZLipo8ljcaZQu4VtI4Jqbzjc2VTjzGLF6WmsRXAEgA==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Buffers": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "ratu44uTIHgeBeI0dE8DWvmXVBSo4u7ozRZZHOMmK/JPpYyo0dAfgSiHlpiObMQ5lEtEyIXA40sKRYg5J6A8uQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Diagnostics.Tracing": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Collections": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Collections.Concurrent": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Diagnostics.Tracing": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Console": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "DHDrIxiqk1h03m6khKWV2X8p/uvN79rgSqpilL6uzpmSfxfU5ng8VcPtW4qsDsQDHiTv6IPV9TmD5M/vElPNLg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Diagnostics.Debug": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Diagnostics.DiagnosticSource": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "tD6kosZnTAGdrEa0tZSuFyunMbt/5KYDnHdndJYGqZoNy00XVXyACd5d6KnE1YgYv3ne2CjtAfNXo/fwEhnKUA==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Tracing": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Diagnostics.Tools": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Diagnostics.Tracing": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Globalization": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Globalization.Calendars": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Globalization.Extensions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IO": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IO.Compression": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.Buffers": "4.3.0",
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0",
|
||||||
|
"runtime.native.System": "4.3.0",
|
||||||
|
"runtime.native.System.IO.Compression": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IO.Compression.ZipFile": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "G4HwjEsgIwy3JFBduZ9quBkAu+eUwjIdJleuNSgmUojbH6O3mlvEIme+GHx/cLlTAPcrnnL7GqvB9pTlWRfhOg==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Buffers": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.IO.Compression": "4.3.0",
|
||||||
|
"System.IO.FileSystem": "4.3.0",
|
||||||
|
"System.IO.FileSystem.Primitives": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IO.FileSystem": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.IO.FileSystem.Primitives": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IO.FileSystem.Primitives": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Linq": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Linq.Expressions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Linq": "4.3.0",
|
||||||
|
"System.ObjectModel": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Reflection.Emit": "4.3.0",
|
||||||
|
"System.Reflection.Emit.ILGeneration": "4.3.0",
|
||||||
|
"System.Reflection.Emit.Lightweight": "4.3.0",
|
||||||
|
"System.Reflection.Extensions": "4.3.0",
|
||||||
|
"System.Reflection.Primitives": "4.3.0",
|
||||||
|
"System.Reflection.TypeExtensions": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Net.Http": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Diagnostics.DiagnosticSource": "4.3.0",
|
||||||
|
"System.Diagnostics.Tracing": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Globalization.Extensions": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.IO.FileSystem": "4.3.0",
|
||||||
|
"System.Net.Primitives": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||||
|
"System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Security.Cryptography.X509Certificates": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0",
|
||||||
|
"runtime.native.System": "4.3.0",
|
||||||
|
"runtime.native.System.Net.Http": "4.3.0",
|
||||||
|
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Net.Primitives": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Net.Sockets": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "m6icV6TqQOAdgt5N/9I5KNpjom/5NFtkmGseEH+AK/hny8XrytLH3+b5M8zL/Ycg3fhIocFpUMyl/wpFnVRvdw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Net.Primitives": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.ObjectModel": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Reflection.Primitives": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection.Emit": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Reflection.Emit.ILGeneration": "4.3.0",
|
||||||
|
"System.Reflection.Primitives": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection.Emit.ILGeneration": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Reflection.Primitives": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection.Emit.Lightweight": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Reflection.Emit.ILGeneration": "4.3.0",
|
||||||
|
"System.Reflection.Primitives": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection.Extensions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection.Primitives": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Reflection.TypeExtensions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Resources.ResourceManager": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime.Extensions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime.Handles": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime.InteropServices": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Reflection.Primitives": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime.InteropServices.RuntimeInformation": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Reflection.Extensions": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"runtime.native.System": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime.Numerics": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.Algorithms": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Runtime.Numerics": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"runtime.native.System.Security.Cryptography.Apple": "4.3.0",
|
||||||
|
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.Cng": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.Csp": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.Encoding": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Collections.Concurrent": "4.3.0",
|
||||||
|
"System.Linq": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.OpenSsl": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Runtime.Numerics": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.Primitives": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.X509Certificates": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.Globalization.Calendars": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.IO.FileSystem": "4.3.0",
|
||||||
|
"System.IO.FileSystem.Primitives": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.Handles": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Runtime.Numerics": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Cng": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Csp": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Encoding": "4.3.0",
|
||||||
|
"System.Security.Cryptography.OpenSsl": "4.3.0",
|
||||||
|
"System.Security.Cryptography.Primitives": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"runtime.native.System": "4.3.0",
|
||||||
|
"runtime.native.System.Net.Http": "4.3.0",
|
||||||
|
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Text.Encoding": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Text.Encoding.Extensions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"System.Text.Json": {
|
"System.Text.Json": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "8.0.5",
|
"resolved": "8.0.5",
|
||||||
"contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg=="
|
"contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg=="
|
||||||
},
|
},
|
||||||
"ecommons": {
|
"System.Text.RegularExpressions": {
|
||||||
"type": "Project"
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Threading": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Threading.Tasks": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Threading.Tasks.Extensions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "npvJkVKl5rKXrtl1Kkm6OhOUaYGEiF9wFbppFRWSMoApKzt2PiPHT2Bb8a5sAWxprvdOAtvaARS9QYMznEUtug==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Threading.Timer": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "Z6YfyYTCg7lOZjJzBjONJTFKGN9/NIYKSxhU5GRd+DTwHSZyvWp1xuI5aR+dLg+ayyC5Xv57KiY4oJ0tMO89fQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||||
|
"Microsoft.NETCore.Targets": "1.1.0",
|
||||||
|
"System.Runtime": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Xml.ReaderWriter": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.IO.FileSystem": "4.3.0",
|
||||||
|
"System.IO.FileSystem.Primitives": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Runtime.InteropServices": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Text.Encoding.Extensions": "4.3.0",
|
||||||
|
"System.Text.RegularExpressions": "4.3.0",
|
||||||
|
"System.Threading.Tasks": "4.3.0",
|
||||||
|
"System.Threading.Tasks.Extensions": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Xml.XDocument": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.3.0",
|
||||||
|
"contentHash": "5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.3.0",
|
||||||
|
"System.Diagnostics.Debug": "4.3.0",
|
||||||
|
"System.Diagnostics.Tools": "4.3.0",
|
||||||
|
"System.Globalization": "4.3.0",
|
||||||
|
"System.IO": "4.3.0",
|
||||||
|
"System.Reflection": "4.3.0",
|
||||||
|
"System.Resources.ResourceManager": "4.3.0",
|
||||||
|
"System.Runtime": "4.3.0",
|
||||||
|
"System.Runtime.Extensions": "4.3.0",
|
||||||
|
"System.Text.Encoding": "4.3.0",
|
||||||
|
"System.Threading": "4.3.0",
|
||||||
|
"System.Xml.ReaderWriter": "4.3.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"llib": {
|
"llib": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
@ -90,6 +1031,14 @@
|
|||||||
"DalamudPackager": "[11.0.0, )"
|
"DalamudPackager": "[11.0.0, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pictomancy": {
|
||||||
|
"type": "Project",
|
||||||
|
"dependencies": {
|
||||||
|
"SharpDX.D3DCompiler": "[4.2.0, )",
|
||||||
|
"SharpDX.Direct2D1": "[4.2.0, )",
|
||||||
|
"SharpDX.Direct3D11": "[4.2.0, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
"questionable.model": {
|
"questionable.model": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
2
LLib
2
LLib
@ -1 +1 @@
|
|||||||
Subproject commit 746d14681baa91132784ab17f8f49671e86ea211
|
Subproject commit edab3c7ecc6bd66ac07e3c3938eb9c8a835a1c42
|
@ -123,6 +123,9 @@ internal static class QuestStepExtensions
|
|||||||
Assignment(nameof(QuestStep.AutoDutyEnabled),
|
Assignment(nameof(QuestStep.AutoDutyEnabled),
|
||||||
step.AutoDutyEnabled, emptyStep.AutoDutyEnabled)
|
step.AutoDutyEnabled, emptyStep.AutoDutyEnabled)
|
||||||
.AsSyntaxNodeOrToken(),
|
.AsSyntaxNodeOrToken(),
|
||||||
|
Assignment(nameof(QuestStep.SinglePlayerDutyOptions), step.SinglePlayerDutyOptions,
|
||||||
|
emptyStep.SinglePlayerDutyOptions)
|
||||||
|
.AsSyntaxNodeOrToken(),
|
||||||
Assignment(nameof(QuestStep.SkipConditions), step.SkipConditions,
|
Assignment(nameof(QuestStep.SkipConditions), step.SkipConditions,
|
||||||
emptyStep.SkipConditions)
|
emptyStep.SkipConditions)
|
||||||
.AsSyntaxNodeOrToken(),
|
.AsSyntaxNodeOrToken(),
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Questionable.Model.Questing;
|
||||||
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||||
|
using static Questionable.QuestPathGenerator.RoslynShortcuts;
|
||||||
|
|
||||||
|
namespace Questionable.QuestPathGenerator.RoslynElements;
|
||||||
|
|
||||||
|
internal static class SinglePlayerDutyOptionsExtensions
|
||||||
|
{
|
||||||
|
public static ExpressionSyntax ToExpressionSyntax(this SinglePlayerDutyOptions dutyOptions)
|
||||||
|
{
|
||||||
|
var emptyOptions = new SinglePlayerDutyOptions();
|
||||||
|
return ObjectCreationExpression(
|
||||||
|
IdentifierName(nameof(SinglePlayerDutyOptions)))
|
||||||
|
.WithInitializer(
|
||||||
|
InitializerExpression(
|
||||||
|
SyntaxKind.ObjectInitializerExpression,
|
||||||
|
SeparatedList<ExpressionSyntax>(
|
||||||
|
SyntaxNodeList(
|
||||||
|
Assignment(nameof(SinglePlayerDutyOptions.Enabled),
|
||||||
|
dutyOptions.Enabled, emptyOptions.Enabled)
|
||||||
|
.AsSyntaxNodeOrToken(),
|
||||||
|
AssignmentList(nameof(SinglePlayerDutyOptions.Notes), dutyOptions.Notes)
|
||||||
|
.AsSyntaxNodeOrToken(),
|
||||||
|
Assignment(nameof(SinglePlayerDutyOptions.Index),
|
||||||
|
dutyOptions.Index, emptyOptions.Index)
|
||||||
|
.AsSyntaxNodeOrToken()))));
|
||||||
|
}
|
||||||
|
}
|
@ -62,6 +62,7 @@ public static class RoslynShortcuts
|
|||||||
ComplexCombatData complexCombatData => complexCombatData.ToExpressionSyntax(),
|
ComplexCombatData complexCombatData => complexCombatData.ToExpressionSyntax(),
|
||||||
QuestWorkValue questWorkValue => questWorkValue.ToExpressionSyntax(),
|
QuestWorkValue questWorkValue => questWorkValue.ToExpressionSyntax(),
|
||||||
List<QuestWorkValue> list => list.ToExpressionSyntax(), // TODO fix in AssignmentList
|
List<QuestWorkValue> list => list.ToExpressionSyntax(), // TODO fix in AssignmentList
|
||||||
|
SinglePlayerDutyOptions dutyOptions => dutyOptions.ToExpressionSyntax(),
|
||||||
SkipConditions skipConditions => skipConditions.ToExpressionSyntax(),
|
SkipConditions skipConditions => skipConditions.ToExpressionSyntax(),
|
||||||
SkipStepConditions skipStepConditions => skipStepConditions.ToExpressionSyntax(),
|
SkipStepConditions skipStepConditions => skipStepConditions.ToExpressionSyntax(),
|
||||||
SkipItemConditions skipItemCondition => skipItemCondition.ToExpressionSyntax(),
|
SkipItemConditions skipItemCondition => skipItemCondition.ToExpressionSyntax(),
|
||||||
|
@ -57,6 +57,9 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 153,
|
"TerritoryId": 153,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Index": 1
|
||||||
|
},
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -62,6 +62,9 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 154,
|
"TerritoryId": 154,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Index": 1
|
||||||
|
},
|
||||||
"AetheryteShortcut": "North Shroud - Fallgourd Float",
|
"AetheryteShortcut": "North Shroud - Fallgourd Float",
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,10 @@
|
|||||||
"Z": 29.06836
|
"Z": 29.06836
|
||||||
},
|
},
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Index": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -140,6 +140,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 141,
|
"TerritoryId": 141,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -92,6 +92,9 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 130,
|
"TerritoryId": 130,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Index": 1
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Ul'dah"
|
"AetheryteShortcut": "Ul'dah"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 137,
|
"TerritoryId": 137,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Eastern La Noscea - Wineport",
|
"AetheryteShortcut": "Eastern La Noscea - Wineport",
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -65,7 +65,8 @@
|
|||||||
"AetheryteShortcut": "East Shroud - Hawthorne Hut",
|
"AetheryteShortcut": "East Shroud - Hawthorne Hut",
|
||||||
"SkipConditions": {
|
"SkipConditions": {
|
||||||
"AetheryteShortcutIf": {
|
"AetheryteShortcutIf": {
|
||||||
"InSameTerritory": true
|
"InSameTerritory": true,
|
||||||
|
"AetheryteLocked": "East Shroud - Hawthorne Hut"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +117,11 @@
|
|||||||
"Z": 35.568726
|
"Z": 35.568726
|
||||||
},
|
},
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -33,6 +33,39 @@
|
|||||||
{
|
{
|
||||||
"Sequence": 1,
|
"Sequence": 1,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
{
|
||||||
|
"DataId": 1001263,
|
||||||
|
"Position": {
|
||||||
|
"X": 181.41443,
|
||||||
|
"Y": -2.3519497,
|
||||||
|
"Z": -240.40594
|
||||||
|
},
|
||||||
|
"TerritoryId": 133,
|
||||||
|
"InteractionType": "Interact",
|
||||||
|
"TargetTerritoryId": 152,
|
||||||
|
"AethernetShortcut": [
|
||||||
|
"[Gridania] Conjurers' Guild",
|
||||||
|
"[Gridania] Lancers' Guild"
|
||||||
|
],
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"AetheryteUnlocked": "East Shroud - Hawthorne Hut",
|
||||||
|
"InTerritory": [
|
||||||
|
152
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TerritoryId": 152,
|
||||||
|
"InteractionType": "AttuneAetheryte",
|
||||||
|
"Aetheryte": "East Shroud - Hawthorne Hut",
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"AetheryteUnlocked": "East Shroud - Hawthorne Hut"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Position": {
|
"Position": {
|
||||||
"X": -276.804,
|
"X": -276.804,
|
||||||
@ -42,7 +75,12 @@
|
|||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "WalkTo",
|
"InteractionType": "WalkTo",
|
||||||
"AetheryteShortcut": "East Shroud - Hawthorne Hut",
|
"AetheryteShortcut": "East Shroud - Hawthorne Hut",
|
||||||
"Fly": true
|
"Fly": true,
|
||||||
|
"SkipConditions": {
|
||||||
|
"AetheryteShortcutIf": {
|
||||||
|
"AetheryteLocked": "East Shroud - Hawthorne Hut"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataId": 2000889,
|
"DataId": 2000889,
|
||||||
@ -212,6 +250,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -138,7 +138,11 @@
|
|||||||
"Z": 192.2179
|
"Z": 192.2179
|
||||||
},
|
},
|
||||||
"TerritoryId": 148,
|
"TerritoryId": 148,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -111,7 +111,14 @@
|
|||||||
"Z": 295.52136
|
"Z": 295.52136
|
||||||
},
|
},
|
||||||
"TerritoryId": 148,
|
"TerritoryId": 148,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"Healer NPC is only killed after the boss dies; all NPCs need to be killed for the duty to complete"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -28,7 +28,14 @@
|
|||||||
"Z": -309.55975
|
"Z": -309.55975
|
||||||
},
|
},
|
||||||
"TerritoryId": 148,
|
"TerritoryId": 148,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": false,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"AI doesn't automatically target newly spawning adds until after the boss died, and dies (tested on CNJ)"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -77,6 +77,13 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 148,
|
"TerritoryId": 148,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"(Phase 1) Healer NPCs are only killed after the boss dies - allied NPCs will kill them eventually; all NPCs need to be killed for the duty to complete"
|
||||||
|
]
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Central Shroud - Bentbranch Meadows"
|
"AetheryteShortcut": "Central Shroud - Bentbranch Meadows"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -69,6 +69,13 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 135,
|
"TerritoryId": 135,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": false,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"(Phase 1, second enemy group) Stuck with enemy being out of sight -- but still able to attack you (tested on ACN)"
|
||||||
|
]
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Lower La Noscea - Moraby Drydocks"
|
"AetheryteShortcut": "Lower La Noscea - Moraby Drydocks"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -45,8 +45,11 @@
|
|||||||
"TerritoryId": 134,
|
"TerritoryId": 134,
|
||||||
"InteractionType": "Combat",
|
"InteractionType": "Combat",
|
||||||
"EnemySpawnType": "AutoOnEnterArea",
|
"EnemySpawnType": "AutoOnEnterArea",
|
||||||
"KillEnemyDataIds": [
|
"ComplexCombatData": [
|
||||||
52
|
{
|
||||||
|
"DataId": 52,
|
||||||
|
"IgnoreQuestMarker": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,11 @@
|
|||||||
"Z": -432.15082
|
"Z": -432.15082
|
||||||
},
|
},
|
||||||
"TerritoryId": 134,
|
"TerritoryId": 134,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -28,7 +28,14 @@
|
|||||||
"Z": -141.7716
|
"Z": -141.7716
|
||||||
},
|
},
|
||||||
"TerritoryId": 134,
|
"TerritoryId": 134,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": false,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"AI doesn't automatically target newly spawning adds until after the boss died (requires healing luck on ACN)"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -58,6 +58,13 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 138,
|
"TerritoryId": 138,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"(Phase 1) Kills PGL NPCs and then the boss - allied NPCs will kill most other NPCs eventually; all NPCs need to be killed for the duty to complete"
|
||||||
|
]
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Western La Noscea - Swiftperch"
|
"AetheryteShortcut": "Western La Noscea - Swiftperch"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -44,7 +44,11 @@
|
|||||||
"Z": -242.51166
|
"Z": -242.51166
|
||||||
},
|
},
|
||||||
"TerritoryId": 145,
|
"TerritoryId": 145,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -79,6 +79,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 130,
|
"TerritoryId": 130,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Ul'dah",
|
"AetheryteShortcut": "Ul'dah",
|
||||||
"AethernetShortcut": [
|
"AethernetShortcut": [
|
||||||
"[Ul'dah] Aetheryte Plaza",
|
"[Ul'dah] Aetheryte Plaza",
|
||||||
@ -87,6 +91,9 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Sequence": 5
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Sequence": 255,
|
"Sequence": 255,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
@ -63,12 +63,22 @@
|
|||||||
"AethernetShortcut": [
|
"AethernetShortcut": [
|
||||||
"[Gridania] Aetheryte Plaza",
|
"[Gridania] Aetheryte Plaza",
|
||||||
"[Gridania] Lancers' Guild"
|
"[Gridania] Lancers' Guild"
|
||||||
]
|
],
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"AetheryteUnlocked": "East Shroud - Hawthorne Hut"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "AttuneAetheryte",
|
"InteractionType": "AttuneAetheryte",
|
||||||
"Aetheryte": "East Shroud - Hawthorne Hut"
|
"Aetheryte": "East Shroud - Hawthorne Hut",
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"AetheryteUnlocked": "East Shroud - Hawthorne Hut"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1004886,
|
"DataId": 1004886,
|
||||||
@ -78,7 +88,17 @@
|
|||||||
"Z": 475.30322
|
"Z": 475.30322
|
||||||
},
|
},
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
|
"AetheryteShortcut": "East Shroud - Hawthorne Hut",
|
||||||
|
"SkipConditions": {
|
||||||
|
"AetheryteShortcutIf": {
|
||||||
|
"InSameTerritory": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -64,6 +64,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 135,
|
"TerritoryId": 135,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"AethernetShortcut": [
|
"AethernetShortcut": [
|
||||||
"[Limsa Lominsa] The Aftcastle",
|
"[Limsa Lominsa] The Aftcastle",
|
||||||
"[Limsa Lominsa] Tempest Gate (Lower La Noscea)"
|
"[Limsa Lominsa] Tempest Gate (Lower La Noscea)"
|
||||||
|
@ -59,6 +59,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 140,
|
"TerritoryId": 140,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Western Thanalan - Horizon"
|
"AetheryteShortcut": "Western Thanalan - Horizon"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -46,7 +46,8 @@
|
|||||||
},
|
},
|
||||||
"StopDistance": 7,
|
"StopDistance": 7,
|
||||||
"TerritoryId": 141,
|
"TerritoryId": 141,
|
||||||
"InteractionType": "Interact"
|
"InteractionType": "Interact",
|
||||||
|
"DelaySecondsAtStart": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -158,7 +158,11 @@
|
|||||||
"Z": 117.29602
|
"Z": 117.29602
|
||||||
},
|
},
|
||||||
"TerritoryId": 141,
|
"TerritoryId": 141,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,15 @@
|
|||||||
{
|
{
|
||||||
"Sequence": 255,
|
"Sequence": 255,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": -174.73444,
|
||||||
|
"Y": 15.450659,
|
||||||
|
"Z": -266.76144
|
||||||
|
},
|
||||||
|
"TerritoryId": 140,
|
||||||
|
"InteractionType": "WalkTo"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Position": {
|
"Position": {
|
||||||
"X": -289.1099,
|
"X": -289.1099,
|
||||||
|
@ -37,7 +37,11 @@
|
|||||||
"Z": -293.1411
|
"Z": -293.1411
|
||||||
},
|
},
|
||||||
"TerritoryId": 140,
|
"TerritoryId": 140,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 141,
|
"TerritoryId": 141,
|
||||||
"InteractionType": "Combat",
|
"InteractionType": "Combat",
|
||||||
"EnemySpawnType": "OverworldEnemies",
|
"EnemySpawnType": "FinishCombatIfAny",
|
||||||
"KillEnemyDataIds": [
|
"KillEnemyDataIds": [
|
||||||
352,
|
352,
|
||||||
353
|
353
|
||||||
@ -53,6 +53,25 @@
|
|||||||
{
|
{
|
||||||
"Sequence": 255,
|
"Sequence": 255,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": 131.78122,
|
||||||
|
"Y": 20.119337,
|
||||||
|
"Z": -115.27284
|
||||||
|
},
|
||||||
|
"TerritoryId": 141,
|
||||||
|
"InteractionType": "WalkTo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": 127.7017,
|
||||||
|
"Y": -0.15994573,
|
||||||
|
"Z": -161.89238
|
||||||
|
},
|
||||||
|
"TerritoryId": 141,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"DisableNavmesh": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1001605,
|
"DataId": 1001605,
|
||||||
"Position": {
|
"Position": {
|
||||||
|
@ -28,7 +28,11 @@
|
|||||||
"Z": 536.88855
|
"Z": 536.88855
|
||||||
},
|
},
|
||||||
"TerritoryId": 141,
|
"TerritoryId": 141,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -64,7 +64,14 @@
|
|||||||
"Z": -131.48706
|
"Z": -131.48706
|
||||||
},
|
},
|
||||||
"TerritoryId": 141,
|
"TerritoryId": 141,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"(Phase 1) Healer NPCs are only killed after the boss dies - allied NPCs will kill them eventually; all NPCs need to be killed for the duty to complete"
|
||||||
|
]
|
||||||
|
},
|
||||||
"AetheryteShortcut": "Central Thanalan - Black Brush Station"
|
"AetheryteShortcut": "Central Thanalan - Black Brush Station"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -73,13 +73,23 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 133,
|
"TerritoryId": 133,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "Interact",
|
||||||
"TargetTerritoryId": 152
|
"TargetTerritoryId": 152,
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"AetheryteUnlocked": "East Shroud - Hawthorne Hut"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "AttuneAetheryte",
|
"InteractionType": "AttuneAetheryte",
|
||||||
"Aetheryte": "East Shroud - Hawthorne Hut",
|
"Aetheryte": "East Shroud - Hawthorne Hut",
|
||||||
"StopDistance": 5
|
"StopDistance": 5,
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"AetheryteUnlocked": "East Shroud - Hawthorne Hut"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1006188,
|
"DataId": 1006188,
|
||||||
@ -89,7 +99,13 @@
|
|||||||
"Z": 283.4973
|
"Z": 283.4973
|
||||||
},
|
},
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "CompleteQuest"
|
"InteractionType": "CompleteQuest",
|
||||||
|
"AetheryteShortcut": "East Shroud - Hawthorne Hut",
|
||||||
|
"SkipConditions": {
|
||||||
|
"AetheryteShortcutIf": {
|
||||||
|
"InSameTerritory": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,11 @@
|
|||||||
"Z": -39.383606
|
"Z": -39.383606
|
||||||
},
|
},
|
||||||
"TerritoryId": 152,
|
"TerritoryId": 152,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -83,7 +83,14 @@
|
|||||||
"Z": -12.985474
|
"Z": -12.985474
|
||||||
},
|
},
|
||||||
"TerritoryId": 153,
|
"TerritoryId": 153,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"AI will kill initial adds before the boss, but not switch target whenever new enemies spawn; all NPCs need to be killed for the duty to complete"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -26,6 +26,28 @@
|
|||||||
{
|
{
|
||||||
"Sequence": 1,
|
"Sequence": 1,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": -225.94685,
|
||||||
|
"Y": 26.139933,
|
||||||
|
"Z": -340.8984
|
||||||
|
},
|
||||||
|
"TerritoryId": 146,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"Mount": true,
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"CompletionQuestVariablesFlags": [
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
16
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"DataId": 2001980,
|
"DataId": 2001980,
|
||||||
"Position": {
|
"Position": {
|
||||||
|
@ -159,7 +159,11 @@
|
|||||||
"Z": -805.478
|
"Z": -805.478
|
||||||
},
|
},
|
||||||
"TerritoryId": 140,
|
"TerritoryId": 140,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -103,7 +103,11 @@
|
|||||||
"Z": 479.9724
|
"Z": 479.9724
|
||||||
},
|
},
|
||||||
"TerritoryId": 1053,
|
"TerritoryId": 1053,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -68,6 +68,15 @@
|
|||||||
{
|
{
|
||||||
"Sequence": 3,
|
"Sequence": 3,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": -561.9863,
|
||||||
|
"Y": 9.919454,
|
||||||
|
"Z": 66.29564
|
||||||
|
},
|
||||||
|
"TerritoryId": 152,
|
||||||
|
"InteractionType": "WalkTo"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1008276,
|
"DataId": 1008276,
|
||||||
"Position": {
|
"Position": {
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 137,
|
"TerritoryId": 137,
|
||||||
"InteractionType": "WalkTo",
|
"InteractionType": "WalkTo",
|
||||||
"Fly": true
|
"Mount": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Position": {
|
"Position": {
|
||||||
|
@ -78,6 +78,10 @@
|
|||||||
"StopDistance": 1,
|
"StopDistance": 1,
|
||||||
"TerritoryId": 156,
|
"TerritoryId": 156,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -120,6 +120,15 @@
|
|||||||
8
|
8
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": -140.77458,
|
||||||
|
"Y": 39.99999,
|
||||||
|
"Z": 155.4174
|
||||||
|
},
|
||||||
|
"TerritoryId": 128,
|
||||||
|
"InteractionType": "WalkTo"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1009133,
|
"DataId": 1009133,
|
||||||
"Position": {
|
"Position": {
|
||||||
|
@ -100,6 +100,28 @@
|
|||||||
2
|
2
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": 86.662384,
|
||||||
|
"Y": 28.34813,
|
||||||
|
"Z": -627.5218
|
||||||
|
},
|
||||||
|
"TerritoryId": 156,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"Fly": true,
|
||||||
|
"SkipConditions": {
|
||||||
|
"StepIf": {
|
||||||
|
"CompletionQuestVariablesFlags": [
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
32
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1009143,
|
"DataId": 1009143,
|
||||||
"Position": {
|
"Position": {
|
||||||
@ -109,7 +131,6 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 156,
|
"TerritoryId": 156,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "Interact",
|
||||||
"Fly": true,
|
|
||||||
"$": "1 112 0 0 0 2 -> 2 96 0 0 0 34",
|
"$": "1 112 0 0 0 2 -> 2 96 0 0 0 34",
|
||||||
"CompletionQuestVariablesFlags": [
|
"CompletionQuestVariablesFlags": [
|
||||||
null,
|
null,
|
||||||
|
@ -71,6 +71,14 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 147,
|
"TerritoryId": 147,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"Will target Eline first (other NPCs later), and move to some -other- group of NPCs; only re-targets once they're at 1 HP (for Eline) or die",
|
||||||
|
"If the target isn't in melee range but other NPCs are, whether any AOEs are used for nearby enemies seems random"
|
||||||
|
]
|
||||||
|
},
|
||||||
"Fly": true,
|
"Fly": true,
|
||||||
"AetheryteShortcut": "Northern Thanalan - Ceruleum Processing Plant"
|
"AetheryteShortcut": "Northern Thanalan - Ceruleum Processing Plant"
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,16 @@
|
|||||||
"Z": -328.66406
|
"Z": -328.66406
|
||||||
},
|
},
|
||||||
"TerritoryId": 155,
|
"TerritoryId": 155,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": false,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"WIP: Needs to be re-tested",
|
||||||
|
"AI doesn't move after starting the instance, so enemies won't be triggered",
|
||||||
|
"(First Barrier) If the player is too far south, after being stunned by Vishap's roar, AI doesn't move out of the AOE and dies to the Cauterize"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -80,7 +80,8 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 148,
|
"TerritoryId": 148,
|
||||||
"InteractionType": "UseItem",
|
"InteractionType": "UseItem",
|
||||||
"ItemId": 4868
|
"ItemId": 4868,
|
||||||
|
"Fly": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Position": {
|
"Position": {
|
||||||
|
@ -46,6 +46,10 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 155,
|
"TerritoryId": 155,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
},
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -95,7 +95,11 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 138,
|
"TerritoryId": 138,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
"Fly": true
|
"Fly": true,
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -30,7 +30,11 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 397,
|
"TerritoryId": 397,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
"Comment": "Walk straight to Gorgagne Mills basement, ignore footprints"
|
"Comment": "Walk straight to Gorgagne Mills basement, ignore footprints",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,11 @@
|
|||||||
"Z": 349.96558
|
"Z": 349.96558
|
||||||
},
|
},
|
||||||
"TerritoryId": 401,
|
"TerritoryId": 401,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -78,7 +78,11 @@
|
|||||||
"AethernetShortcut": [
|
"AethernetShortcut": [
|
||||||
"[Ishgard] The Forgotten Knight",
|
"[Ishgard] The Forgotten Knight",
|
||||||
"[Ishgard] The Tribunal"
|
"[Ishgard] The Tribunal"
|
||||||
]
|
],
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -28,7 +28,14 @@
|
|||||||
"Z": 388.63196
|
"Z": 388.63196
|
||||||
},
|
},
|
||||||
"TerritoryId": 145,
|
"TerritoryId": 145,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"Will not move into melee range to kill the gate; Alphinaud will kill it after a while"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,16 @@
|
|||||||
{
|
{
|
||||||
"Sequence": 1,
|
"Sequence": 1,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": 474.62885,
|
||||||
|
"Y": 200.2377,
|
||||||
|
"Z": 657.9519
|
||||||
|
},
|
||||||
|
"TerritoryId": 397,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Position": {
|
"Position": {
|
||||||
"X": 486.38373,
|
"X": 486.38373,
|
||||||
@ -28,8 +38,7 @@
|
|||||||
"Z": 239.54294
|
"Z": 239.54294
|
||||||
},
|
},
|
||||||
"TerritoryId": 397,
|
"TerritoryId": 397,
|
||||||
"InteractionType": "WalkTo",
|
"InteractionType": "WalkTo"
|
||||||
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Position": {
|
"Position": {
|
||||||
@ -69,7 +78,11 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 397,
|
"TerritoryId": 397,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
"DisableNavmesh": true
|
"DisableNavmesh": true,
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -59,7 +59,14 @@
|
|||||||
"KillEnemyDataIds": [
|
"KillEnemyDataIds": [
|
||||||
4015
|
4015
|
||||||
],
|
],
|
||||||
"$": "0 0 0 0 0 0 -> "
|
"CompletionQuestVariablesFlags": [
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
128
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Position": {
|
"Position": {
|
||||||
@ -72,6 +79,14 @@
|
|||||||
"EnemySpawnType": "AutoOnEnterArea",
|
"EnemySpawnType": "AutoOnEnterArea",
|
||||||
"KillEnemyDataIds": [
|
"KillEnemyDataIds": [
|
||||||
4015
|
4015
|
||||||
|
],
|
||||||
|
"CompletionQuestVariablesFlags": [
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
64
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -89,6 +89,16 @@
|
|||||||
"InteractionType": "WalkTo",
|
"InteractionType": "WalkTo",
|
||||||
"Mount": true
|
"Mount": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": -335.0186,
|
||||||
|
"Y": 13.983504,
|
||||||
|
"Z": -100.87753
|
||||||
|
},
|
||||||
|
"TerritoryId": 140,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"Fly": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1004019,
|
"DataId": 1004019,
|
||||||
"Position": {
|
"Position": {
|
||||||
@ -98,7 +108,6 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 140,
|
"TerritoryId": 140,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "Interact",
|
||||||
"Fly": true,
|
|
||||||
"TargetTerritoryId": 140
|
"TargetTerritoryId": 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -74,7 +74,11 @@
|
|||||||
"Z": 37.247192
|
"Z": 37.247192
|
||||||
},
|
},
|
||||||
"TerritoryId": 418,
|
"TerritoryId": 418,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -56,7 +56,11 @@
|
|||||||
"TerritoryId": 401,
|
"TerritoryId": 401,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
"Emote": "lookout",
|
"Emote": "lookout",
|
||||||
"StopDistance": 0.25
|
"StopDistance": 0.25,
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -47,7 +47,11 @@
|
|||||||
"AethernetShortcut": [
|
"AethernetShortcut": [
|
||||||
"[Idyllshire] Aetheryte Plaza",
|
"[Idyllshire] Aetheryte Plaza",
|
||||||
"[Idyllshire] Epilogue Gate (Eastern Hinterlands)"
|
"[Idyllshire] Epilogue Gate (Eastern Hinterlands)"
|
||||||
]
|
],
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -68,7 +68,11 @@
|
|||||||
"Z": 553.97876
|
"Z": 553.97876
|
||||||
},
|
},
|
||||||
"TerritoryId": 402,
|
"TerritoryId": 402,
|
||||||
"InteractionType": "SinglePlayerDuty"
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": true,
|
||||||
|
"TestedBossModVersion": 292
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
"Z": -509.51404
|
"Z": -509.51404
|
||||||
},
|
},
|
||||||
"TerritoryId": 622,
|
"TerritoryId": 622,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
"Fly": true
|
"Fly": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
"Z": 686.427
|
"Z": 686.427
|
||||||
},
|
},
|
||||||
"TerritoryId": 135,
|
"TerritoryId": 135,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
"AetheryteShortcut": "Lower La Noscea - Moraby Drydocks"
|
"AetheryteShortcut": "Lower La Noscea - Moraby Drydocks"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -61,7 +61,19 @@
|
|||||||
"TerritoryId": 156,
|
"TerritoryId": 156,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "Interact",
|
||||||
"AetheryteShortcut": "Mor Dhona",
|
"AetheryteShortcut": "Mor Dhona",
|
||||||
"TargetTerritoryId": 351
|
"TargetTerritoryId": 351,
|
||||||
|
"SkipConditions": {
|
||||||
|
"AetheryteShortcutIf": {
|
||||||
|
"InTerritory": [
|
||||||
|
351
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"StepIf": {
|
||||||
|
"InTerritory": [
|
||||||
|
351
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1032081,
|
"DataId": 1032081,
|
||||||
@ -73,13 +85,17 @@
|
|||||||
"TerritoryId": 351,
|
"TerritoryId": 351,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
"Comment": "Estinien vs. Arch Ultima",
|
"Comment": "Estinien vs. Arch Ultima",
|
||||||
"DialogueChoices": [
|
"SinglePlayerDutyOptions": {
|
||||||
{
|
"Enabled": false,
|
||||||
"Type": "YesNo",
|
"TestedBossModVersion": 292,
|
||||||
"Prompt": "TEXT_LUCKMG110_03682_Q1_100_125",
|
"Notes": [
|
||||||
"Yes": true
|
"AI doesn't move automatically for the first boss",
|
||||||
}
|
"AI doesn't move automatically for the dialogue with gaius on the bridge",
|
||||||
|
"After walking downstairs automatically, AI tries to run back towards the stairs (ignoring the arena boudnary)",
|
||||||
|
"After moving from the arena boundary, AI doesn't move into melee range and stops too far away when initially attacking"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"$": "This doesn't have a duty confirmation dialog, so we're treating TEXT_LUCKMG110_03682_Q1_100_125 as one"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -46,6 +46,13 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 817,
|
"TerritoryId": 817,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Enabled": false,
|
||||||
|
"TestedBossModVersion": 292,
|
||||||
|
"Notes": [
|
||||||
|
"Doesn't walk to the teleporter to finish the duty"
|
||||||
|
]
|
||||||
|
},
|
||||||
"Fly": true,
|
"Fly": true,
|
||||||
"Comment": "A Sleep Disturbed (Opo-Opo, Wolf, Serpent)",
|
"Comment": "A Sleep Disturbed (Opo-Opo, Wolf, Serpent)",
|
||||||
"$": "The dialogue choices and data ids here are recycled",
|
"$": "The dialogue choices and data ids here are recycled",
|
||||||
|
@ -104,6 +104,9 @@
|
|||||||
"StopDistance": 5,
|
"StopDistance": 5,
|
||||||
"TerritoryId": 829,
|
"TerritoryId": 829,
|
||||||
"InteractionType": "SinglePlayerDuty",
|
"InteractionType": "SinglePlayerDuty",
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"Index": 1
|
||||||
|
},
|
||||||
"DialogueChoices": [
|
"DialogueChoices": [
|
||||||
{
|
{
|
||||||
"Type": "List",
|
"Type": "List",
|
||||||
|
@ -1257,6 +1257,50 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"properties": {
|
||||||
|
"InteractionType": {
|
||||||
|
"const": "SinglePlayerDuty"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"properties": {
|
||||||
|
"SinglePlayerDutyOptions": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Enabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"Notes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Index": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 1,
|
||||||
|
"description": "If a quest has multiple solo instances (which affects 5 quests total), indicates which one this is"
|
||||||
|
},
|
||||||
|
"TestedBossModVersion": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 292
|
||||||
|
},
|
||||||
|
"$": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TODO_required": [
|
||||||
|
"Enabled"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -91,6 +91,8 @@ public abstract class ElementId : IComparable<ElementId>, IEquatable<ElementId>
|
|||||||
|
|
||||||
public sealed class QuestId(ushort value) : ElementId(value)
|
public sealed class QuestId(ushort value) : ElementId(value)
|
||||||
{
|
{
|
||||||
|
public static QuestId FromRowId(uint rowId) => new((ushort)(rowId & 0xFFFF));
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Value.ToString(CultureInfo.InvariantCulture);
|
return Value.ToString(CultureInfo.InvariantCulture);
|
||||||
|
@ -75,6 +75,8 @@ public sealed class QuestStep
|
|||||||
public JumpDestination? JumpDestination { get; set; }
|
public JumpDestination? JumpDestination { get; set; }
|
||||||
public uint? ContentFinderConditionId { get; set; }
|
public uint? ContentFinderConditionId { get; set; }
|
||||||
public bool AutoDutyEnabled { get; set; }
|
public bool AutoDutyEnabled { get; set; }
|
||||||
|
public SinglePlayerDutyOptions? SinglePlayerDutyOptions { get; set; }
|
||||||
|
public byte SinglePlayerDutyIndex => SinglePlayerDutyOptions?.Index ?? 0;
|
||||||
public SkipConditions? SkipConditions { get; set; }
|
public SkipConditions? SkipConditions { get; set; }
|
||||||
|
|
||||||
public List<List<QuestWorkValue>?> RequiredQuestVariables { get; set; } = new();
|
public List<List<QuestWorkValue>?> RequiredQuestVariables { get; set; } = new();
|
||||||
|
10
Questionable.Model/Questing/SinglePlayerDutyOptions.cs
Normal file
10
Questionable.Model/Questing/SinglePlayerDutyOptions.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Questionable.Model.Questing;
|
||||||
|
|
||||||
|
public sealed class SinglePlayerDutyOptions
|
||||||
|
{
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
public List<string> Notes { get; set; } = [];
|
||||||
|
public byte Index { get; set; }
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "/liza/Questionable/raw/branch/master/Questionable.Model/common-aethernetshard.json",
|
"$id": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-aethernetshard.json",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"[Gridania] Aetheryte Plaza",
|
"[Gridania] Aetheryte Plaza",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "/liza/Questionable/raw/branch/master/Questionable.Model/common-aetheryte.json",
|
"$id": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-aetheryte.json",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Gridania",
|
"Gridania",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "/liza/Questionable/raw/branch/master/Questionable.Model/common-classjob.json",
|
"$id": "https://git.carvel.li//liza/Questionable/raw/branch/master/Questionable.Model/common-classjob.json",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Gladiator",
|
"Gladiator",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "/liza/Questionable/raw/branch/master/Questionable.Model/common-completionflags.json",
|
"$id": "https://git.carvel.li//liza/Questionable/raw/branch/master/Questionable.Model/common-completionflags.json",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"description": "Quest Variables that dictate whether or not this step is skipped: null is don't check, positive values need to be set, negative values need to be unset",
|
"description": "Quest Variables that dictate whether or not this step is skipped: null is don't check, positive values need to be set, negative values need to be unset",
|
||||||
"items": {
|
"items": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "/liza/Questionable/raw/branch/master/Questionable.Model/common-vector3.json",
|
"$id": "https://git.carvel.li//liza/Questionable/raw/branch/master/Questionable.Model/common-vector3.json",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "Position in the world",
|
"description": "Position in the world",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -19,8 +19,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GatheringPaths", "Gathering
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GatheringPathRenderer", "GatheringPathRenderer\GatheringPathRenderer.csproj", "{F514DA95-9867-4F3F-8062-ACE0C62E8740}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GatheringPathRenderer", "GatheringPathRenderer\GatheringPathRenderer.csproj", "{F514DA95-9867-4F3F-8062-ACE0C62E8740}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ECommons", "vendor\ECommons\ECommons\ECommons.csproj", "{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BBFFC6EA-15B1-48FC-B4D3-D9491278C27F}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BBFFC6EA-15B1-48FC-B4D3-D9491278C27F}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
Directory.Build.targets = Directory.Build.targets
|
Directory.Build.targets = Directory.Build.targets
|
||||||
@ -30,6 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "vendor", "vendor", "{8F5EC9
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationMasterAPI", "vendor\NotificationMasterAPI\NotificationMasterAPI\NotificationMasterAPI.csproj", "{9BD494ED-22F2-487B-BCE1-435399A8720E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationMasterAPI", "vendor\NotificationMasterAPI\NotificationMasterAPI\NotificationMasterAPI.csproj", "{9BD494ED-22F2-487B-BCE1-435399A8720E}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pictomancy", "vendor\pictomancy\Pictomancy\Pictomancy.csproj", "{D1AE2F8C-BDE7-457F-A369-973101044A25}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@ -68,20 +68,20 @@ Global
|
|||||||
{F514DA95-9867-4F3F-8062-ACE0C62E8740}.Debug|x64.Build.0 = Debug|x64
|
{F514DA95-9867-4F3F-8062-ACE0C62E8740}.Debug|x64.Build.0 = Debug|x64
|
||||||
{F514DA95-9867-4F3F-8062-ACE0C62E8740}.Release|x64.ActiveCfg = Release|x64
|
{F514DA95-9867-4F3F-8062-ACE0C62E8740}.Release|x64.ActiveCfg = Release|x64
|
||||||
{F514DA95-9867-4F3F-8062-ACE0C62E8740}.Release|x64.Build.0 = Release|x64
|
{F514DA95-9867-4F3F-8062-ACE0C62E8740}.Release|x64.Build.0 = Release|x64
|
||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.Build.0 = Release|x64
|
|
||||||
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Debug|x64.ActiveCfg = Debug|x64
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Debug|x64.Build.0 = Debug|x64
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Debug|x64.Build.0 = Debug|x64
|
||||||
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Release|x64.ActiveCfg = Release|x64
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Release|x64.ActiveCfg = Release|x64
|
||||||
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Release|x64.Build.0 = Release|x64
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{D1AE2F8C-BDE7-457F-A369-973101044A25}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{D1AE2F8C-BDE7-457F-A369-973101044A25}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{D1AE2F8C-BDE7-457F-A369-973101044A25}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D1AE2F8C-BDE7-457F-A369-973101044A25}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B} = {8F5EC9D5-4CE7-433B-BB3A-782500E84DDB}
|
|
||||||
{9BD494ED-22F2-487B-BCE1-435399A8720E} = {8F5EC9D5-4CE7-433B-BB3A-782500E84DDB}
|
{9BD494ED-22F2-487B-BCE1-435399A8720E} = {8F5EC9D5-4CE7-433B-BB3A-782500E84DDB}
|
||||||
|
{D1AE2F8C-BDE7-457F-A369-973101044A25} = {8F5EC9D5-4CE7-433B-BB3A-782500E84DDB}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Dalamud.Configuration;
|
using Dalamud.Configuration;
|
||||||
using Dalamud.Game.Text;
|
using Dalamud.Game.Text;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
@ -14,6 +15,7 @@ internal sealed class Configuration : IPluginConfiguration
|
|||||||
public int PluginSetupCompleteVersion { get; set; }
|
public int PluginSetupCompleteVersion { get; set; }
|
||||||
public GeneralConfiguration General { get; } = new();
|
public GeneralConfiguration General { get; } = new();
|
||||||
public DutyConfiguration Duties { get; } = new();
|
public DutyConfiguration Duties { get; } = new();
|
||||||
|
public SinglePlayerDutyConfiguration SinglePlayerDuties { get; } = new();
|
||||||
public NotificationConfiguration Notifications { get; } = new();
|
public NotificationConfiguration Notifications { get; } = new();
|
||||||
public AdvancedConfiguration Advanced { get; } = new();
|
public AdvancedConfiguration Advanced { get; } = new();
|
||||||
public WindowConfig DebugWindowConfig { get; } = new();
|
public WindowConfig DebugWindowConfig { get; } = new();
|
||||||
@ -41,6 +43,17 @@ internal sealed class Configuration : IPluginConfiguration
|
|||||||
public HashSet<uint> BlacklistedDutyCfcIds { get; set; } = [];
|
public HashSet<uint> BlacklistedDutyCfcIds { get; set; } = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal sealed class SinglePlayerDutyConfiguration
|
||||||
|
{
|
||||||
|
public bool RunSoloInstancesWithBossMod { get; set; }
|
||||||
|
|
||||||
|
[SuppressMessage("Performance", "CA1822", Justification = "Will be fixed when no longer WIP")]
|
||||||
|
public byte RetryDifficulty => 0;
|
||||||
|
|
||||||
|
public HashSet<uint> WhitelistedSinglePlayerDutyCfcIds { get; set; } = [];
|
||||||
|
public HashSet<uint> BlacklistedSinglePlayerDutyCfcIds { get; set; } = [];
|
||||||
|
}
|
||||||
|
|
||||||
internal sealed class NotificationConfiguration
|
internal sealed class NotificationConfiguration
|
||||||
{
|
{
|
||||||
public bool Enabled { get; set; } = true;
|
public bool Enabled { get; set; } = true;
|
||||||
|
@ -9,33 +9,26 @@ using Questionable.Model;
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using Questionable.External;
|
||||||
|
|
||||||
namespace Questionable.Controller.CombatModules;
|
namespace Questionable.Controller.CombatModules;
|
||||||
|
|
||||||
internal sealed class BossModModule : ICombatModule, IDisposable
|
internal sealed class BossModModule : ICombatModule, IDisposable
|
||||||
{
|
{
|
||||||
private const string Name = "BossMod";
|
|
||||||
private readonly ILogger<BossModModule> _logger;
|
private readonly ILogger<BossModModule> _logger;
|
||||||
|
private readonly BossModIpc _bossModIpc;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly ICallGateSubscriber<string, string?> _getPreset;
|
|
||||||
private readonly ICallGateSubscriber<string, bool, bool> _createPreset;
|
|
||||||
private readonly ICallGateSubscriber<string, bool> _setPreset;
|
|
||||||
private readonly ICallGateSubscriber<bool> _clearPreset;
|
|
||||||
|
|
||||||
private static Stream Preset => typeof(BossModModule).Assembly.GetManifestResourceStream("Questionable.Controller.CombatModules.BossModPreset")!;
|
private static Stream Preset => typeof(BossModModule).Assembly.GetManifestResourceStream("Questionable.Controller.CombatModules.BossModPreset")!;
|
||||||
|
|
||||||
public BossModModule(
|
public BossModModule(
|
||||||
ILogger<BossModModule> logger,
|
ILogger<BossModModule> logger,
|
||||||
IDalamudPluginInterface pluginInterface,
|
BossModIpc bossModIpc,
|
||||||
Configuration configuration)
|
Configuration configuration)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_bossModIpc = bossModIpc;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
|
|
||||||
_getPreset = pluginInterface.GetIpcSubscriber<string, string?>($"{Name}.Presets.Get");
|
|
||||||
_createPreset = pluginInterface.GetIpcSubscriber<string, bool, bool>($"{Name}.Presets.Create");
|
|
||||||
_setPreset = pluginInterface.GetIpcSubscriber<string, bool>($"{Name}.Presets.SetActive");
|
|
||||||
_clearPreset = pluginInterface.GetIpcSubscriber<bool>($"{Name}.Presets.ClearActive");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||||
@ -43,26 +36,19 @@ internal sealed class BossModModule : ICombatModule, IDisposable
|
|||||||
if (_configuration.General.CombatModule != Configuration.ECombatModule.BossMod)
|
if (_configuration.General.CombatModule != Configuration.ECombatModule.BossMod)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
try
|
return _bossModIpc.IsSupported();
|
||||||
{
|
|
||||||
return _getPreset.HasFunction;
|
|
||||||
}
|
|
||||||
catch (IpcError)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Start(CombatController.CombatData combatData)
|
public bool Start(CombatController.CombatData combatData)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_getPreset.InvokeFunc("Questionable") == null)
|
if (_bossModIpc.GetPreset("Questionable") == null)
|
||||||
{
|
{
|
||||||
using var reader = new StreamReader(Preset);
|
using var reader = new StreamReader(Preset);
|
||||||
_logger.LogInformation("Loading Questionable BossMod Preset: {LoadedState}", _createPreset.InvokeFunc(reader.ReadToEnd(), true));
|
_logger.LogInformation("Loading Questionable BossMod Preset: {LoadedState}", _bossModIpc.CreatePreset(reader.ReadToEnd(), true));
|
||||||
}
|
}
|
||||||
_setPreset.InvokeFunc("Questionable");
|
_bossModIpc.SetPreset("Questionable");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (IpcError e)
|
catch (IpcError e)
|
||||||
@ -76,7 +62,7 @@ internal sealed class BossModModule : ICombatModule, IDisposable
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_clearPreset.InvokeFunc();
|
_bossModIpc.ClearPreset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (IpcError e)
|
catch (IpcError e)
|
||||||
|
@ -19,6 +19,7 @@ using Lumina.Excel.Sheets;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Questionable.Controller.Steps.Interactions;
|
using Questionable.Controller.Steps.Interactions;
|
||||||
using Questionable.Data;
|
using Questionable.Data;
|
||||||
|
using Questionable.External;
|
||||||
using Questionable.Functions;
|
using Questionable.Functions;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.Gathering;
|
using Questionable.Model.Gathering;
|
||||||
@ -45,6 +46,8 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
private readonly ITargetManager _targetManager;
|
private readonly ITargetManager _targetManager;
|
||||||
private readonly IClientState _clientState;
|
private readonly IClientState _clientState;
|
||||||
private readonly ShopController _shopController;
|
private readonly ShopController _shopController;
|
||||||
|
private readonly BossModIpc _bossModIpc;
|
||||||
|
private readonly Configuration _configuration;
|
||||||
private readonly ILogger<InteractionUiController> _logger;
|
private readonly ILogger<InteractionUiController> _logger;
|
||||||
private readonly Regex _returnRegex;
|
private readonly Regex _returnRegex;
|
||||||
private readonly Regex _purchaseItemRegex;
|
private readonly Regex _purchaseItemRegex;
|
||||||
@ -68,6 +71,8 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
IPluginLog pluginLog,
|
IPluginLog pluginLog,
|
||||||
IClientState clientState,
|
IClientState clientState,
|
||||||
ShopController shopController,
|
ShopController shopController,
|
||||||
|
BossModIpc bossModIpc,
|
||||||
|
Configuration configuration,
|
||||||
ILogger<InteractionUiController> logger)
|
ILogger<InteractionUiController> logger)
|
||||||
{
|
{
|
||||||
_addonLifecycle = addonLifecycle;
|
_addonLifecycle = addonLifecycle;
|
||||||
@ -85,6 +90,8 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
_targetManager = targetManager;
|
_targetManager = targetManager;
|
||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
_shopController = shopController;
|
_shopController = shopController;
|
||||||
|
_bossModIpc = bossModIpc;
|
||||||
|
_configuration = configuration;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_returnRegex = _dataManager.GetExcelSheet<Addon>().GetRow(196).GetRegex(addon => addon.Text, pluginLog)!;
|
_returnRegex = _dataManager.GetExcelSheet<Addon>().GetRow(196).GetRegex(addon => addon.Text, pluginLog)!;
|
||||||
@ -94,6 +101,7 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "CutSceneSelectString", CutsceneSelectStringPostSetup);
|
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "CutSceneSelectString", CutsceneSelectStringPostSetup);
|
||||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectIconString", SelectIconStringPostSetup);
|
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectIconString", SelectIconStringPostSetup);
|
||||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesnoPostSetup);
|
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesnoPostSetup);
|
||||||
|
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "DifficultySelectYesNo", DifficultySelectYesNoPostSetup);
|
||||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "PointMenu", PointMenuPostSetup);
|
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "PointMenu", PointMenuPostSetup);
|
||||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "HousingSelectBlock", HousingSelectBlockPostSetup);
|
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "HousingSelectBlock", HousingSelectBlockPostSetup);
|
||||||
|
|
||||||
@ -140,6 +148,12 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
SelectYesnoPostSetup(addonSelectYesno, true);
|
SelectYesnoPostSetup(addonSelectYesno, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_gameGui.TryGetAddonByName("DifficultySelectYesNo", out AtkUnitBase* addonDifficultySelectYesNo))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("DifficultySelectYesNo window is open");
|
||||||
|
DifficultySelectYesNoPostSetup(addonDifficultySelectYesNo, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (_gameGui.TryGetAddonByName("PointMenu", out AtkUnitBase* addonPointMenu))
|
if (_gameGui.TryGetAddonByName("PointMenu", out AtkUnitBase* addonPointMenu))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("PointMenu is open");
|
_logger.LogInformation("PointMenu is open");
|
||||||
@ -176,8 +190,11 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
|
|
||||||
int? answer = HandleListChoice(actualPrompt, answers, checkAllSteps) ?? HandleInstanceListChoice(actualPrompt);
|
int? answer = HandleListChoice(actualPrompt, answers, checkAllSteps) ?? HandleInstanceListChoice(actualPrompt);
|
||||||
if (answer != null)
|
if (answer != null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Using choice {Choice} for list prompt '{Prompt}'", answer, actualPrompt);
|
||||||
addonSelectString->AtkUnitBase.FireCallbackInt(answer.Value);
|
addonSelectString->AtkUnitBase.FireCallbackInt(answer.Value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private unsafe void CutsceneSelectStringPostSetup(AddonEvent type, AddonArgs args)
|
private unsafe void CutsceneSelectStringPostSetup(AddonEvent type, AddonArgs args)
|
||||||
{
|
{
|
||||||
@ -224,6 +241,7 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
int? answer = HandleListChoice(actualPrompt, answers, checkAllSteps);
|
int? answer = HandleListChoice(actualPrompt, answers, checkAllSteps);
|
||||||
if (answer != null)
|
if (answer != null)
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation("Using choice {Choice} for list prompt '{Prompt}'", answer, actualPrompt);
|
||||||
addonSelectIconString->AtkUnitBase.FireCallbackInt(answer.Value);
|
addonSelectIconString->AtkUnitBase.FireCallbackInt(answer.Value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -266,6 +284,7 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
int questSelection = answers.FindIndex(x => GameFunctions.GameStringEquals(questName, x));
|
int questSelection = answers.FindIndex(x => GameFunctions.GameStringEquals(questName, x));
|
||||||
if (questSelection >= 0)
|
if (questSelection >= 0)
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation("Selecting quest {QuestName}", questName);
|
||||||
addonSelectIconString->AtkUnitBase.FireCallbackInt(questSelection);
|
addonSelectIconString->AtkUnitBase.FireCallbackInt(questSelection);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -598,14 +617,14 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
if (checkAllSteps)
|
if (checkAllSteps)
|
||||||
{
|
{
|
||||||
var sequence = quest.FindSequence(currentQuest.Sequence);
|
var sequence = quest.FindSequence(currentQuest.Sequence);
|
||||||
if (sequence != null && HandleDefaultYesNo(addonSelectYesno, quest,
|
if (sequence != null &&
|
||||||
sequence.Steps.SelectMany(x => x.DialogueChoices).ToList(), actualPrompt))
|
sequence.Steps.Any(step => HandleDefaultYesNo(addonSelectYesno, quest, step, step.DialogueChoices, actualPrompt)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var step = quest.FindSequence(currentQuest.Sequence)?.FindStep(currentQuest.Step);
|
var step = quest.FindSequence(currentQuest.Sequence)?.FindStep(currentQuest.Step);
|
||||||
if (step != null && HandleDefaultYesNo(addonSelectYesno, quest, step.DialogueChoices, actualPrompt))
|
if (step != null && HandleDefaultYesNo(addonSelectYesno, quest, step, step.DialogueChoices, actualPrompt))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,7 +638,7 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
Yes = true
|
Yes = true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (HandleDefaultYesNo(addonSelectYesno, quest, [dialogueChoice], actualPrompt))
|
if (HandleDefaultYesNo(addonSelectYesno, quest, null, [dialogueChoice], actualPrompt))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,7 +649,7 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
private unsafe bool HandleDefaultYesNo(AddonSelectYesno* addonSelectYesno, Quest quest,
|
private unsafe bool HandleDefaultYesNo(AddonSelectYesno* addonSelectYesno, Quest quest,
|
||||||
List<DialogueChoice> dialogueChoices, string actualPrompt)
|
QuestStep? step, List<DialogueChoice> dialogueChoices, string actualPrompt)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("DefaultYesNo: Choice count: {Count}", dialogueChoices.Count);
|
_logger.LogTrace("DefaultYesNo: Choice count: {Count}", dialogueChoices.Count);
|
||||||
foreach (var dialogueChoice in dialogueChoices)
|
foreach (var dialogueChoice in dialogueChoices)
|
||||||
@ -655,10 +674,35 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("Returning {YesNo} for '{Prompt}'", dialogueChoice.Yes ? "Yes" : "No", actualPrompt);
|
||||||
addonSelectYesno->AtkUnitBase.FireCallbackInt(dialogueChoice.Yes ? 0 : 1);
|
addonSelectYesno->AtkUnitBase.FireCallbackInt(dialogueChoice.Yes ? 0 : 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CheckSinglePlayerDutyYesNo(quest.Id, step))
|
||||||
|
{
|
||||||
|
addonSelectYesno->AtkUnitBase.FireCallbackInt(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckSinglePlayerDutyYesNo(ElementId questId, QuestStep? step)
|
||||||
|
{
|
||||||
|
if (step is { InteractionType: EInteractionType.SinglePlayerDuty } &&
|
||||||
|
_bossModIpc.IsConfiguredToRunSoloInstance(questId, step.SinglePlayerDutyOptions))
|
||||||
|
{
|
||||||
|
// Most of these are yes/no dialogs "Duty calls, ...".
|
||||||
|
//
|
||||||
|
// For 'Vows of Virtue, Deeds of Cruelty', there's no such dialog, and it just puts you into the instance
|
||||||
|
// after you confirm 'Wait for Krile?'. However, if you fail that duty, you'll get a DifficultySelectYesNo.
|
||||||
|
|
||||||
|
// DifficultySelectYesNo → [0, 2] for very easy
|
||||||
|
_logger.LogInformation("SinglePlayerDutyYesNo: probably Single Player Duty");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,6 +736,44 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private unsafe void DifficultySelectYesNoPostSetup(AddonEvent type, AddonArgs args)
|
||||||
|
{
|
||||||
|
AtkUnitBase* addonDifficultySelectYesNo = (AtkUnitBase*)args.Addon;
|
||||||
|
DifficultySelectYesNoPostSetup(addonDifficultySelectYesNo, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe void DifficultySelectYesNoPostSetup(AtkUnitBase* addonDifficultySelectYesNo, bool checkAllSteps)
|
||||||
|
{
|
||||||
|
var currentQuest = _questController.StartedQuest;
|
||||||
|
if (currentQuest == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var quest = currentQuest.Quest;
|
||||||
|
bool autoConfirm;
|
||||||
|
if (checkAllSteps)
|
||||||
|
{
|
||||||
|
var sequence = quest.FindSequence(currentQuest.Sequence);
|
||||||
|
autoConfirm = sequence != null && sequence.Steps.Any(step => CheckSinglePlayerDutyYesNo(quest.Id, step));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var step = quest.FindSequence(currentQuest.Sequence)?.FindStep(currentQuest.Step);
|
||||||
|
autoConfirm = step != null && CheckSinglePlayerDutyYesNo(quest.Id, step);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (autoConfirm)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Confirming difficulty ({Difficulty}) for quest battle", _configuration.SinglePlayerDuties.RetryDifficulty);
|
||||||
|
var selectChoice = stackalloc AtkValue[]
|
||||||
|
{
|
||||||
|
new() { Type = ValueType.Int, Int = 0 },
|
||||||
|
new() { Type = ValueType.Int, Int = _configuration.SinglePlayerDuties.RetryDifficulty }
|
||||||
|
};
|
||||||
|
addonDifficultySelectYesNo->FireCallback(2, selectChoice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ushort? FindTargetTerritoryFromQuestStep(QuestController.QuestProgress currentQuest)
|
private ushort? FindTargetTerritoryFromQuestStep(QuestController.QuestProgress currentQuest)
|
||||||
{
|
{
|
||||||
// this can be triggered either manually (in which case we should increase the step counter), or automatically
|
// this can be triggered either manually (in which case we should increase the step counter), or automatically
|
||||||
@ -864,6 +946,7 @@ internal sealed class InteractionUiController : IDisposable
|
|||||||
{
|
{
|
||||||
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "HousingSelectBlock", HousingSelectBlockPostSetup);
|
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "HousingSelectBlock", HousingSelectBlockPostSetup);
|
||||||
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "PointMenu", PointMenuPostSetup);
|
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "PointMenu", PointMenuPostSetup);
|
||||||
|
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "DifficultySelectYesNo", DifficultySelectYesNoPostSetup);
|
||||||
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesnoPostSetup);
|
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesnoPostSetup);
|
||||||
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "SelectIconString", SelectIconStringPostSetup);
|
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "SelectIconString", SelectIconStringPostSetup);
|
||||||
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "CutSceneSelectString", CutsceneSelectStringPostSetup);
|
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "CutSceneSelectString", CutsceneSelectStringPostSetup);
|
||||||
|
@ -10,11 +10,13 @@ using Dalamud.Plugin.Services;
|
|||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Questionable.Controller.Steps;
|
using Questionable.Controller.Steps;
|
||||||
|
using Questionable.Controller.Steps.Interactions;
|
||||||
using Questionable.Controller.Steps.Shared;
|
using Questionable.Controller.Steps.Shared;
|
||||||
using Questionable.External;
|
using Questionable.External;
|
||||||
using Questionable.Functions;
|
using Questionable.Functions;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
|
using Questionable.Windows.ConfigComponents;
|
||||||
using Quest = Questionable.Model.Quest;
|
using Quest = Questionable.Model.Quest;
|
||||||
|
|
||||||
namespace Questionable.Controller;
|
namespace Questionable.Controller;
|
||||||
@ -35,6 +37,7 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly YesAlreadyIpc _yesAlreadyIpc;
|
private readonly YesAlreadyIpc _yesAlreadyIpc;
|
||||||
private readonly TaskCreator _taskCreator;
|
private readonly TaskCreator _taskCreator;
|
||||||
|
private readonly SinglePlayerDutyConfigComponent _singlePlayerDutyConfigComponent;
|
||||||
private readonly ILogger<QuestController> _logger;
|
private readonly ILogger<QuestController> _logger;
|
||||||
|
|
||||||
private readonly object _progressLock = new();
|
private readonly object _progressLock = new();
|
||||||
@ -76,7 +79,8 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||||||
TaskCreator taskCreator,
|
TaskCreator taskCreator,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
InterruptHandler interruptHandler,
|
InterruptHandler interruptHandler,
|
||||||
IDataManager dataManager)
|
IDataManager dataManager,
|
||||||
|
SinglePlayerDutyConfigComponent singlePlayerDutyConfigComponent)
|
||||||
: base(chatGui, condition, serviceProvider, interruptHandler, dataManager, logger)
|
: base(chatGui, condition, serviceProvider, interruptHandler, dataManager, logger)
|
||||||
{
|
{
|
||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
@ -93,6 +97,7 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_yesAlreadyIpc = yesAlreadyIpc;
|
_yesAlreadyIpc = yesAlreadyIpc;
|
||||||
_taskCreator = taskCreator;
|
_taskCreator = taskCreator;
|
||||||
|
_singlePlayerDutyConfigComponent = singlePlayerDutyConfigComponent;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_condition.ConditionChange += OnConditionChange;
|
_condition.ConditionChange += OnConditionChange;
|
||||||
@ -169,6 +174,7 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||||||
DebugState = null;
|
DebugState = null;
|
||||||
|
|
||||||
_questRegistry.Reload();
|
_questRegistry.Reload();
|
||||||
|
_singlePlayerDutyConfigComponent.Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +201,13 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||||||
|
|
||||||
if (!_clientState.IsLoggedIn || _condition[ConditionFlag.Unconscious])
|
if (!_clientState.IsLoggedIn || _condition[ConditionFlag.Unconscious])
|
||||||
{
|
{
|
||||||
if (!_taskQueue.AllTasksComplete)
|
if (_condition[ConditionFlag.Unconscious] &&
|
||||||
|
_condition[ConditionFlag.SufferingStatusAffliction63] &&
|
||||||
|
_clientState.TerritoryType == SinglePlayerDuty.LahabreaTerritoryId)
|
||||||
|
{
|
||||||
|
// ignore, we're in the lahabrea fight
|
||||||
|
}
|
||||||
|
else if (!_taskQueue.AllTasksComplete)
|
||||||
{
|
{
|
||||||
Stop("HP = 0");
|
Stop("HP = 0");
|
||||||
_movementController.Stop();
|
_movementController.Stop();
|
||||||
@ -757,6 +769,10 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||||||
if (ManualPriorityQuests.Contains(currentQuest.Quest))
|
if (ManualPriorityQuests.Contains(currentQuest.Quest))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// "ifrit bleeds, we can kill it" isn't listed as priority quest, as we accept it during the MSQ 'Moving On'
|
||||||
|
if (currentQuest.Quest.Id is QuestId { Value: 1048 })
|
||||||
|
return false;
|
||||||
|
|
||||||
if (currentQuest.Quest.Info.AlliedSociety != EAlliedSociety.None)
|
if (currentQuest.Quest.Info.AlliedSociety != EAlliedSociety.None)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ internal sealed class QuestRegistry
|
|||||||
private readonly JsonSchemaValidator _jsonSchemaValidator;
|
private readonly JsonSchemaValidator _jsonSchemaValidator;
|
||||||
private readonly ILogger<QuestRegistry> _logger;
|
private readonly ILogger<QuestRegistry> _logger;
|
||||||
private readonly LeveData _leveData;
|
private readonly LeveData _leveData;
|
||||||
|
private readonly TerritoryData _territoryData;
|
||||||
|
|
||||||
private readonly ICallGateProvider<object> _reloadDataIpc;
|
private readonly ICallGateProvider<object> _reloadDataIpc;
|
||||||
private readonly Dictionary<ElementId, Quest> _quests = [];
|
private readonly Dictionary<ElementId, Quest> _quests = [];
|
||||||
@ -34,7 +35,7 @@ internal sealed class QuestRegistry
|
|||||||
|
|
||||||
public QuestRegistry(IDalamudPluginInterface pluginInterface, QuestData questData,
|
public QuestRegistry(IDalamudPluginInterface pluginInterface, QuestData questData,
|
||||||
QuestValidator questValidator, JsonSchemaValidator jsonSchemaValidator,
|
QuestValidator questValidator, JsonSchemaValidator jsonSchemaValidator,
|
||||||
ILogger<QuestRegistry> logger, LeveData leveData)
|
ILogger<QuestRegistry> logger, LeveData leveData, TerritoryData territoryData)
|
||||||
{
|
{
|
||||||
_pluginInterface = pluginInterface;
|
_pluginInterface = pluginInterface;
|
||||||
_questData = questData;
|
_questData = questData;
|
||||||
@ -42,6 +43,7 @@ internal sealed class QuestRegistry
|
|||||||
_jsonSchemaValidator = jsonSchemaValidator;
|
_jsonSchemaValidator = jsonSchemaValidator;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_leveData = leveData;
|
_leveData = leveData;
|
||||||
|
_territoryData = territoryData;
|
||||||
_reloadDataIpc = _pluginInterface.GetIpcProvider<object>("Questionable.ReloadData");
|
_reloadDataIpc = _pluginInterface.GetIpcProvider<object>("Questionable.ReloadData");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,9 +152,15 @@ internal sealed class QuestRegistry
|
|||||||
foreach (var quest in _quests.Values)
|
foreach (var quest in _quests.Values)
|
||||||
{
|
{
|
||||||
foreach (var dutyStep in quest.AllSteps().Where(x =>
|
foreach (var dutyStep in quest.AllSteps().Where(x =>
|
||||||
x.Step.InteractionType == EInteractionType.Duty && x.Step.ContentFinderConditionId != null))
|
x.Step.InteractionType is EInteractionType.Duty or EInteractionType.SinglePlayerDuty))
|
||||||
{
|
{
|
||||||
_contentFinderConditionIds[dutyStep.Step.ContentFinderConditionId!.Value] = (quest.Id, dutyStep.Step);
|
if (dutyStep.Step is { InteractionType: EInteractionType.Duty, ContentFinderConditionId: not null })
|
||||||
|
_contentFinderConditionIds[dutyStep.Step.ContentFinderConditionId!.Value] =
|
||||||
|
(quest.Id, dutyStep.Step);
|
||||||
|
else if (dutyStep.Step.InteractionType == EInteractionType.SinglePlayerDuty &&
|
||||||
|
_territoryData.TryGetContentFinderConditionForSoloInstance(quest.Id,
|
||||||
|
dutyStep.Step.SinglePlayerDutyIndex, out var cfcData))
|
||||||
|
_contentFinderConditionIds[cfcData.ContentFinderConditionId] = (quest.Id, dutyStep.Step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,11 +240,11 @@ internal sealed class QuestRegistry
|
|||||||
public bool TryGetQuest(ElementId questId, [NotNullWhen(true)] out Quest? quest)
|
public bool TryGetQuest(ElementId questId, [NotNullWhen(true)] out Quest? quest)
|
||||||
=> _quests.TryGetValue(questId, out quest);
|
=> _quests.TryGetValue(questId, out quest);
|
||||||
|
|
||||||
public List<QuestInfo> GetKnownClassJobQuests(EClassJob classJob)
|
public List<QuestInfo> GetKnownClassJobQuests(EClassJob classJob, bool includeRoleQuests = true)
|
||||||
{
|
{
|
||||||
List<QuestInfo> allQuests = [.._questData.GetClassJobQuests(classJob)];
|
List<QuestInfo> allQuests = [.._questData.GetClassJobQuests(classJob, includeRoleQuests)];
|
||||||
if (classJob.AsJob() != classJob)
|
if (classJob.AsJob() != classJob)
|
||||||
allQuests.AddRange(_questData.GetClassJobQuests(classJob.AsJob()));
|
allQuests.AddRange(_questData.GetClassJobQuests(classJob.AsJob(), includeRoleQuests));
|
||||||
|
|
||||||
return allQuests
|
return allQuests
|
||||||
.Where(x => IsKnownQuest(x.QuestId))
|
.Where(x => IsKnownQuest(x.QuestId))
|
||||||
|
@ -37,7 +37,7 @@ internal static class Mount
|
|||||||
private bool _mountTriggered;
|
private bool _mountTriggered;
|
||||||
private DateTime _retryAt = DateTime.MinValue;
|
private DateTime _retryAt = DateTime.MinValue;
|
||||||
|
|
||||||
public MountResult EvaluateMountState()
|
public unsafe MountResult EvaluateMountState()
|
||||||
{
|
{
|
||||||
if (condition[ConditionFlag.Mounted])
|
if (condition[ConditionFlag.Mounted])
|
||||||
return MountResult.DontMount;
|
return MountResult.DontMount;
|
||||||
@ -58,7 +58,7 @@ internal static class Mount
|
|||||||
{
|
{
|
||||||
Vector3 playerPosition = clientState.LocalPlayer?.Position ?? Vector3.Zero;
|
Vector3 playerPosition = clientState.LocalPlayer?.Position ?? Vector3.Zero;
|
||||||
float distance = System.Numerics.Vector3.Distance(playerPosition, Task.Position.GetValueOrDefault());
|
float distance = System.Numerics.Vector3.Distance(playerPosition, Task.Position.GetValueOrDefault());
|
||||||
if (Task.TerritoryId == clientState.TerritoryType && distance < 30f && !Conditions.IsDiving)
|
if (Task.TerritoryId == clientState.TerritoryType && distance < 30f && !Conditions.Instance()->Diving)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Not using mount, as we're close to the target");
|
logger.LogInformation("Not using mount, as we're close to the target");
|
||||||
return MountResult.DontMount;
|
return MountResult.DontMount;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using System.Linq;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Questionable.Data;
|
||||||
using Questionable.Functions;
|
using Questionable.Functions;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
@ -21,7 +23,7 @@ internal static class NextQuest
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
// probably irrelevant, since pick up is handled elsewhere (and, in particular, checks for aetherytes and stuff)
|
// probably irrelevant, since pick up is handled elsewhere (and, in particular, checks for aetherytes and stuff)
|
||||||
if (questFunctions.GetPriorityQuests().Contains(step.NextQuestId))
|
if (questFunctions.GetPriorityQuests(onlyClassAndRoleQuests: true).Contains(step.NextQuestId))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new SetQuestTask(step.NextQuestId, quest.Id);
|
return new SetQuestTask(step.NextQuestId, quest.Id);
|
||||||
|
@ -14,6 +14,7 @@ internal static class SendNotification
|
|||||||
internal sealed class Factory(
|
internal sealed class Factory(
|
||||||
AutomatonIpc automatonIpc,
|
AutomatonIpc automatonIpc,
|
||||||
AutoDutyIpc autoDutyIpc,
|
AutoDutyIpc autoDutyIpc,
|
||||||
|
BossModIpc bossModIpc,
|
||||||
TerritoryData territoryData) : SimpleTaskFactory
|
TerritoryData territoryData) : SimpleTaskFactory
|
||||||
{
|
{
|
||||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||||
@ -26,7 +27,8 @@ internal static class SendNotification
|
|||||||
new Task(step.InteractionType, step.ContentFinderConditionId.HasValue
|
new Task(step.InteractionType, step.ContentFinderConditionId.HasValue
|
||||||
? territoryData.GetContentFinderCondition(step.ContentFinderConditionId.Value)?.Name
|
? territoryData.GetContentFinderCondition(step.ContentFinderConditionId.Value)?.Name
|
||||||
: step.Comment),
|
: step.Comment),
|
||||||
EInteractionType.SinglePlayerDuty => new Task(step.InteractionType, quest.Info.Name),
|
EInteractionType.SinglePlayerDuty when !bossModIpc.IsConfiguredToRunSoloInstance(quest.Id, step.SinglePlayerDutyOptions) =>
|
||||||
|
new Task(step.InteractionType, quest.Info.Name),
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,12 @@ internal static class Interact
|
|||||||
private EInteractionState _interactionState = EInteractionState.None;
|
private EInteractionState _interactionState = EInteractionState.None;
|
||||||
private DateTime _continueAt = DateTime.MinValue;
|
private DateTime _continueAt = DateTime.MinValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A slight delay when we think an interaction has ended, to make sure that we're processing "Action cancelled"
|
||||||
|
/// prior to the next step (in case we're attacked).
|
||||||
|
/// </summary>
|
||||||
|
private bool delayedFinalCheck;
|
||||||
|
|
||||||
public Quest? Quest => Task.Quest;
|
public Quest? Quest => Task.Quest;
|
||||||
public EInteractionType InteractionType { get; set; }
|
public EInteractionType InteractionType { get; set; }
|
||||||
|
|
||||||
@ -179,7 +185,14 @@ internal static class Interact
|
|||||||
return ETaskResult.StillRunning;
|
return ETaskResult.StillRunning;
|
||||||
else if (ProgressContext.WasSuccessful() ||
|
else if (ProgressContext.WasSuccessful() ||
|
||||||
_interactionState == EInteractionState.InteractionConfirmed)
|
_interactionState == EInteractionState.InteractionConfirmed)
|
||||||
|
{
|
||||||
|
if (delayedFinalCheck)
|
||||||
return ETaskResult.TaskComplete;
|
return ETaskResult.TaskComplete;
|
||||||
|
|
||||||
|
_continueAt = DateTime.Now.AddSeconds(0.2);
|
||||||
|
delayedFinalCheck = true;
|
||||||
|
return ETaskResult.StillRunning;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(Task.DataId);
|
IGameObject? gameObject = gameFunctions.FindObjectByDataId(Task.DataId);
|
||||||
|
161
Questionable/Controller/Steps/Interactions/SinglePlayerDuty.cs
Normal file
161
Questionable/Controller/Steps/Interactions/SinglePlayerDuty.cs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
|
using Questionable.Controller.Steps.Common;
|
||||||
|
using Questionable.Controller.Steps.Shared;
|
||||||
|
using Questionable.Data;
|
||||||
|
using Questionable.External;
|
||||||
|
using Questionable.Model;
|
||||||
|
using Questionable.Model.Questing;
|
||||||
|
|
||||||
|
namespace Questionable.Controller.Steps.Interactions;
|
||||||
|
|
||||||
|
internal static class SinglePlayerDuty
|
||||||
|
{
|
||||||
|
public const int LahabreaTerritoryId = 1052;
|
||||||
|
|
||||||
|
internal sealed class Factory(
|
||||||
|
BossModIpc bossModIpc,
|
||||||
|
TerritoryData territoryData,
|
||||||
|
ICondition condition,
|
||||||
|
IClientState clientState) : ITaskFactory
|
||||||
|
{
|
||||||
|
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||||
|
{
|
||||||
|
if (step.InteractionType != EInteractionType.SinglePlayerDuty)
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
if (bossModIpc.IsConfiguredToRunSoloInstance(quest.Id, step.SinglePlayerDutyOptions))
|
||||||
|
{
|
||||||
|
if (!territoryData.TryGetContentFinderConditionForSoloInstance(quest.Id, step.SinglePlayerDutyIndex, out var cfcData))
|
||||||
|
throw new TaskException("Failed to get content finder condition for solo instance");
|
||||||
|
|
||||||
|
yield return new StartSinglePlayerDuty(cfcData.ContentFinderConditionId);
|
||||||
|
yield return new EnableAi();
|
||||||
|
if (cfcData.TerritoryId == LahabreaTerritoryId)
|
||||||
|
{
|
||||||
|
yield return new SetTarget(14643);
|
||||||
|
yield return new WaitCondition.Task(() => condition[ConditionFlag.Unconscious] || clientState.TerritoryType != LahabreaTerritoryId, "Wait(death)");
|
||||||
|
yield return new DisableAi();
|
||||||
|
yield return new WaitCondition.Task(() => !condition[ConditionFlag.Unconscious] || clientState.TerritoryType != LahabreaTerritoryId, "Wait(resurrection)");
|
||||||
|
yield return new EnableAi();
|
||||||
|
}
|
||||||
|
yield return new WaitSinglePlayerDuty(cfcData.ContentFinderConditionId);
|
||||||
|
yield return new DisableAi();
|
||||||
|
yield return new WaitAtEnd.WaitNextStepOrSequence();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed record StartSinglePlayerDuty(uint ContentFinderConditionId) : ITask
|
||||||
|
{
|
||||||
|
public override string ToString() => $"Wait(BossMod, entered instance {ContentFinderConditionId})";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class StartSinglePlayerDutyExecutor : TaskExecutor<StartSinglePlayerDuty>
|
||||||
|
{
|
||||||
|
protected override bool Start() => true;
|
||||||
|
|
||||||
|
public override unsafe ETaskResult Update()
|
||||||
|
{
|
||||||
|
return GameMain.Instance()->CurrentContentFinderConditionId == Task.ContentFinderConditionId
|
||||||
|
? ETaskResult.TaskComplete
|
||||||
|
: ETaskResult.StillRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ShouldInterruptOnDamage() => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed record EnableAi : ITask
|
||||||
|
{
|
||||||
|
public override string ToString() => "BossMod.EnableAi";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class EnableAiExecutor(
|
||||||
|
BossModIpc bossModIpc) : TaskExecutor<EnableAi>
|
||||||
|
{
|
||||||
|
protected override bool Start()
|
||||||
|
{
|
||||||
|
bossModIpc.EnableAi();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ETaskResult Update() => ETaskResult.TaskComplete;
|
||||||
|
|
||||||
|
public override bool ShouldInterruptOnDamage() => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed record WaitSinglePlayerDuty(uint ContentFinderConditionId) : ITask
|
||||||
|
{
|
||||||
|
public override string ToString() => $"Wait(BossMod, left instance {ContentFinderConditionId})";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class WaitSinglePlayerDutyExecutor(
|
||||||
|
BossModIpc bossModIpc) : TaskExecutor<WaitSinglePlayerDuty>, IStoppableTaskExecutor
|
||||||
|
{
|
||||||
|
protected override bool Start() => true;
|
||||||
|
|
||||||
|
public override unsafe ETaskResult Update()
|
||||||
|
{
|
||||||
|
return GameMain.Instance()->CurrentContentFinderConditionId != Task.ContentFinderConditionId
|
||||||
|
? ETaskResult.TaskComplete
|
||||||
|
: ETaskResult.StillRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopNow() => bossModIpc.DisableAi();
|
||||||
|
|
||||||
|
public override bool ShouldInterruptOnDamage() => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed record DisableAi : ITask
|
||||||
|
{
|
||||||
|
public override string ToString() => "BossMod.DisableAi";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class DisableAiExecutor(
|
||||||
|
BossModIpc bossModIpc) : TaskExecutor<DisableAi>
|
||||||
|
{
|
||||||
|
protected override bool Start()
|
||||||
|
{
|
||||||
|
bossModIpc.DisableAi();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ETaskResult Update() => ETaskResult.TaskComplete;
|
||||||
|
|
||||||
|
public override bool ShouldInterruptOnDamage() => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this should be handled in VBM
|
||||||
|
internal sealed record SetTarget(uint DataId) : ITask
|
||||||
|
{
|
||||||
|
public override string ToString() => $"SetTarget({DataId})";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class SetTargetExecutor(
|
||||||
|
ITargetManager targetManager,
|
||||||
|
IObjectTable objectTable) : TaskExecutor<SetTarget>
|
||||||
|
{
|
||||||
|
protected override bool Start() => true;
|
||||||
|
|
||||||
|
public override ETaskResult Update()
|
||||||
|
{
|
||||||
|
if (targetManager.Target?.DataId == Task.DataId)
|
||||||
|
return ETaskResult.TaskComplete;
|
||||||
|
|
||||||
|
IGameObject? gameObject = objectTable.FirstOrDefault(x => x.DataId == Task.DataId);
|
||||||
|
if (gameObject == null)
|
||||||
|
return ETaskResult.StillRunning;
|
||||||
|
|
||||||
|
targetManager.Target = gameObject;
|
||||||
|
return ETaskResult.StillRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ShouldInterruptOnDamage() => false;
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,8 @@ internal static class WaitAtEnd
|
|||||||
IClientState clientState,
|
IClientState clientState,
|
||||||
ICondition condition,
|
ICondition condition,
|
||||||
TerritoryData territoryData,
|
TerritoryData territoryData,
|
||||||
AutoDutyIpc autoDutyIpc)
|
AutoDutyIpc autoDutyIpc,
|
||||||
|
BossModIpc bossModIpc)
|
||||||
: ITaskFactory
|
: ITaskFactory
|
||||||
{
|
{
|
||||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||||
@ -53,7 +54,7 @@ internal static class WaitAtEnd
|
|||||||
return [new WaitNextStepOrSequence()];
|
return [new WaitNextStepOrSequence()];
|
||||||
|
|
||||||
case EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled):
|
case EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled):
|
||||||
case EInteractionType.SinglePlayerDuty:
|
case EInteractionType.SinglePlayerDuty when !bossModIpc.IsConfiguredToRunSoloInstance(quest.Id, step.SinglePlayerDutyOptions):
|
||||||
return [new EndAutomation()];
|
return [new EndAutomation()];
|
||||||
|
|
||||||
case EInteractionType.WalkTo:
|
case EInteractionType.WalkTo:
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Questionable.Controller.Steps.Interactions;
|
||||||
|
using Questionable.Data;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
|
|
||||||
@ -11,11 +14,19 @@ namespace Questionable.Controller.Steps;
|
|||||||
internal sealed class TaskCreator
|
internal sealed class TaskCreator
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly TerritoryData _territoryData;
|
||||||
|
private readonly IClientState _clientState;
|
||||||
private readonly ILogger<TaskCreator> _logger;
|
private readonly ILogger<TaskCreator> _logger;
|
||||||
|
|
||||||
public TaskCreator(IServiceProvider serviceProvider, ILogger<TaskCreator> logger)
|
public TaskCreator(
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
TerritoryData territoryData,
|
||||||
|
IClientState clientState,
|
||||||
|
ILogger<TaskCreator> logger)
|
||||||
{
|
{
|
||||||
_serviceProvider = serviceProvider;
|
_serviceProvider = serviceProvider;
|
||||||
|
_territoryData = territoryData;
|
||||||
|
_clientState = clientState;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +51,31 @@ internal sealed class TaskCreator
|
|||||||
return tasks;
|
return tasks;
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
var singlePlayerDutyTask = newTasks
|
||||||
|
.Where(y => y is SinglePlayerDuty.StartSinglePlayerDuty)
|
||||||
|
.Cast<SinglePlayerDuty.StartSinglePlayerDuty>()
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (singlePlayerDutyTask != null &&
|
||||||
|
_territoryData.TryGetContentFinderCondition(singlePlayerDutyTask.ContentFinderConditionId,
|
||||||
|
out var cfcData))
|
||||||
|
{
|
||||||
|
// if we have a single player duty in queue, we check if we're in the matching territory
|
||||||
|
// if yes, skip all steps before (e.g. teleporting, waiting for navmesh, moving, interacting)
|
||||||
|
if (_clientState.TerritoryType == cfcData.TerritoryId)
|
||||||
|
{
|
||||||
|
int index = newTasks.IndexOf(singlePlayerDutyTask);
|
||||||
|
_logger.LogWarning(
|
||||||
|
"Skipping {SkippedTaskCount} out of {TotalCount} tasks, questionable was started while in single player duty",
|
||||||
|
index + 1, newTasks.Count);
|
||||||
|
|
||||||
|
newTasks.RemoveRange(0, index + 1);
|
||||||
|
_logger.LogInformation("Next actual task: {NextTask}, total tasks left: {RemainingTaskCount}",
|
||||||
|
newTasks.FirstOrDefault(),
|
||||||
|
newTasks.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newTasks.Count == 0)
|
if (newTasks.Count == 0)
|
||||||
_logger.LogInformation("Nothing to execute for step?");
|
_logger.LogInformation("Nothing to execute for step?");
|
||||||
else
|
else
|
||||||
|
169
Questionable/Controller/Utils/PartyWatchDog.cs
Normal file
169
Questionable/Controller/Utils/PartyWatchDog.cs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
using System;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game.Group;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Questionable.Controller.Utils;
|
||||||
|
|
||||||
|
internal sealed class PartyWatchDog : IDisposable
|
||||||
|
{
|
||||||
|
private readonly QuestController _questController;
|
||||||
|
private readonly IClientState _clientState;
|
||||||
|
private readonly IChatGui _chatGui;
|
||||||
|
private readonly ILogger<PartyWatchDog> _logger;
|
||||||
|
|
||||||
|
private ushort? _uncheckedTeritoryId;
|
||||||
|
|
||||||
|
public PartyWatchDog(QuestController questController, IClientState clientState, IChatGui chatGui,
|
||||||
|
ILogger<PartyWatchDog> logger)
|
||||||
|
{
|
||||||
|
_questController = questController;
|
||||||
|
_clientState = clientState;
|
||||||
|
_chatGui = chatGui;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
_clientState.TerritoryChanged += TerritoryChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe void TerritoryChanged(ushort newTerritoryId)
|
||||||
|
{
|
||||||
|
var intendedUse = (ETerritoryIntendedUseEnum)GameMain.Instance()->CurrentTerritoryIntendedUseId;
|
||||||
|
switch (intendedUse)
|
||||||
|
{
|
||||||
|
case ETerritoryIntendedUseEnum.Gaol:
|
||||||
|
case ETerritoryIntendedUseEnum.Frontline:
|
||||||
|
case ETerritoryIntendedUseEnum.LordOfVerminion:
|
||||||
|
case ETerritoryIntendedUseEnum.Diadem:
|
||||||
|
case ETerritoryIntendedUseEnum.CrystallineConflict:
|
||||||
|
case ETerritoryIntendedUseEnum.Battlehall:
|
||||||
|
case ETerritoryIntendedUseEnum.CrystallineConflict2:
|
||||||
|
case ETerritoryIntendedUseEnum.DeepDungeon:
|
||||||
|
case ETerritoryIntendedUseEnum.TreasureMapDuty:
|
||||||
|
case ETerritoryIntendedUseEnum.Diadem2:
|
||||||
|
case ETerritoryIntendedUseEnum.RivalWings:
|
||||||
|
case ETerritoryIntendedUseEnum.Eureka:
|
||||||
|
case ETerritoryIntendedUseEnum.LeapOfFaith:
|
||||||
|
case ETerritoryIntendedUseEnum.OceanFishing:
|
||||||
|
case ETerritoryIntendedUseEnum.Diadem3:
|
||||||
|
case ETerritoryIntendedUseEnum.Bozja:
|
||||||
|
case ETerritoryIntendedUseEnum.Battlehall2:
|
||||||
|
case ETerritoryIntendedUseEnum.Battlehall3:
|
||||||
|
case ETerritoryIntendedUseEnum.LargeScaleRaid:
|
||||||
|
case ETerritoryIntendedUseEnum.LargeScaleSavageRaid:
|
||||||
|
case ETerritoryIntendedUseEnum.Blunderville:
|
||||||
|
StopIfRunning($"Unsupported Area entered ({newTerritoryId})");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ETerritoryIntendedUseEnum.Dungeon:
|
||||||
|
case ETerritoryIntendedUseEnum.VariantDungeon:
|
||||||
|
case ETerritoryIntendedUseEnum.AllianceRaid:
|
||||||
|
case ETerritoryIntendedUseEnum.Trial:
|
||||||
|
case ETerritoryIntendedUseEnum.Raid:
|
||||||
|
case ETerritoryIntendedUseEnum.Raid2:
|
||||||
|
case ETerritoryIntendedUseEnum.SeasonalEvent:
|
||||||
|
case ETerritoryIntendedUseEnum.SeasonalEvent2:
|
||||||
|
case ETerritoryIntendedUseEnum.CriterionDuty:
|
||||||
|
case ETerritoryIntendedUseEnum.CriterionSavageDuty:
|
||||||
|
_uncheckedTeritoryId = newTerritoryId;
|
||||||
|
_logger.LogInformation("Will check territory {TerritoryId} after loading", newTerritoryId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void Update()
|
||||||
|
{
|
||||||
|
if (_uncheckedTeritoryId == _clientState.TerritoryType && GameMain.Instance()->TerritoryLoadState == 2)
|
||||||
|
{
|
||||||
|
var groupManager = GroupManager.Instance();
|
||||||
|
if (groupManager == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
byte memberCount = groupManager->MainGroup.MemberCount;
|
||||||
|
bool isInAlliance = groupManager->MainGroup.IsAlliance;
|
||||||
|
_logger.LogDebug("Territory {TerritoryId} with {MemberCount} members, alliance: {IsInAlliance}",
|
||||||
|
_uncheckedTeritoryId, memberCount, isInAlliance);
|
||||||
|
if (memberCount > 1 || isInAlliance)
|
||||||
|
StopIfRunning("Other party members present");
|
||||||
|
|
||||||
|
_uncheckedTeritoryId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopIfRunning(string reason)
|
||||||
|
{
|
||||||
|
if (_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual)
|
||||||
|
{
|
||||||
|
_chatGui.PrintError(
|
||||||
|
$"Stopping Questionable: {reason}. If you believe this to be correct, please restart Questionable manually.",
|
||||||
|
CommandHandler.MessageTag, CommandHandler.TagColor);
|
||||||
|
_questController.Stop(reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_clientState.TerritoryChanged -= TerritoryChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
// from https://github.com/NightmareXIV/ECommons/blob/f69e460e95134c72592654059843b138b4c01a9e/ECommons/ExcelServices/TerritoryIntendedUseEnum.cs#L5
|
||||||
|
[UsedImplicitly(ImplicitUseTargetFlags.Members, Reason = "game data")]
|
||||||
|
private enum ETerritoryIntendedUseEnum : byte
|
||||||
|
{
|
||||||
|
CityArea = 0,
|
||||||
|
OpenWorld = 1,
|
||||||
|
Inn = 2,
|
||||||
|
Dungeon = 3,
|
||||||
|
VariantDungeon = 4,
|
||||||
|
Gaol = 5,
|
||||||
|
StartingArea = 6,
|
||||||
|
QuestArea = 7,
|
||||||
|
AllianceRaid = 8,
|
||||||
|
QuestBattle = 9,
|
||||||
|
Trial = 10,
|
||||||
|
QuestArea2 = 12,
|
||||||
|
ResidentialArea = 13,
|
||||||
|
HousingInstances = 14,
|
||||||
|
QuestArea3 = 15,
|
||||||
|
Raid = 16,
|
||||||
|
Raid2 = 17,
|
||||||
|
Frontline = 18,
|
||||||
|
ChocoboSquare = 20,
|
||||||
|
RestorationEvent = 21,
|
||||||
|
Sanctum = 22,
|
||||||
|
GoldSaucer = 23,
|
||||||
|
LordOfVerminion = 25,
|
||||||
|
Diadem = 26,
|
||||||
|
HallOfTheNovice = 27,
|
||||||
|
CrystallineConflict = 28,
|
||||||
|
QuestBattle2 = 29,
|
||||||
|
Barracks = 30,
|
||||||
|
DeepDungeon = 31,
|
||||||
|
SeasonalEvent = 32,
|
||||||
|
TreasureMapDuty = 33,
|
||||||
|
SeasonalEventDuty = 34,
|
||||||
|
Battlehall = 35,
|
||||||
|
CrystallineConflict2 = 37,
|
||||||
|
Diadem2 = 38,
|
||||||
|
RivalWings = 39,
|
||||||
|
Unknown1 = 40,
|
||||||
|
Eureka = 41,
|
||||||
|
SeasonalEvent2 = 43,
|
||||||
|
LeapOfFaith = 44,
|
||||||
|
MaskedCarnivale = 45,
|
||||||
|
OceanFishing = 46,
|
||||||
|
Diadem3 = 47,
|
||||||
|
Bozja = 48,
|
||||||
|
IslandSanctuary = 49,
|
||||||
|
Battlehall2 = 50,
|
||||||
|
Battlehall3 = 51,
|
||||||
|
LargeScaleRaid = 52,
|
||||||
|
LargeScaleSavageRaid = 53,
|
||||||
|
QuestArea4 = 54,
|
||||||
|
TribalInstance = 56,
|
||||||
|
CriterionDuty = 57,
|
||||||
|
CriterionSavageDuty = 58,
|
||||||
|
Blunderville = 59,
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ using Dalamud.Plugin.Services;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Questionable.Controller;
|
using Questionable.Controller;
|
||||||
using Questionable.Controller.GameUi;
|
using Questionable.Controller.GameUi;
|
||||||
|
using Questionable.Controller.Utils;
|
||||||
using Questionable.Windows;
|
using Questionable.Windows;
|
||||||
|
|
||||||
namespace Questionable;
|
namespace Questionable;
|
||||||
@ -23,6 +24,7 @@ internal sealed class DalamudInitializer : IDisposable
|
|||||||
private readonly ConfigWindow _configWindow;
|
private readonly ConfigWindow _configWindow;
|
||||||
private readonly IToastGui _toastGui;
|
private readonly IToastGui _toastGui;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
|
private readonly PartyWatchDog _partyWatchDog;
|
||||||
private readonly ILogger<DalamudInitializer> _logger;
|
private readonly ILogger<DalamudInitializer> _logger;
|
||||||
|
|
||||||
public DalamudInitializer(
|
public DalamudInitializer(
|
||||||
@ -42,6 +44,7 @@ internal sealed class DalamudInitializer : IDisposable
|
|||||||
PriorityWindow priorityWindow,
|
PriorityWindow priorityWindow,
|
||||||
IToastGui toastGui,
|
IToastGui toastGui,
|
||||||
Configuration configuration,
|
Configuration configuration,
|
||||||
|
PartyWatchDog partyWatchDog,
|
||||||
ILogger<DalamudInitializer> logger)
|
ILogger<DalamudInitializer> logger)
|
||||||
{
|
{
|
||||||
_pluginInterface = pluginInterface;
|
_pluginInterface = pluginInterface;
|
||||||
@ -54,6 +57,7 @@ internal sealed class DalamudInitializer : IDisposable
|
|||||||
_configWindow = configWindow;
|
_configWindow = configWindow;
|
||||||
_toastGui = toastGui;
|
_toastGui = toastGui;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
|
_partyWatchDog = partyWatchDog;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_windowSystem.AddWindow(oneTimeSetupWindow);
|
_windowSystem.AddWindow(oneTimeSetupWindow);
|
||||||
@ -77,6 +81,7 @@ internal sealed class DalamudInitializer : IDisposable
|
|||||||
|
|
||||||
private void FrameworkUpdate(IFramework framework)
|
private void FrameworkUpdate(IFramework framework)
|
||||||
{
|
{
|
||||||
|
_partyWatchDog.Update();
|
||||||
_questController.Update();
|
_questController.Update();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -23,17 +23,17 @@ internal sealed class JournalData
|
|||||||
var genreLimsa = new Genre(uint.MaxValue - 3, "Starting in Limsa Lominsa", 1,
|
var genreLimsa = new Genre(uint.MaxValue - 3, "Starting in Limsa Lominsa", 1,
|
||||||
new uint[] { 108, 109 }.Concat(limsaStart.QuestRedoParam.Select(x => x.Quest.RowId))
|
new uint[] { 108, 109 }.Concat(limsaStart.QuestRedoParam.Select(x => x.Quest.RowId))
|
||||||
.Where(x => x != 0)
|
.Where(x => x != 0)
|
||||||
.Select(x => questData.GetQuestInfo(new QuestId((ushort)(x & 0xFFFF))))
|
.Select(x => questData.GetQuestInfo(QuestId.FromRowId(x)))
|
||||||
.ToList());
|
.ToList());
|
||||||
var genreGridania = new Genre(uint.MaxValue - 2, "Starting in Gridania", 1,
|
var genreGridania = new Genre(uint.MaxValue - 2, "Starting in Gridania", 1,
|
||||||
new uint[] { 85, 123, 124 }.Concat(gridaniaStart.QuestRedoParam.Select(x => x.Quest.RowId))
|
new uint[] { 85, 123, 124 }.Concat(gridaniaStart.QuestRedoParam.Select(x => x.Quest.RowId))
|
||||||
.Where(x => x != 0)
|
.Where(x => x != 0)
|
||||||
.Select(x => questData.GetQuestInfo(new QuestId((ushort)(x & 0xFFFF))))
|
.Select(x => questData.GetQuestInfo(QuestId.FromRowId(x)))
|
||||||
.ToList());
|
.ToList());
|
||||||
var genreUldah = new Genre(uint.MaxValue - 1, "Starting in Ul'dah", 1,
|
var genreUldah = new Genre(uint.MaxValue - 1, "Starting in Ul'dah", 1,
|
||||||
new uint[] { 568, 569, 570 }.Concat(uldahStart.QuestRedoParam.Select(x => x.Quest.RowId))
|
new uint[] { 568, 569, 570 }.Concat(uldahStart.QuestRedoParam.Select(x => x.Quest.RowId))
|
||||||
.Where(x => x != 0)
|
.Where(x => x != 0)
|
||||||
.Select(x => questData.GetQuestInfo(new QuestId((ushort)(x & 0xFFFF))))
|
.Select(x => questData.GetQuestInfo(QuestId.FromRowId(x)))
|
||||||
.ToList());
|
.ToList());
|
||||||
genres.InsertRange(0, [genreLimsa, genreGridania, genreUldah]);
|
genres.InsertRange(0, [genreLimsa, genreGridania, genreUldah]);
|
||||||
genres.Single(x => x.Id == 1)
|
genres.Single(x => x.Id == 1)
|
||||||
|
@ -247,8 +247,8 @@ internal sealed class QuestData
|
|||||||
|
|
||||||
private void AddPreviousQuest(QuestId questToUpdate, QuestId requiredQuestId)
|
private void AddPreviousQuest(QuestId questToUpdate, QuestId requiredQuestId)
|
||||||
{
|
{
|
||||||
QuestInfo quest = (QuestInfo)_quests[questToUpdate];
|
if (_quests.TryGetValue(questToUpdate, out IQuestInfo? quest) && quest is QuestInfo questInfo)
|
||||||
quest.AddPreviousQuest(new PreviousQuestInfo(requiredQuestId));
|
questInfo.AddPreviousQuest(new PreviousQuestInfo(requiredQuestId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddGcFollowUpQuests()
|
private void AddGcFollowUpQuests()
|
||||||
@ -300,7 +300,7 @@ internal sealed class QuestData
|
|||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<QuestInfo> GetClassJobQuests(EClassJob classJob)
|
public List<QuestInfo> GetClassJobQuests(EClassJob classJob, bool includeRoleQuests = false)
|
||||||
{
|
{
|
||||||
List<uint> chapterIds = classJob switch
|
List<uint> chapterIds = classJob switch
|
||||||
{
|
{
|
||||||
@ -367,7 +367,20 @@ internal sealed class QuestData
|
|||||||
_ => throw new ArgumentOutOfRangeException(nameof(classJob)),
|
_ => throw new ArgumentOutOfRangeException(nameof(classJob)),
|
||||||
};
|
};
|
||||||
|
|
||||||
chapterIds.AddRange(classJob switch
|
if (includeRoleQuests)
|
||||||
|
{
|
||||||
|
chapterIds.AddRange(GetRoleQuestIds(classJob));
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetQuestsInNewGamePlusChapters(chapterIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<QuestInfo> GetRoleQuests(EClassJob referenceClassJob) =>
|
||||||
|
GetQuestsInNewGamePlusChapters(GetRoleQuestIds(referenceClassJob).ToList());
|
||||||
|
|
||||||
|
private static IEnumerable<uint> GetRoleQuestIds(EClassJob classJob)
|
||||||
|
{
|
||||||
|
return classJob switch
|
||||||
{
|
{
|
||||||
_ when classJob.IsTank() => TankRoleQuests,
|
_ when classJob.IsTank() => TankRoleQuests,
|
||||||
_ when classJob.IsHealer() => HealerRoleQuests,
|
_ when classJob.IsHealer() => HealerRoleQuests,
|
||||||
@ -375,9 +388,7 @@ internal sealed class QuestData
|
|||||||
_ when classJob.IsPhysicalRanged() => PhysicalRangedRoleQuests,
|
_ when classJob.IsPhysicalRanged() => PhysicalRangedRoleQuests,
|
||||||
_ when classJob.IsCaster() && classJob != EClassJob.BlueMage => CasterRoleQuests,
|
_ when classJob.IsCaster() && classJob != EClassJob.BlueMage => CasterRoleQuests,
|
||||||
_ => []
|
_ => []
|
||||||
});
|
};
|
||||||
|
|
||||||
return GetQuestsInNewGamePlusChapters(chapterIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<QuestInfo> GetQuestsInNewGamePlusChapters(List<uint> chapterIds)
|
private List<QuestInfo> GetQuestsInNewGamePlusChapters(List<uint> chapterIds)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@ -7,6 +8,7 @@ using Dalamud.Game;
|
|||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using Lumina.Excel.Sheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
using Questionable.Model.Questing;
|
||||||
|
|
||||||
namespace Questionable.Data;
|
namespace Questionable.Data;
|
||||||
|
|
||||||
@ -17,6 +19,7 @@ internal sealed class TerritoryData
|
|||||||
private readonly ImmutableDictionary<ushort, uint> _dutyTerritories;
|
private readonly ImmutableDictionary<ushort, uint> _dutyTerritories;
|
||||||
private readonly ImmutableDictionary<uint, string> _instanceNames;
|
private readonly ImmutableDictionary<uint, string> _instanceNames;
|
||||||
private readonly ImmutableDictionary<uint, ContentFinderConditionData> _contentFinderConditions;
|
private readonly ImmutableDictionary<uint, ContentFinderConditionData> _contentFinderConditions;
|
||||||
|
private readonly ImmutableDictionary<(ElementId QuestId, byte Index), uint> _questsToCfc;
|
||||||
|
|
||||||
public TerritoryData(IDataManager dataManager)
|
public TerritoryData(IDataManager dataManager)
|
||||||
{
|
{
|
||||||
@ -45,9 +48,16 @@ internal sealed class TerritoryData
|
|||||||
.ToImmutableDictionary(x => x.Content.RowId, x => x.Name.ToDalamudString().ToString());
|
.ToImmutableDictionary(x => x.Content.RowId, x => x.Name.ToDalamudString().ToString());
|
||||||
|
|
||||||
_contentFinderConditions = dataManager.GetExcelSheet<ContentFinderCondition>()
|
_contentFinderConditions = dataManager.GetExcelSheet<ContentFinderCondition>()
|
||||||
.Where(x => x.RowId > 0 && x.Content.RowId != 0 && x.ContentLinkType == 1 && x.ContentType.RowId != 6)
|
.Where(x => x.RowId > 0 && x.Content.RowId != 0 && x.ContentLinkType is 1 or 5 && x.ContentType.RowId != 6)
|
||||||
.Select(x => new ContentFinderConditionData(x, dataManager.Language))
|
.Select(x => new ContentFinderConditionData(x, dataManager.Language))
|
||||||
.ToImmutableDictionary(x => x.ContentFinderConditionId, x => x);
|
.ToImmutableDictionary(x => x.ContentFinderConditionId, x => x);
|
||||||
|
|
||||||
|
_questsToCfc = dataManager.GetExcelSheet<Quest>()
|
||||||
|
.Where(x => x is { RowId: > 0, IssuerLocation.RowId: > 0 })
|
||||||
|
.SelectMany(GetQuestBattles)
|
||||||
|
.Select(x => (x.QuestId, x.Index,
|
||||||
|
CfcId: LookupContentFinderConditionForQuestBattle(dataManager, x.QuestBattleId)))
|
||||||
|
.ToImmutableDictionary(x => (x.QuestId, x.Index), x => x.CfcId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? GetName(ushort territoryId) => _territoryNames.GetValueOrDefault(territoryId);
|
public string? GetName(ushort territoryId) => _territoryNames.GetValueOrDefault(territoryId);
|
||||||
@ -77,6 +87,23 @@ internal sealed class TerritoryData
|
|||||||
[NotNullWhen(true)] out ContentFinderConditionData? contentFinderConditionData) =>
|
[NotNullWhen(true)] out ContentFinderConditionData? contentFinderConditionData) =>
|
||||||
_contentFinderConditions.TryGetValue(cfcId, out contentFinderConditionData);
|
_contentFinderConditions.TryGetValue(cfcId, out contentFinderConditionData);
|
||||||
|
|
||||||
|
public bool TryGetContentFinderConditionForSoloInstance(ElementId questId, byte index,
|
||||||
|
[NotNullWhen(true)] out ContentFinderConditionData? contentFinderConditionData)
|
||||||
|
{
|
||||||
|
if (_questsToCfc.TryGetValue((questId, index), out uint cfcId))
|
||||||
|
return _contentFinderConditions.TryGetValue(cfcId, out contentFinderConditionData);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contentFinderConditionData = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(ElementId QuestId, byte Index, ContentFinderConditionData Data)> GetAllQuestsWithQuestBattles()
|
||||||
|
{
|
||||||
|
return _questsToCfc.Select(x => (x.Key.QuestId, x.Key.Index, _contentFinderConditions[x.Value]));
|
||||||
|
}
|
||||||
|
|
||||||
private static string FixName(string name, ClientLanguage language)
|
private static string FixName(string name, ClientLanguage language)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(name) || language != ClientLanguage.English)
|
if (string.IsNullOrEmpty(name) || language != ClientLanguage.English)
|
||||||
@ -85,6 +112,27 @@ internal sealed class TerritoryData
|
|||||||
return string.Concat(name[0].ToString().ToUpper(CultureInfo.InvariantCulture), name.AsSpan(1));
|
return string.Concat(name[0].ToString().ToUpper(CultureInfo.InvariantCulture), name.AsSpan(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<(ElementId QuestId, byte Index, uint QuestBattleId)> GetQuestBattles(Quest quest)
|
||||||
|
{
|
||||||
|
foreach (Quest.QuestParamsStruct t in quest.QuestParams)
|
||||||
|
{
|
||||||
|
if (t.ScriptInstruction == "QUESTBATTLE0")
|
||||||
|
yield return (QuestId.FromRowId(quest.RowId), 0, t.ScriptArg);
|
||||||
|
else if (t.ScriptInstruction == "QUESTBATTLE1")
|
||||||
|
yield return (QuestId.FromRowId(quest.RowId), 1, t.ScriptArg);
|
||||||
|
else if (t.ScriptInstruction.IsEmpty)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint LookupContentFinderConditionForQuestBattle(IDataManager dataManager, uint questBattleId)
|
||||||
|
{
|
||||||
|
if (questBattleId >= 5000)
|
||||||
|
return dataManager.GetExcelSheet<InstanceContent>().GetRow(questBattleId).Order;
|
||||||
|
else
|
||||||
|
return dataManager.GetExcelSheet<QuestBattleResident>().GetRow(questBattleId).Unknown0;
|
||||||
|
}
|
||||||
|
|
||||||
public sealed record ContentFinderConditionData(
|
public sealed record ContentFinderConditionData(
|
||||||
uint ContentFinderConditionId,
|
uint ContentFinderConditionId,
|
||||||
string Name,
|
string Name,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user