Merge branch 'gathering'

sb-p1
Liza 2024-08-03 17:27:06 +02:00
commit 2a39d053ba
Signed by: liza
GPG Key ID: 7199F8D727D55F67
226 changed files with 7238 additions and 2010 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "LLib"]
path = LLib
url = https://git.carvel.li/liza/LLib.git
[submodule "vendor/ECommons"]
path = vendor/ECommons
url = https://github.com/NightmareXIV/ECommons.git

View File

@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.Command;
using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets;
using Questionable.Model;
using Questionable.Model.Gathering;
namespace GatheringPathRenderer;
internal sealed class EditorCommands : IDisposable
{
private readonly RendererPlugin _plugin;
private readonly IDataManager _dataManager;
private readonly ICommandManager _commandManager;
private readonly ITargetManager _targetManager;
private readonly IClientState _clientState;
private readonly IChatGui _chatGui;
public EditorCommands(RendererPlugin plugin, IDataManager dataManager, ICommandManager commandManager,
ITargetManager targetManager, IClientState clientState, IChatGui chatGui)
{
_plugin = plugin;
_dataManager = dataManager;
_commandManager = commandManager;
_targetManager = targetManager;
_clientState = clientState;
_chatGui = chatGui;
_commandManager.AddHandler("/qg", new CommandInfo(ProcessCommand));
}
private void ProcessCommand(string command, string argument)
{
string[] parts = argument.Split(' ');
string subCommand = parts[0];
List<string> arguments = parts.Skip(1).ToList();
try
{
switch (subCommand)
{
case "add":
CreateOrAddLocationToGroup(arguments);
break;
}
}
catch (Exception e)
{
_chatGui.PrintError(e.ToString(), "qG");
}
}
private void CreateOrAddLocationToGroup(List<string> arguments)
{
var target = _targetManager.Target;
if (target == null || target.ObjectKind != ObjectKind.GatheringPoint)
throw new Exception("No valid target");
var gatheringPoint = _dataManager.GetExcelSheet<GatheringPoint>()!.GetRow(target.DataId);
if (gatheringPoint == null)
throw new Exception("Invalid gathering point");
FileInfo targetFile;
GatheringRoot root;
var locationsInTerritory = _plugin.GetLocationsInTerritory(_clientState.TerritoryType).ToList();
var location = locationsInTerritory.SingleOrDefault(x => x.Id == gatheringPoint.GatheringPointBase.Row);
if (location != null)
{
targetFile = location.File;
root = location.Root;
// if this is an existing node, ignore it
var existingNode = root.Groups.SelectMany(x => x.Nodes.Where(y => y.DataId == target.DataId))
.Any(x => x.Locations.Any(y => Vector3.Distance(y.Position, target.Position) < 0.1f));
if (existingNode)
throw new Exception("Node already exists");
if (arguments.Contains("group"))
AddToNewGroup(root, target);
else
AddToExistingGroup(root, target);
}
else
{
(targetFile, root) = CreateNewFile(gatheringPoint, target);
_chatGui.Print($"Creating new file under {targetFile.FullName}", "qG");
}
_plugin.Save(targetFile, root);
}
public void AddToNewGroup(GatheringRoot root, IGameObject target)
{
root.Groups.Add(new GatheringNodeGroup
{
Nodes =
[
new GatheringNode
{
DataId = target.DataId,
Locations =
[
new GatheringLocation
{
Position = target.Position,
}
]
}
]
});
_chatGui.Print("Added group.", "qG");
}
public void AddToExistingGroup(GatheringRoot root, IGameObject target)
{
// find the same data id
var node = root.Groups.SelectMany(x => x.Nodes)
.SingleOrDefault(x => x.DataId == target.DataId);
if (node != null)
{
node.Locations.Add(new GatheringLocation
{
Position = target.Position,
});
_chatGui.Print($"Added location to existing node {target.DataId}.", "qG");
}
else
{
// find the closest group
var closestGroup = root.Groups
.Select(group => new
{
Group = group,
Distance = group.Nodes.Min(x =>
x.Locations.Min(y =>
Vector3.Distance(_clientState.LocalPlayer!.Position, y.Position)))
})
.OrderBy(x => x.Distance)
.First();
closestGroup.Group.Nodes.Add(new GatheringNode
{
DataId = target.DataId,
Locations =
[
new GatheringLocation
{
Position = target.Position,
}
]
});
_chatGui.Print($"Added new node {target.DataId}.", "qG");
}
}
public (FileInfo targetFile, GatheringRoot root) CreateNewFile(GatheringPoint gatheringPoint, IGameObject target)
{
// determine target folder
DirectoryInfo? targetFolder = _plugin.GetLocationsInTerritory(_clientState.TerritoryType).FirstOrDefault()
?.File.Directory;
if (targetFolder == null)
{
var territoryInfo = _dataManager.GetExcelSheet<TerritoryType>()!.GetRow(_clientState.TerritoryType)!;
targetFolder = _plugin.PathsDirectory
.CreateSubdirectory(ExpansionData.ExpansionFolders[(byte)territoryInfo.ExVersion.Row])
.CreateSubdirectory(territoryInfo.PlaceName.Value!.Name.ToString());
}
FileInfo targetFile =
new FileInfo(
Path.Combine(targetFolder.FullName,
$"{gatheringPoint.GatheringPointBase.Row}_{gatheringPoint.PlaceName.Value!.Name}_{(_clientState.LocalPlayer!.ClassJob.Id == 16 ? "MIN" : "BTN")}.json"));
var root = new GatheringRoot
{
TerritoryId = _clientState.TerritoryType,
Groups =
[
new GatheringNodeGroup
{
Nodes =
[
new GatheringNode
{
DataId = target.DataId,
Locations =
[
new GatheringLocation
{
Position = target.Position
}
]
}
]
}
]
};
return (targetFile, root);
}
public void Dispose()
{
_commandManager.RemoveHandler("/qg");
}
}

View File

@ -0,0 +1,8 @@
<Project Sdk="Dalamud.NET.Sdk/10.0.0">
<ItemGroup>
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj" />
<ProjectReference Include="..\vendor\ECommons\ECommons\ECommons.csproj" />
</ItemGroup>
<Import Project="..\LLib\LLib.targets"/>
</Project>

View File

@ -0,0 +1,6 @@
{
"Name": "GatheringPathRenderer",
"Author": "Liza Carvelli",
"Punchline": "dev only plugin: Renders gathering location.",
"Description": "dev only plugin: Renders gathering location (without ECommons polluting the entire normal project)."
}

View File

@ -0,0 +1,290 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ECommons;
using ECommons.Schedulers;
using ECommons.SplatoonAPI;
using FFXIVClientStructs.FFXIV.Common.Math;
using GatheringPathRenderer.Windows;
using Questionable.Model;
using Questionable.Model.Gathering;
namespace GatheringPathRenderer;
public sealed class RendererPlugin : IDalamudPlugin
{
private const long OnTerritoryChange = -2;
private readonly WindowSystem _windowSystem = new(nameof(RendererPlugin));
private readonly List<uint> _colors = [0xFFFF2020, 0xFF20FF20, 0xFF2020FF, 0xFFFFFF20, 0xFFFF20FF, 0xFF20FFFF];
private readonly IDalamudPluginInterface _pluginInterface;
private readonly IClientState _clientState;
private readonly IPluginLog _pluginLog;
private readonly EditorCommands _editorCommands;
private readonly EditorWindow _editorWindow;
private readonly List<GatheringLocationContext> _gatheringLocations = [];
public RendererPlugin(IDalamudPluginInterface pluginInterface, IClientState clientState,
ICommandManager commandManager, IDataManager dataManager, ITargetManager targetManager, IChatGui chatGui,
IObjectTable objectTable, IPluginLog pluginLog)
{
_pluginInterface = pluginInterface;
_clientState = clientState;
_pluginLog = pluginLog;
_editorCommands = new EditorCommands(this, dataManager, commandManager, targetManager, clientState, chatGui);
_editorWindow = new EditorWindow(this, _editorCommands, dataManager, targetManager, clientState, objectTable)
{ IsOpen = true };
_windowSystem.AddWindow(_editorWindow);
_pluginInterface.GetIpcSubscriber<object>("Questionable.ReloadData")
.Subscribe(Reload);
ECommonsMain.Init(pluginInterface, this, Module.SplatoonAPI);
LoadGatheringLocationsFromDirectory();
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
_clientState.TerritoryChanged += TerritoryChanged;
if (_clientState.IsLoggedIn)
TerritoryChanged(_clientState.TerritoryType);
}
internal DirectoryInfo PathsDirectory
{
get
{
DirectoryInfo? solutionDirectory = _pluginInterface.AssemblyLocation.Directory?.Parent?.Parent?.Parent;
if (solutionDirectory != null)
{
DirectoryInfo pathProjectDirectory =
new DirectoryInfo(Path.Combine(solutionDirectory.FullName, "GatheringPaths"));
if (pathProjectDirectory.Exists)
return pathProjectDirectory;
}
throw new Exception("Unable to resolve project path");
}
}
internal void Reload()
{
LoadGatheringLocationsFromDirectory();
Redraw();
}
private void LoadGatheringLocationsFromDirectory()
{
_gatheringLocations.Clear();
try
{
foreach (var expansionFolder in ExpansionData.ExpansionFolders.Values)
LoadFromDirectory(
new DirectoryInfo(Path.Combine(PathsDirectory.FullName, expansionFolder)));
_pluginLog.Information(
$"Loaded {_gatheringLocations.Count} gathering root locations from project directory");
}
catch (Exception e)
{
_pluginLog.Error(e, "Failed to load paths from project directory");
}
}
private void LoadFromDirectory(DirectoryInfo directory)
{
if (!directory.Exists)
return;
_pluginLog.Information($"Loading locations from {directory}");
foreach (FileInfo fileInfo in directory.GetFiles("*.json"))
{
try
{
using FileStream stream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);
LoadLocationFromStream(fileInfo, stream);
}
catch (Exception e)
{
throw new InvalidDataException($"Unable to load file {fileInfo.FullName}", e);
}
}
foreach (DirectoryInfo childDirectory in directory.GetDirectories())
LoadFromDirectory(childDirectory);
}
private void LoadLocationFromStream(FileInfo fileInfo, Stream stream)
{
var locationNode = JsonNode.Parse(stream)!;
GatheringRoot root = locationNode.Deserialize<GatheringRoot>()!;
_gatheringLocations.Add(new GatheringLocationContext(fileInfo, ushort.Parse(fileInfo.Name.Split('_')[0]),
root));
}
internal IEnumerable<GatheringLocationContext> GetLocationsInTerritory(ushort territoryId)
=> _gatheringLocations.Where(x => x.Root.TerritoryId == territoryId);
internal void Save(FileInfo targetFile, GatheringRoot root)
{
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
WriteIndented = true,
};
using (var stream = File.Create(targetFile.FullName))
{
var jsonNode = (JsonObject)JsonSerializer.SerializeToNode(root, options)!;
var newNode = new JsonObject();
newNode.Add("$schema",
"https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json");
foreach (var (key, value) in jsonNode)
newNode.Add(key, value?.DeepClone());
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Indented = true
});
newNode.WriteTo(writer, options);
}
Reload();
}
private void TerritoryChanged(ushort territoryId) => Redraw();
internal void Redraw()
{
Splatoon.RemoveDynamicElements("GatheringPathRenderer");
var elements = GetLocationsInTerritory(_clientState.TerritoryType)
.SelectMany(location =>
location.Root.Groups.SelectMany(group =>
group.Nodes.SelectMany(node => node.Locations
.SelectMany(x =>
{
bool isCone = false;
int minimumAngle = 0;
int maximumAngle = 0;
if (_editorWindow.TryGetOverride(x.InternalId, out LocationOverride? locationOverride) &&
locationOverride != null)
{
if (locationOverride.IsCone())
{
isCone = true;
minimumAngle = locationOverride.MinimumAngle.GetValueOrDefault();
maximumAngle = locationOverride.MaximumAngle.GetValueOrDefault();
}
}
if (!isCone && x.IsCone())
{
isCone = true;
minimumAngle = x.MinimumAngle.GetValueOrDefault();
maximumAngle = x.MaximumAngle.GetValueOrDefault();
}
var a = GatheringMath.CalculateLandingLocation(x, 0, 0);
var b = GatheringMath.CalculateLandingLocation(x, 1, 1);
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 = x.CalculateMinimumDistance(),
Donut = x.CalculateMaximumDistance() - 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 = 0x00000000,
Enabled = true,
overlayText =
$"{location.Root.Groups.IndexOf(group)} // {node.DataId} / {node.Locations.IndexOf(x)}",
},
new Element(ElementType.CircleAtFixedCoordinates)
{
refX = a.X,
refY = a.Z,
refZ = a.Y,
color = _colors[0],
radius = 0.1f,
Enabled = true,
overlayText = "Min Angle"
},
new Element(ElementType.CircleAtFixedCoordinates)
{
refX = b.X,
refY = b.Z,
refZ = b.Y,
color = _colors[1],
radius = 0.1f,
Enabled = true,
overlayText = "Max Angle"
}
};
}))))
.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()
{
_clientState.TerritoryChanged -= TerritoryChanged;
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
Splatoon.RemoveDynamicElements("GatheringPathRenderer");
ECommonsMain.Dispose();
_pluginInterface.GetIpcSubscriber<object>("Questionable.ReloadData")
.Unsubscribe(Reload);
_editorCommands.Dispose();
}
internal sealed record GatheringLocationContext(FileInfo File, ushort Id, GatheringRoot Root);
}

View File

@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin.Services;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Questionable.Model.Gathering;
namespace GatheringPathRenderer.Windows;
internal sealed class EditorWindow : Window
{
private readonly RendererPlugin _plugin;
private readonly EditorCommands _editorCommands;
private readonly IDataManager _dataManager;
private readonly ITargetManager _targetManager;
private readonly IClientState _clientState;
private readonly IObjectTable _objectTable;
private readonly Dictionary<Guid, LocationOverride> _changes = [];
private IGameObject? _target;
private (RendererPlugin.GatheringLocationContext Context, GatheringNode Node, GatheringLocation Location)?
_targetLocation;
public EditorWindow(RendererPlugin plugin, EditorCommands editorCommands, IDataManager dataManager,
ITargetManager targetManager, IClientState clientState, IObjectTable objectTable)
: base("Gathering Path Editor###QuestionableGatheringPathEditor")
{
_plugin = plugin;
_editorCommands = editorCommands;
_dataManager = dataManager;
_targetManager = targetManager;
_clientState = clientState;
_objectTable = objectTable;
SizeConstraints = new WindowSizeConstraints
{
MinimumSize = new Vector2(300, 300),
};
ShowCloseButton = false;
}
public override void Update()
{
_target = _targetManager.Target;
var gatheringLocations = _plugin.GetLocationsInTerritory(_clientState.TerritoryType);
var location = gatheringLocations.SelectMany(context =>
context.Root.Groups.SelectMany(group =>
group.Nodes
.SelectMany(node => node.Locations
.Where(location =>
{
if (_target != null)
return Vector3.Distance(location.Position, _target.Position) < 0.1f;
else
return Vector3.Distance(location.Position, _clientState.LocalPlayer!.Position) < 3f;
})
.Select(location => new { Context = context, Node = node, Location = location }))))
.FirstOrDefault();
if (_target != null && _target.ObjectKind != ObjectKind.GatheringPoint)
{
_target = null;
_targetLocation = null;
return;
}
if (location == null)
{
_targetLocation = null;
return;
}
_target ??= _objectTable.FirstOrDefault(
x => x.ObjectKind == ObjectKind.GatheringPoint &&
x.DataId == location.Node.DataId &&
Vector3.Distance(location.Location.Position, _clientState.LocalPlayer!.Position) < 3f);
_targetLocation = (location.Context, location.Node, location.Location);
}
public override bool DrawConditions()
{
return _target != null || _targetLocation != null;
}
public override void Draw()
{
if (_target != null && _targetLocation != null)
{
var context = _targetLocation.Value.Context;
var node = _targetLocation.Value.Node;
var location = _targetLocation.Value.Location;
ImGui.Text(context.File.Directory?.Name ?? string.Empty);
ImGui.Indent();
ImGui.Text(context.File.Name);
ImGui.Unindent();
ImGui.Text($"{_target.DataId} // {location.InternalId}");
ImGui.Text(string.Create(CultureInfo.InvariantCulture, $"{location.Position:G}"));
if (!_changes.TryGetValue(location.InternalId, out LocationOverride? locationOverride))
{
locationOverride = new LocationOverride();
_changes[location.InternalId] = locationOverride;
}
int minAngle = locationOverride.MinimumAngle ?? location.MinimumAngle.GetValueOrDefault();
if (ImGui.DragInt("Min Angle", ref minAngle, 5, -360, 360))
{
locationOverride.MinimumAngle = minAngle;
locationOverride.MaximumAngle ??= location.MaximumAngle.GetValueOrDefault();
_plugin.Redraw();
}
int maxAngle = locationOverride.MaximumAngle ?? location.MaximumAngle.GetValueOrDefault();
if (ImGui.DragInt("Max Angle", ref maxAngle, 5, -360, 360))
{
locationOverride.MinimumAngle ??= location.MinimumAngle.GetValueOrDefault();
locationOverride.MaximumAngle = maxAngle;
_plugin.Redraw();
}
bool unsaved = locationOverride is { MinimumAngle: not null, MaximumAngle: not null };
ImGui.BeginDisabled(!unsaved);
if (unsaved)
ImGui.PushStyleColor(ImGuiCol.Button, ImGuiColors.DalamudRed);
if (ImGui.Button("Save"))
{
location.MinimumAngle = locationOverride.MinimumAngle;
location.MaximumAngle = locationOverride.MaximumAngle;
_plugin.Save(context.File, context.Root);
}
if (unsaved)
ImGui.PopStyleColor();
ImGui.SameLine();
if (ImGui.Button("Reset"))
{
_changes[location.InternalId] = new LocationOverride();
_plugin.Redraw();
}
ImGui.EndDisabled();
List<IGameObject> nodesInObjectTable = _objectTable
.Where(x => x.ObjectKind == ObjectKind.GatheringPoint && x.DataId == _target.DataId)
.ToList();
List<IGameObject> missingLocations = nodesInObjectTable
.Where(x => !node.Locations.Any(y => Vector3.Distance(x.Position, y.Position) < 0.1f))
.ToList();
if (missingLocations.Count > 0)
{
if (ImGui.Button("Add missing locations"))
{
foreach (var missing in missingLocations)
_editorCommands.AddToExistingGroup(context.Root, missing);
_plugin.Save(context.File, context.Root);
}
}
}
else if (_target != null)
{
var gatheringPoint = _dataManager.GetExcelSheet<GatheringPoint>()!.GetRow(_target.DataId);
if (gatheringPoint == null)
return;
var locationsInTerritory = _plugin.GetLocationsInTerritory(_clientState.TerritoryType).ToList();
var location = locationsInTerritory.SingleOrDefault(x => x.Id == gatheringPoint.GatheringPointBase.Row);
if (location != null)
{
var targetFile = location.File;
var root = location.Root;
if (ImGui.Button("Add to closest group"))
{
_editorCommands.AddToExistingGroup(root, _target);
_plugin.Save(targetFile, root);
}
ImGui.BeginDisabled(root.Groups.Any(group => group.Nodes.Any(node => node.DataId == _target.DataId)));
ImGui.SameLine();
if (ImGui.Button("Add as new group"))
{
_editorCommands.AddToNewGroup(root, _target);
_plugin.Save(targetFile, root);
}
ImGui.EndDisabled();
}
else
{
if (ImGui.Button("Create location"))
{
var (targetFile, root) = _editorCommands.CreateNewFile(gatheringPoint, _target);
_plugin.Save(targetFile, root);
}
}
}
}
public bool TryGetOverride(Guid internalId, out LocationOverride? locationOverride)
=> _changes.TryGetValue(internalId, out locationOverride);
}
internal sealed class LocationOverride
{
public int? MinimumAngle { get; set; }
public int? MaximumAngle { get; set; }
public float? MinimumDistance { get; set; }
public float? MaximumDistance { get; set; }
public bool IsCone()
{
return MinimumAngle != null && MaximumAngle != null && MinimumAngle != MaximumAngle;
}
}

View File

@ -0,0 +1,109 @@
{
"version": 1,
"dependencies": {
"net8.0-windows7.0": {
"DalamudPackager": {
"type": "Direct",
"requested": "[2.1.13, )",
"resolved": "2.1.13",
"contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ=="
},
"DotNet.ReproducibleBuilds": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "+H2t/t34h6mhEoUvHi8yGXyuZ2GjSovcGYehJrS2MDm2XgmPfZL2Sdxg+uL2lKgZ4M6tTwKHIlxOob2bgh0NRQ==",
"dependencies": {
"Microsoft.SourceLink.AzureRepos.Git": "1.1.1",
"Microsoft.SourceLink.Bitbucket.Git": "1.1.1",
"Microsoft.SourceLink.GitHub": "1.1.1",
"Microsoft.SourceLink.GitLab": "1.1.1"
}
},
"Microsoft.SourceLink.Gitea": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "KOBodmDnlWGIqZt2hT47Q69TIoGhIApDVLCyyj9TT5ct8ju16AbHYcB4XeknoHX562wO1pMS/1DfBIZK+V+sxg==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.SourceLink.AzureRepos.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "qB5urvw9LO2bG3eVAkuL+2ughxz2rR7aYgm2iyrB8Rlk9cp2ndvGRCvehk3rNIhRuNtQaeKwctOl1KvWiklv5w==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Bitbucket.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "cDzxXwlyWpLWaH0em4Idj0H3AmVo3L/6xRXKssYemx+7W52iNskj/SQ4FOmfCb8YQt39otTDNMveCZzYtMoucQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.GitLab": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "tvsg47DDLqqedlPeYVE2lmiTpND8F0hkrealQ5hYltSmvruy/Gr5nHAKSsjyw5L3NeM/HLMI5ORv7on/M4qyZw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"System.Text.Encodings.Web": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
},
"System.Text.Json": {
"type": "Transitive",
"resolved": "8.0.4",
"contentHash": "bAkhgDJ88XTsqczoxEMliSrpijKZHhbJQldhAmObj/RbrN3sU5dcokuXmWJWsdQAhiMJ9bTayWsL1C9fbbCRhw==",
"dependencies": {
"System.Text.Encodings.Web": "8.0.0"
}
},
"ecommons": {
"type": "Project"
},
"gatheringpaths": {
"type": "Project",
"dependencies": {
"Questionable.Model": "[1.0.0, )"
}
},
"questionable.model": {
"type": "Project",
"dependencies": {
"System.Text.Json": "[8.0.4, )"
}
}
}
}
}

View File

View File

@ -0,0 +1,158 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": [],
"TerritoryId": 958,
"AetheryteShortcut": "Garlemald - Camp Broken Glass",
"Groups": [
{
"Nodes": [
{
"DataId": 33932,
"Locations": [
{
"Position": {
"X": -80.95969,
"Y": -9.810837,
"Z": 462.2579
},
"MinimumAngle": 130,
"MaximumAngle": 260
}
]
},
{
"DataId": 33933,
"Locations": [
{
"Position": {
"X": -72.11935,
"Y": -10.90324,
"Z": 471.2258
},
"MinimumAngle": 105,
"MaximumAngle": 250
},
{
"Position": {
"X": -98.97565,
"Y": -5.664787,
"Z": 463.9966
},
"MinimumAngle": 60,
"MaximumAngle": 230
},
{
"Position": {
"X": -63.49503,
"Y": -11.21235,
"Z": 469.3839
},
"MinimumAngle": 80,
"MaximumAngle": 255
}
]
}
]
},
{
"Nodes": [
{
"DataId": 33931,
"Locations": [
{
"Position": {
"X": -61.34306,
"Y": 6.11244,
"Z": 318.3409
},
"MinimumAngle": -120,
"MaximumAngle": 70
},
{
"Position": {
"X": -61.47854,
"Y": 6.076105,
"Z": 281.4938
},
"MinimumAngle": 65,
"MaximumAngle": 240
},
{
"Position": {
"X": -73.25829,
"Y": 6.108262,
"Z": 302.9926
},
"MinimumAngle": 50,
"MaximumAngle": 220
}
]
},
{
"DataId": 33930,
"Locations": [
{
"Position": {
"X": -51.28564,
"Y": 6.088318,
"Z": 318.0529
},
"MinimumAngle": -65,
"MaximumAngle": 110
}
]
}
]
},
{
"Nodes": [
{
"DataId": 33935,
"Locations": [
{
"Position": {
"X": 72.58704,
"Y": -11.59895,
"Z": 354.757
},
"MinimumAngle": 75,
"MaximumAngle": 235
},
{
"Position": {
"X": 65.33016,
"Y": -11.61111,
"Z": 358.7321
},
"MinimumAngle": 65,
"MaximumAngle": 235
},
{
"Position": {
"X": 68.21196,
"Y": -11.81954,
"Z": 366.5172
},
"MinimumAngle": 5,
"MaximumAngle": 85
}
]
},
{
"DataId": 33934,
"Locations": [
{
"Position": {
"X": 81.30492,
"Y": -11.53227,
"Z": 347.9922
},
"MinimumAngle": 50,
"MaximumAngle": 215
}
]
}
]
}
]
}

View File

@ -0,0 +1,157 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": [],
"TerritoryId": 959,
"Groups": [
{
"Nodes": [
{
"DataId": 33929,
"Locations": [
{
"Position": {
"X": 304.4121,
"Y": 118.8077,
"Z": 673.4494
},
"MinimumAngle": 50,
"MaximumAngle": 230
},
{
"Position": {
"X": 297.7666,
"Y": 119.4976,
"Z": 679.5604
},
"MinimumAngle": 50,
"MaximumAngle": 220
},
{
"Position": {
"X": 322.163,
"Y": 119.0883,
"Z": 657.4384
},
"MinimumAngle": 55,
"MaximumAngle": 235
}
]
},
{
"DataId": 33928,
"Locations": [
{
"Position": {
"X": 313.72,
"Y": 118.3442,
"Z": 664.8668
},
"MinimumAngle": 60,
"MaximumAngle": 230
}
]
}
]
},
{
"Nodes": [
{
"DataId": 33927,
"Locations": [
{
"Position": {
"X": 394.3838,
"Y": 144.7951,
"Z": 820.7851
},
"MinimumAngle": 75,
"MaximumAngle": 250
},
{
"Position": {
"X": 421.0549,
"Y": 143.6111,
"Z": 805.9457
},
"MinimumAngle": 60,
"MaximumAngle": 225
},
{
"Position": {
"X": 414.2961,
"Y": 143.2405,
"Z": 811.3884
},
"MinimumAngle": 65,
"MaximumAngle": 230
}
]
},
{
"DataId": 33926,
"Locations": [
{
"Position": {
"X": 405.2481,
"Y": 143.6621,
"Z": 816.6496
},
"MinimumAngle": 75,
"MaximumAngle": 230
}
]
}
]
},
{
"Nodes": [
{
"DataId": 33925,
"Locations": [
{
"Position": {
"X": 474.679,
"Y": 143.4776,
"Z": 698.5961
},
"MinimumAngle": 20,
"MaximumAngle": 170
},
{
"Position": {
"X": 474.8585,
"Y": 144.2588,
"Z": 685.7468
},
"MinimumAngle": 0,
"MaximumAngle": 155
},
{
"Position": {
"X": 467.506,
"Y": 144.9235,
"Z": 654.2
},
"MinimumAngle": 0,
"MaximumAngle": 150
}
]
},
{
"DataId": 33924,
"Locations": [
{
"Position": {
"X": 470.7754,
"Y": 144.8793,
"Z": 672.114
},
"MinimumAngle": -5,
"MaximumAngle": 165
}
]
}
]
}
]
}

View File

@ -0,0 +1,159 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 957,
"AetheryteShortcut": "Thavnair - Great Work",
"Groups": [
{
"Nodes": [
{
"DataId": 33918,
"Locations": [
{
"Position": {
"X": -582.5132,
"Y": 40.54578,
"Z": -426.0171
},
"MinimumAngle": -50,
"MaximumAngle": 90
}
]
},
{
"DataId": 33919,
"Locations": [
{
"Position": {
"X": -578.2101,
"Y": 41.27147,
"Z": -447.6376
},
"MinimumAngle": 130,
"MaximumAngle": 220
},
{
"Position": {
"X": -546.2882,
"Y": 44.52267,
"Z": -435.8184
},
"MinimumAngle": 200,
"MaximumAngle": 360
},
{
"Position": {
"X": -606.7445,
"Y": 38.37634,
"Z": -425.5284
},
"MinimumAngle": -80,
"MaximumAngle": 70
}
]
}
]
},
{
"Nodes": [
{
"DataId": 33920,
"Locations": [
{
"Position": {
"X": -488.2276,
"Y": 34.71221,
"Z": -359.6945
},
"MinimumAngle": 20,
"MaximumAngle": 128,
"MinimumDistance": 1.3
}
]
},
{
"DataId": 33921,
"Locations": [
{
"Position": {
"X": -498.8687,
"Y": 31.08014,
"Z": -351.9397
},
"MinimumAngle": 40,
"MaximumAngle": 190
},
{
"Position": {
"X": -490.7759,
"Y": 28.70215,
"Z": -344.4114
},
"MinimumAngle": -110,
"MaximumAngle": 60
},
{
"Position": {
"X": -494.1286,
"Y": 32.89971,
"Z": -355.0208
},
"MinimumAngle": 80,
"MaximumAngle": 230
}
]
}
]
},
{
"Nodes": [
{
"DataId": 33922,
"Locations": [
{
"Position": {
"X": -304.0609,
"Y": 68.76999,
"Z": -479.1875
},
"MinimumAngle": -110,
"MaximumAngle": 70
}
]
},
{
"DataId": 33923,
"Locations": [
{
"Position": {
"X": -293.6989,
"Y": 68.77935,
"Z": -484.2256
},
"MinimumAngle": -30,
"MaximumAngle": 110
},
{
"Position": {
"X": -295.0806,
"Y": 69.12621,
"Z": -498.1898
},
"MinimumAngle": 10,
"MaximumAngle": 200
},
{
"Position": {
"X": -281.4858,
"Y": 67.64153,
"Z": -477.6673
},
"MinimumAngle": -105,
"MaximumAngle": 75
}
]
}
]
}
]
}

View File

@ -0,0 +1,158 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": [],
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Wachunpelo",
"Groups": [
{
"Nodes": [
{
"DataId": 34749,
"Locations": [
{
"Position": {
"X": -392.813,
"Y": -47.04364,
"Z": -386.862
},
"MinimumAngle": -10,
"MaximumAngle": 240
}
]
},
{
"DataId": 34750,
"Locations": [
{
"Position": {
"X": -402.8987,
"Y": -45.59287,
"Z": -390.7613
},
"MinimumAngle": 220,
"MaximumAngle": 305
},
{
"Position": {
"X": -388.9036,
"Y": -46.86702,
"Z": -381.3985
},
"MinimumAngle": -50,
"MaximumAngle": 210
},
{
"Position": {
"X": -394.2657,
"Y": -47.86026,
"Z": -394.9654
},
"MinimumAngle": -120,
"MaximumAngle": 120
}
]
}
]
},
{
"Nodes": [
{
"DataId": 34753,
"Locations": [
{
"Position": {
"X": -541.7726,
"Y": -22.952,
"Z": -517.8604
},
"MinimumAngle": 215,
"MaximumAngle": 330
}
]
},
{
"DataId": 34754,
"Locations": [
{
"Position": {
"X": -522.9433,
"Y": -25.87319,
"Z": -537.3257
},
"MinimumAngle": 225,
"MaximumAngle": 360
},
{
"Position": {
"X": -532.3487,
"Y": -22.79275,
"Z": -510.8069
},
"MinimumAngle": 135,
"MaximumAngle": 270
},
{
"Position": {
"X": -536.2922,
"Y": -23.79476,
"Z": -526.0406
},
"MinimumAngle": -110,
"MaximumAngle": 35
}
]
}
]
},
{
"Nodes": [
{
"DataId": 34751,
"Locations": [
{
"Position": {
"X": -448.8079,
"Y": -14.9586,
"Z": -658.0133
},
"MinimumAngle": -45,
"MaximumAngle": 115
}
]
},
{
"DataId": 34752,
"Locations": [
{
"Position": {
"X": -452.2813,
"Y": -12.43015,
"Z": -665.0275
},
"MinimumAngle": 0,
"MaximumAngle": 150
},
{
"Position": {
"X": -431.5875,
"Y": -16.68724,
"Z": -656.528
},
"MinimumAngle": -35,
"MaximumAngle": 90
},
{
"Position": {
"X": -439.8079,
"Y": -16.67447,
"Z": -654.6749
},
"MinimumAngle": -45,
"MaximumAngle": 85
}
]
}
]
}
]
}

View File

@ -0,0 +1,150 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": [],
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Wachunpelo",
"Groups": [
{
"Nodes": [
{
"DataId": 34857,
"Locations": [
{
"Position": {
"X": -12.48859,
"Y": -133.2091,
"Z": -427.7497
}
}
]
},
{
"DataId": 34858,
"Locations": [
{
"Position": {
"X": -22.41956,
"Y": -129.3952,
"Z": -396.6573
}
},
{
"Position": {
"X": -16.08351,
"Y": -137.6674,
"Z": -464.35
},
"MinimumAngle": -65,
"MaximumAngle": 145
},
{
"Position": {
"X": -9.000858,
"Y": -134.9256,
"Z": -439.0332
},
"MinimumAngle": -125,
"MaximumAngle": 105
}
]
}
]
},
{
"Nodes": [
{
"DataId": 34861,
"Locations": [
{
"Position": {
"X": -234.8222,
"Y": -99.01237,
"Z": -376.7287
},
"MinimumAngle": -180,
"MaximumAngle": 40
}
]
},
{
"DataId": 34862,
"Locations": [
{
"Position": {
"X": -236.0182,
"Y": -97.50027,
"Z": -372.1523
},
"MinimumAngle": -180,
"MaximumAngle": 45
},
{
"Position": {
"X": -249.7221,
"Y": -96.55618,
"Z": -386.2397
},
"MinimumAngle": 35,
"MaximumAngle": 280
},
{
"Position": {
"X": -241.8424,
"Y": -99.37369,
"Z": -386.2889
},
"MinimumAngle": -300,
"MaximumAngle": -45
}
]
}
]
},
{
"Nodes": [
{
"DataId": 34860,
"Locations": [
{
"Position": {
"X": -169.8177,
"Y": -85.61841,
"Z": -240.1007
}
},
{
"Position": {
"X": -116.6446,
"Y": -93.99508,
"Z": -274.6102
},
"MinimumAngle": -140,
"MaximumAngle": 150
},
{
"Position": {
"X": -133.936,
"Y": -91.54122,
"Z": -273.3963
},
"MinimumAngle": -155,
"MaximumAngle": 85
}
]
},
{
"DataId": 34859,
"Locations": [
{
"Position": {
"X": -131.9198,
"Y": -89.88039,
"Z": -249.5422
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,148 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": [],
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Wachunpelo",
"Groups": [
{
"Nodes": [
{
"DataId": 34866,
"Locations": [
{
"Position": {
"X": 242.7737,
"Y": -135.9734,
"Z": -431.2313
},
"MinimumAngle": -55,
"MaximumAngle": 100
},
{
"Position": {
"X": 302.1836,
"Y": -135.4149,
"Z": -359.7965
},
"MinimumAngle": 5,
"MaximumAngle": 155
},
{
"Position": {
"X": 256.1657,
"Y": -135.744,
"Z": -414.7577
}
}
]
},
{
"DataId": 34865,
"Locations": [
{
"Position": {
"X": 269.7338,
"Y": -134.0488,
"Z": -381.6242
},
"MinimumAngle": -85,
"MaximumAngle": 145
}
]
}
]
},
{
"Nodes": [
{
"DataId": 34868,
"Locations": [
{
"Position": {
"X": 389.1952,
"Y": -154.3099,
"Z": -368.3658
},
"MinimumAngle": 105,
"MaximumAngle": 345
},
{
"Position": {
"X": 401.9319,
"Y": -150.0004,
"Z": -408.114
},
"MinimumAngle": -70,
"MaximumAngle": 85
},
{
"Position": {
"X": 406.1098,
"Y": -152.2166,
"Z": -364.7227
},
"MinimumAngle": -210,
"MaximumAngle": 35
}
]
},
{
"DataId": 34867,
"Locations": [
{
"Position": {
"X": 399.1297,
"Y": -152.1141,
"Z": -394.71
},
"MinimumAngle": 120,
"MaximumAngle": 330
}
]
}
]
},
{
"Nodes": [
{
"DataId": 34864,
"Locations": [
{
"Position": {
"X": 359.517,
"Y": -161.1972,
"Z": -644.0471
}
},
{
"Position": {
"X": 307.4235,
"Y": -159.1669,
"Z": -622.6444
}
},
{
"Position": {
"X": 348.5925,
"Y": -165.3805,
"Z": -671.4193
}
}
]
},
{
"DataId": 34863,
"Locations": [
{
"Position": {
"X": 323.8758,
"Y": -162.9682,
"Z": -648.8156
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Questionable.Model.Gathering;
namespace Questionable.GatheringPaths;
[SuppressMessage("ReSharper", "PartialTypeWithSinglePart", Justification = "Required for RELEASE")]
public static partial class AssemblyGatheringLocationLoader
{
private static Dictionary<ushort, GatheringRoot>? _locations;
public static IReadOnlyDictionary<ushort, GatheringRoot> GetLocations()
{
if (_locations == null)
{
_locations = [];
LoadLocations();
}
return _locations ?? throw new InvalidOperationException("location data is not initialized");
}
public static Stream QuestSchema =>
typeof(AssemblyGatheringLocationLoader).Assembly.GetManifestResourceStream("Questionable.GatheringPaths.GatheringLocationSchema")!;
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private static void AddLocation(ushort questId, GatheringRoot root) => _locations![questId] = root;
}

View File

@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<RootNamespace>Questionable.GatheringPaths</RootNamespace>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<DebugType>none</DebugType>
<PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<Platforms>x64</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj" />
<ProjectReference Include="..\QuestPathGenerator\QuestPathGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
<ItemGroup>
<None Remove="gatheringlocation-v1.json" />
<EmbeddedResource Include="gatheringlocation-v1.json">
<LogicalName>Questionable.GatheringPaths.GatheringLocationSchema</LogicalName>
</EmbeddedResource>
<AdditionalFiles Include="gatheringlocation-v1.json" />
<AdditionalFiles Include="..\Questionable.Model\common-schema.json" />
</ItemGroup>
<ItemGroup>
<None Remove="2.x - A Realm Reborn" />
<None Remove="3.x - Heavensward" />
<None Remove="4.x - Stormblood" />
<None Remove="5.x - Shadowbringers" />
<None Remove="6.x - Endwalker" />
<None Remove="7.x - Dawntrail" />
<AdditionalFiles Include="2.x - A Realm Reborn\**\*.json" />
<AdditionalFiles Include="3.x - Heavensward\**\*.json" />
<AdditionalFiles Include="4.x - Stormblood\**\*.json" />
<AdditionalFiles Include="5.x - Shadowbringers\**\*.json" />
<AdditionalFiles Include="6.x - Endwalker\**\*.json" />
<AdditionalFiles Include="7.x - Dawntrail\**\*.json" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,120 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"title": "Gathering Location V1",
"description": "A series of gathering locationsk",
"type": "object",
"properties": {
"$schema": {
"type": "string",
"const": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json"
},
"Author": {
"description": "Author of the gathering location data",
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
},
"TerritoryId": {
"type": "number"
},
"AetheryteShortcut": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"Groups": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Nodes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"DataId": {
"type": "number",
"minimum": 30000,
"maximum": 50000
},
"Locations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Position": {
"$ref": "#/$defs/Vector3"
},
"MinimumAngle": {
"type": "number",
"minimum": -360,
"maximum": 360
},
"MaximumAngle": {
"type": "number",
"minimum": -360,
"maximum": 360
},
"MinimumDistance": {
"type": "number",
"minimum": 0
},
"MaximumDistance": {
"type": "number",
"exclusiveMinimum": 0
}
},
"required": [
"Position"
],
"additionalProperties": false
}
}
},
"required": [
"DataId"
],
"additionalProperties": false
}
}
},
"required": [
"Nodes"
],
"additionalProperties": false
}
}
},
"required": [
"$schema",
"Author",
"TerritoryId",
"Groups"
],
"additionalProperties": false,
"$defs": {
"Vector3": {
"type": "object",
"description": "Position to (typically) walk to",
"properties": {
"X": {
"type": "number"
},
"Y": {
"type": "number"
},
"Z": {
"type": "number"
}
},
"required": [
"X",
"Y",
"Z"
]
}
}
}

View File

@ -0,0 +1,26 @@
{
"version": 1,
"dependencies": {
"net8.0-windows7.0": {
"System.Text.Encodings.Web": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
},
"System.Text.Json": {
"type": "Transitive",
"resolved": "8.0.4",
"contentHash": "bAkhgDJ88XTsqczoxEMliSrpijKZHhbJQldhAmObj/RbrN3sU5dcokuXmWJWsdQAhiMJ9bTayWsL1C9fbbCRhw==",
"dependencies": {
"System.Text.Encodings.Web": "8.0.0"
}
},
"questionable.model": {
"type": "Project",
"dependencies": {
"System.Text.Json": "[8.0.4, )"
}
}
}
}
}

View File

@ -1,4 +1,4 @@
using Questionable.Model.V1;
using Questionable.Model.Questing;
using Questionable.QuestPathGenerator;
using Xunit;

View File

@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text.Json;
using Json.Schema;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Questionable.Model.Gathering;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Questionable.QuestPathGenerator.RoslynShortcuts;
namespace Questionable.QuestPathGenerator;
[Generator]
[SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008")]
public class GatheringSourceGenerator : ISourceGenerator
{
private static readonly DiagnosticDescriptor InvalidJson = new("GPG0001",
"Invalid JSON",
"Invalid gathering file: {0}",
nameof(GatheringSourceGenerator),
DiagnosticSeverity.Error,
true);
public void Initialize(GeneratorInitializationContext context)
{
// No initialization required for this generator.
}
public void Execute(GeneratorExecutionContext context)
{
// Find schema definition
AdditionalText? gatheringSchema =
context.AdditionalFiles.SingleOrDefault(x => Path.GetFileName(x.Path) == "gatheringlocation-v1.json");
if (gatheringSchema != null)
GenerateGatheringSource(context, gatheringSchema);
}
private void GenerateGatheringSource(GeneratorExecutionContext context, AdditionalText jsonSchemaFile)
{
var gatheringSchema = JsonSchema.FromText(jsonSchemaFile.GetText()!.ToString());
List<(ushort, GatheringRoot)> gatheringLocations = [];
foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFile, gatheringSchema, InvalidJson))
{
var gatheringLocation = node.Deserialize<GatheringRoot>()!;
gatheringLocations.Add((id, gatheringLocation));
}
if (gatheringLocations.Count == 0)
return;
var partitionedLocations = gatheringLocations
.OrderBy(x => x.Item1)
.GroupBy(x => $"LoadLocation{x.Item1 / 100}")
.ToList();
var methods = Utils.CreateMethods("LoadLocations", partitionedLocations, CreateInitializer);
var code =
CompilationUnit()
.WithUsings(
List(
new[]
{
UsingDirective(
IdentifierName("System")),
UsingDirective(
QualifiedName(
IdentifierName("System"),
IdentifierName("Numerics"))),
UsingDirective(
QualifiedName(
IdentifierName("System"),
IdentifierName("IO"))),
UsingDirective(
QualifiedName(
QualifiedName(
IdentifierName("System"), IdentifierName("Collections")),
IdentifierName("Generic"))),
UsingDirective(
QualifiedName(
QualifiedName(
IdentifierName("Questionable"),
IdentifierName("Model")),
IdentifierName("Gathering"))),
UsingDirective(
QualifiedName(
QualifiedName(
IdentifierName("Questionable"),
IdentifierName("Model")),
IdentifierName("Common")))
}))
.WithMembers(
SingletonList<MemberDeclarationSyntax>(
FileScopedNamespaceDeclaration(
QualifiedName(
IdentifierName("Questionable"),
IdentifierName("GatheringPaths")))
.WithMembers(
SingletonList<MemberDeclarationSyntax>(
ClassDeclaration("AssemblyGatheringLocationLoader")
.WithModifiers(
TokenList(Token(SyntaxKind.PartialKeyword)))
.WithMembers(List<MemberDeclarationSyntax>(methods))))))
.NormalizeWhitespace();
// Add the source code to the compilation.
context.AddSource("AssemblyGatheringLocationLoader.g.cs", code.ToFullString());
}
private static StatementSyntax[] CreateInitializer(List<(ushort QuestId, GatheringRoot Root)> quests)
{
List<StatementSyntax> statements = [];
foreach (var quest in quests)
{
statements.Add(
ExpressionStatement(
InvocationExpression(
IdentifierName("AddLocation"))
.WithArgumentList(
ArgumentList(
SeparatedList<ArgumentSyntax>(
new SyntaxNodeOrToken[]
{
Argument(
LiteralExpression(SyntaxKind.NumericLiteralExpression,
Literal(quest.QuestId))),
Token(SyntaxKind.CommaToken),
Argument(CreateGatheringRootExpression(quest.QuestId, quest.Root))
})))));
}
return statements.ToArray();
}
private static ObjectCreationExpressionSyntax CreateGatheringRootExpression(ushort locationId, GatheringRoot root)
{
try
{
return ObjectCreationExpression(
IdentifierName(nameof(GatheringRoot)))
.WithInitializer(
InitializerExpression(
SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>(
SyntaxNodeList(
AssignmentList(nameof(GatheringRoot.Author), root.Author).AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringRoot.TerritoryId), root.TerritoryId, default)
.AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringRoot.AetheryteShortcut), root.AetheryteShortcut, null),
AssignmentList(nameof(GatheringRoot.Groups), root.Groups).AsSyntaxNodeOrToken()))));
}
catch (Exception e)
{
throw new Exception($"GatheringGen[{locationId}]: {e.Message}", e);
}
}
}

View File

@ -1,16 +1,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using Json.Schema;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Questionable.Model.V1;
using Questionable.Model.Questing;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Questionable.QuestPathGenerator.RoslynShortcuts;
@ -38,47 +36,21 @@ public class QuestSourceGenerator : ISourceGenerator
public void Execute(GeneratorExecutionContext context)
{
List<(ushort, QuestRoot)> quests = [];
// Find schema definition
AdditionalText jsonSchemaFile =
context.AdditionalFiles.Single(x => Path.GetFileName(x.Path) == "quest-v1.json");
AdditionalText? questSchema =
context.AdditionalFiles.SingleOrDefault(x => Path.GetFileName(x.Path) == "quest-v1.json");
if (questSchema != null)
GenerateQuestSource(context, questSchema);
}
private void GenerateQuestSource(GeneratorExecutionContext context, AdditionalText jsonSchemaFile)
{
var questSchema = JsonSchema.FromText(jsonSchemaFile.GetText()!.ToString());
// Go through all files marked as an Additional File in file properties.
foreach (var additionalFile in context.AdditionalFiles)
List<(ushort, QuestRoot)> quests = [];
foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFile, questSchema, InvalidJson))
{
if (additionalFile == null || additionalFile == jsonSchemaFile)
continue;
if (Path.GetExtension(additionalFile.Path) != ".json")
continue;
string name = Path.GetFileName(additionalFile.Path);
if (!name.Contains('_'))
continue;
ushort id = ushort.Parse(name.Substring(0, name.IndexOf('_')));
var text = additionalFile.GetText();
if (text == null)
continue;
var questNode = JsonNode.Parse(text.ToString());
var evaluationResult = questSchema.Evaluate(questNode, new EvaluationOptions
{
Culture = CultureInfo.InvariantCulture,
OutputFormat = OutputFormat.List
});
if (!evaluationResult.IsValid)
{
var error = Diagnostic.Create(InvalidJson,
null,
Path.GetFileName(additionalFile.Path));
context.ReportDiagnostic(error);
}
var quest = questNode.Deserialize<QuestRoot>()!;
var quest = node.Deserialize<QuestRoot>()!;
if (quest.Disabled)
{
quest.Author = [];
@ -97,38 +69,7 @@ public class QuestSourceGenerator : ISourceGenerator
.GroupBy(x => $"LoadQuests{x.Item1 / 50}")
.ToList();
List<MethodDeclarationSyntax> methods =
[
MethodDeclaration(
PredefinedType(
Token(SyntaxKind.VoidKeyword)),
Identifier("LoadQuests"))
.WithModifiers(
TokenList(
Token(SyntaxKind.PrivateKeyword),
Token(SyntaxKind.StaticKeyword)))
.WithBody(
Block(
partitionedQuests
.Select(x =>
ExpressionStatement(
InvocationExpression(
IdentifierName(x.Key))))))
];
foreach (var partition in partitionedQuests)
{
methods.Add(MethodDeclaration(
PredefinedType(
Token(SyntaxKind.VoidKeyword)),
Identifier(partition.Key))
.WithModifiers(
TokenList(
Token(SyntaxKind.PrivateKeyword),
Token(SyntaxKind.StaticKeyword)))
.WithBody(
Block(CreateInitializer(partition.ToList()))));
}
var methods = Utils.CreateMethods("LoadQuests", partitionedQuests, CreateInitializer);
var code =
CompilationUnit()
@ -156,7 +97,13 @@ public class QuestSourceGenerator : ISourceGenerator
QualifiedName(
IdentifierName("Questionable"),
IdentifierName("Model")),
IdentifierName("V1")))
IdentifierName("Questing"))),
UsingDirective(
QualifiedName(
QualifiedName(
IdentifierName("Questionable"),
IdentifierName("Model")),
IdentifierName("Common")))
}))
.WithMembers(
SingletonList<MemberDeclarationSyntax>(

View File

@ -6,7 +6,9 @@ using System.Numerics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Questionable.Model.V1;
using Questionable.Model.Common;
using Questionable.Model.Gathering;
using Questionable.Model.Questing;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Questionable.QuestPathGenerator;
@ -213,7 +215,9 @@ public static class RoslynShortcuts
{
Argument(LiteralValue(qwv.High)),
Token(SyntaxKind.CommaToken),
Argument(LiteralValue(qwv.Low))
Argument(LiteralValue(qwv.Low)),
Token(SyntaxKind.CommaToken),
Argument(LiteralValue(qwv.Mode))
})));
}
else if (value is List<QuestWorkValue> list)
@ -255,6 +259,9 @@ public static class RoslynShortcuts
Assignment(nameof(SkipStepConditions.Never), skipStepConditions.Never,
emptyStep.Never)
.AsSyntaxNodeOrToken(),
AssignmentList(nameof(SkipStepConditions.CompletionQuestVariablesFlags),
skipStepConditions.CompletionQuestVariablesFlags)
.AsSyntaxNodeOrToken(),
Assignment(nameof(SkipStepConditions.Flying), skipStepConditions.Flying,
emptyStep.Flying)
.AsSyntaxNodeOrToken(),
@ -307,6 +314,57 @@ public static class RoslynShortcuts
Assignment(nameof(SkipAetheryteCondition.InSameTerritory),
skipAetheryteCondition.InSameTerritory, emptyAetheryte.InSameTerritory)))));
}
else if (value is GatheringNodeGroup nodeGroup)
{
return ObjectCreationExpression(
IdentifierName(nameof(GatheringNodeGroup)))
.WithInitializer(
InitializerExpression(
SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>(
SyntaxNodeList(
AssignmentList(nameof(GatheringNodeGroup.Nodes), nodeGroup.Nodes)
.AsSyntaxNodeOrToken()))));
}
else if (value is GatheringNode nodeLocation)
{
var emptyLocation = new GatheringNode();
return ObjectCreationExpression(
IdentifierName(nameof(GatheringNode)))
.WithInitializer(
InitializerExpression(
SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>(
SyntaxNodeList(
Assignment(nameof(GatheringNode.DataId), nodeLocation.DataId,
emptyLocation.DataId)
.AsSyntaxNodeOrToken(),
AssignmentList(nameof(GatheringNode.Locations), nodeLocation.Locations)
.AsSyntaxNodeOrToken()))));
}
else if (value is GatheringLocation location)
{
var emptyLocation = new GatheringLocation();
return ObjectCreationExpression(
IdentifierName(nameof(GatheringLocation)))
.WithInitializer(
InitializerExpression(
SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>(
SyntaxNodeList(
Assignment(nameof(GatheringLocation.Position), location.Position,
emptyLocation.Position).AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringLocation.MinimumAngle), location.MinimumAngle,
emptyLocation.MinimumAngle).AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringLocation.MaximumAngle), location.MaximumAngle,
emptyLocation.MaximumAngle).AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringLocation.MinimumDistance),
location.MinimumDistance, emptyLocation.MinimumDistance)
.AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringLocation.MaximumDistance),
location.MaximumDistance, emptyLocation.MaximumDistance)
.AsSyntaxNodeOrToken()))));
}
else if (value is null)
return LiteralExpression(SyntaxKind.NullLiteralExpression);
}

110
QuestPathGenerator/Utils.cs Normal file
View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.Json.Nodes;
using Json.Schema;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Questionable.QuestPathGenerator;
public static class Utils
{
public static IEnumerable<(ushort, JsonNode)> GetAdditionalFiles(GeneratorExecutionContext context,
AdditionalText jsonSchemaFile, JsonSchema jsonSchema, DiagnosticDescriptor invalidJson)
{
var commonSchemaFile = context.AdditionalFiles.Single(x => Path.GetFileName(x.Path) == "common-schema.json");
List<AdditionalText> jsonSchemaFiles = [jsonSchemaFile, commonSchemaFile];
SchemaRegistry.Global.Register(
new Uri("https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json"),
JsonSchema.FromText(commonSchemaFile.GetText()!.ToString()));
foreach (var additionalFile in context.AdditionalFiles)
{
if (additionalFile == null || jsonSchemaFiles.Contains(additionalFile))
continue;
if (Path.GetExtension(additionalFile.Path) != ".json")
continue;
string name = Path.GetFileName(additionalFile.Path);
if (!name.Contains("_"))
continue;
ushort id = ushort.Parse(name.Substring(0, name.IndexOf('_')));
var text = additionalFile.GetText();
if (text == null)
continue;
var node = JsonNode.Parse(text.ToString());
if (node == null)
continue;
string? schemaLocation = node["$schema"]?.GetValue<string?>();
if (schemaLocation == null || new Uri(schemaLocation) != jsonSchema.GetId())
continue;
var evaluationResult = jsonSchema.Evaluate(node, new EvaluationOptions
{
Culture = CultureInfo.InvariantCulture,
OutputFormat = OutputFormat.List,
});
if (evaluationResult.HasErrors)
{
var error = Diagnostic.Create(invalidJson,
null,
Path.GetFileName(additionalFile.Path));
context.ReportDiagnostic(error);
continue;
}
yield return (id, node);
}
}
public static List<MethodDeclarationSyntax> CreateMethods<T>(string prefix,
List<IGrouping<string, (ushort, T)>> partitions,
Func<List<(ushort, T)>, StatementSyntax[]> toInitializers)
{
List<MethodDeclarationSyntax> methods =
[
MethodDeclaration(
PredefinedType(
Token(SyntaxKind.VoidKeyword)),
Identifier(prefix))
.WithModifiers(
TokenList(
Token(SyntaxKind.PrivateKeyword),
Token(SyntaxKind.StaticKeyword)))
.WithBody(
Block(
partitions
.Select(x =>
ExpressionStatement(
InvocationExpression(
IdentifierName(x.Key))))))
];
foreach (var partition in partitions)
{
methods.Add(MethodDeclaration(
PredefinedType(
Token(SyntaxKind.VoidKeyword)),
Identifier(partition.Key))
.WithModifiers(
TokenList(
Token(SyntaxKind.PrivateKeyword),
Token(SyntaxKind.StaticKeyword)))
.WithBody(
Block(toInitializers(partition.ToList()))));
}
return methods;
}
}

View File

@ -1,7 +1,6 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"Disabled": true,
"QuestSequence": [
{
"Sequence": 0,
@ -24,6 +23,183 @@
]
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1001739,
"Position": {
"X": -94.529724,
"Y": 6.4999976,
"Z": 39.81079
},
"TerritoryId": 131,
"InteractionType": "Interact",
"DialogueChoices": [
{
"Type": "YesNo",
"Prompt": "TEXT_CLSGLA020_00253_Q2_000_1",
"Yes": true
}
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"Position": {
"X": 45.13088,
"Y": 3.889354,
"Z": -166.51999
},
"TerritoryId": 130,
"InteractionType": "WalkTo",
"AethernetShortcut": [
"[Ul'dah] Gladiators' Guild",
"[Ul'dah] Adventurers' Guild"
],
"SkipConditions": {
"StepIf": {
"InTerritory": [
141
]
}
}
},
{
"Position": {
"X": -116.10664,
"Y": 10.801613,
"Z": 276.979
},
"TerritoryId": 141,
"InteractionType": "Combat",
"EnemySpawnType": "OverworldEnemies",
"ComplexCombatData": [
{
"DataId": 351,
"MinimumKillCount": 3,
"CompletionQuestVariablesFlags": [
{
"Low": 3,
"Mode": "Exact"
},
null,
null,
null,
null,
null
]
},
{
"DataId": 141,
"MinimumKillCount": 3,
"CompletionQuestVariablesFlags": [
null,
{
"High": 3,
"Mode": "Exact"
},
null,
null,
null,
null
]
}
],
"CompletionQuestVariablesFlags": [
{
"Low": 3,
"Mode": "Exact"
},
{
"High": 3,
"Mode": "Exact"
},
null,
null,
null,
null
]
},
{
"Position": {
"X": 39.635372,
"Y": 3.2401803,
"Z": 273.41232
},
"TerritoryId": 141,
"InteractionType": "Combat",
"EnemySpawnType": "OverworldEnemies",
"ComplexCombatData": [
{
"DataId": 205,
"MinimumKillCount": 3,
"CompletionQuestVariablesFlags": [
null,
{
"Low": 3,
"Mode": "Exact"
},
null,
null,
null,
null
]
}
],
"CompletionQuestVariablesFlags": [
null,
{
"Low": 3,
"Mode": "Exact"
},
null,
null,
null,
null
]
}
]
},
{
"Sequence": 255,
"Steps": [
{
"Position": {
"X": -118.17538,
"Y": 18.35357,
"Z": 341.3039
},
"TerritoryId": 141,
"InteractionType": "WalkTo",
"SkipConditions": {
"StepIf": {
"NotInTerritory": [
141
]
}
}
},
{
"DataId": 1001739,
"Position": {
"X": -94.529724,
"Y": 6.4999976,
"Z": 39.81079
},
"TerritoryId": 131,
"InteractionType": "CompleteQuest",
"AethernetShortcut": [
"[Ul'dah] Adventurers' Guild",
"[Ul'dah] Gladiators' Guild"
],
"NextQuestId": 256
}
]
}
]
}

View File

@ -0,0 +1,286 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1001739,
"Position": {
"X": -94.529724,
"Y": 6.4999976,
"Z": 39.81079
},
"TerritoryId": 131,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1003990,
"Position": {
"X": 77.25635,
"Y": 4.0999947,
"Z": -138.62823
},
"TerritoryId": 130,
"InteractionType": "Emote",
"Emote": "me",
"AethernetShortcut": [
"[Ul'dah] Gladiators' Guild",
"[Ul'dah] Adventurers' Guild"
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 1003984,
"Position": {
"X": 45.029297,
"Y": 3.9999998,
"Z": -128.16058
},
"TerritoryId": 130,
"InteractionType": "Emote",
"Emote": "me",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 1003992,
"Position": {
"X": 12.191956,
"Y": 4.0999947,
"Z": -155.53528
},
"TerritoryId": 130,
"InteractionType": "Emote",
"Emote": "me",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
},
{
"DataId": 1003994,
"Position": {
"X": 15.976135,
"Y": 7.9999995,
"Z": -124.071106
},
"TerritoryId": 130,
"InteractionType": "Emote",
"Emote": "me",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1004222,
"Position": {
"X": 21.927185,
"Y": 7.1999974,
"Z": -97.39838
},
"TerritoryId": 130,
"InteractionType": "Emote",
"Emote": "me"
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1001353,
"Position": {
"X": 21.072632,
"Y": 7.45,
"Z": -78.78235
},
"TerritoryId": 130,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 4,
"Steps": [
{
"DataId": 1001739,
"Position": {
"X": -94.529724,
"Y": 6.4999976,
"Z": 39.81079
},
"TerritoryId": 131,
"InteractionType": "Interact",
"AethernetShortcut": [
"[Ul'dah] Adventurers' Guild",
"[Ul'dah] Gladiators' Guild"
]
}
]
},
{
"Sequence": 5,
"Steps": [
{
"Position": {
"X": -112.70276,
"Y": 7.7544775,
"Z": 9.123527
},
"TerritoryId": 131,
"InteractionType": "WalkTo"
},
{
"Position": {
"X": -183.00035,
"Y": 13.958975,
"Z": -13.998203
},
"TerritoryId": 130,
"InteractionType": "WalkTo"
},
{
"DataId": 1003985,
"Position": {
"X": 201.52588,
"Y": 52.038116,
"Z": 149.40112
},
"TerritoryId": 140,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 6,
"Steps": [
{
"DataId": 2001408,
"Position": {
"X": 154.37549,
"Y": 52.536743,
"Z": 200.91553
},
"TerritoryId": 140,
"InteractionType": "Combat",
"EnemySpawnType": "AfterInteraction",
"KillEnemyDataIds": [
1246
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 2001409,
"Position": {
"X": 141.83252,
"Y": 52.994507,
"Z": 221.54565
},
"TerritoryId": 140,
"InteractionType": "Combat",
"EnemySpawnType": "AfterInteraction",
"KillEnemyDataIds": [
1390
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
]
},
{
"Sequence": 7,
"Steps": [
{
"DataId": 1003985,
"Position": {
"X": 201.52588,
"Y": 52.038116,
"Z": 149.40112
},
"TerritoryId": 140,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"Position": {
"X": 473.74796,
"Y": 96.62057,
"Z": 159.993
},
"TerritoryId": 140,
"InteractionType": "WalkTo"
},
{
"Position": {
"X": -117.06801,
"Y": 9.195247,
"Z": 9.181297
},
"TerritoryId": 130,
"InteractionType": "WalkTo"
},
{
"DataId": 1001739,
"Position": {
"X": -94.529724,
"Y": 6.4999976,
"Z": 39.81079
},
"TerritoryId": 131,
"InteractionType": "CompleteQuest"
}
]
}
]
}

View File

@ -37,16 +37,18 @@
"SkipConditions": {
"AetheryteShortcutIf": {
"InSameTerritory": true
},
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
}
},
{
"DataId": 2002380,
@ -76,14 +78,18 @@
"TerritoryId": 180,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2002379,
@ -112,14 +118,18 @@
"TerritoryId": 180,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 2002382,
@ -148,14 +158,18 @@
"TerritoryId": 180,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2002381,

View File

@ -65,14 +65,18 @@
"TerritoryId": 139,
"InteractionType": "WalkTo",
"Mount": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1007844,
@ -120,16 +124,16 @@
},
"TerritoryId": 139,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
],
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
],
"Flying": "Unlocked"
}
}

View File

@ -28,18 +28,20 @@
},
"TerritoryId": 155,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
],
"AetheryteShortcut": "Coerthas Central Highlands - Camp Dragonhead",
"SkipConditions": {
"AetheryteShortcutIf": {
"InSameTerritory": true
},
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
},
"Fly": true
@ -56,14 +58,18 @@
"KillEnemyDataIds": [
1918
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2002308,
@ -127,14 +133,18 @@
"InteractionType": "UseItem",
"ItemId": 30362,
"TargetTerritoryId": 140,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -148,14 +158,18 @@
"KillEnemyDataIds": [
1920
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2002310,

View File

@ -65,14 +65,18 @@
},
"TerritoryId": 148,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -83,14 +87,18 @@
"TerritoryId": 148,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2000748,
@ -120,14 +128,18 @@
"TerritoryId": 148,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"Position": {
@ -137,14 +149,18 @@
},
"TerritoryId": 148,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 2000751,

View File

@ -36,14 +36,18 @@
},
"StopDistance": 3
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-8
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
8
]
}
}
},
{
"DataId": 1002639,

View File

@ -64,14 +64,18 @@
},
"StopDistance": 5
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 1004506,

View File

@ -65,14 +65,18 @@
"TerritoryId": 141,
"InteractionType": "WalkTo",
"DisableNavmesh": false,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1004599,

View File

@ -29,6 +29,7 @@
"TerritoryId": 139,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"Mount": true,
"Comment": "Avoids swimming"
},
{

View File

@ -63,14 +63,18 @@
},
"DelaySeconds": 0.25
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-8
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
8
]
}
}
},
{
"DataId": 2001953,
@ -92,6 +96,27 @@
8
]
},
{
"Position": {
"X": -103.87269,
"Y": 5.116502,
"Z": -73.9041
},
"TerritoryId": 153,
"InteractionType": "WalkTo",
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
"X": -90.467575,
@ -109,14 +134,18 @@
},
"DelaySeconds": 0.25
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2001951,
@ -146,14 +175,18 @@
"TerritoryId": 153,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"Position": {
@ -163,14 +196,18 @@
},
"TerritoryId": 153,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 2001952,

View File

@ -20,6 +20,17 @@
{
"Sequence": 1,
"Steps": [
{
"Position": {
"X": -119.1183,
"Y": 3.7999938,
"Z": -104.33473
},
"TerritoryId": 130,
"InteractionType": "WalkTo",
"AetheryteShortcut": "Ul'dah",
"$": "Ul'dah Aetheryte to Immortal Flames"
},
{
"DataId": 1004576,
"Position": {
@ -28,8 +39,7 @@
"Z": -114.67157
},
"TerritoryId": 130,
"InteractionType": "Interact",
"AetheryteShortcut": "Ul'dah"
"InteractionType": "Interact"
}
]
},

View File

@ -26,6 +26,49 @@
{
"Sequence": 1,
"Steps": [
{
"Position": {
"X": -179.69392,
"Y": 18.008331,
"Z": -279.60886
},
"TerritoryId": 146,
"InteractionType": "WalkTo",
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
"X": -184.29613,
"Y": 3.5985415,
"Z": -246.7013
},
"TerritoryId": 146,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1006702,
"Position": {

View File

@ -12,6 +12,7 @@
"Y": 26.138475,
"Z": -355.0622
},
"StopDistance": 7,
"TerritoryId": 146,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "Southern Thanalan - Little Ala Mhigo",
@ -53,6 +54,7 @@
"Y": 19.02249,
"Z": -557.8546
},
"StopDistance": 7,
"TerritoryId": 146,
"InteractionType": "Interact"
}

View File

@ -71,14 +71,18 @@
725,
726
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2002261,

View File

@ -64,14 +64,18 @@
"InteractionType": "WalkTo",
"$": "NW Skyfire Locks door (inside)",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 1006396,

View File

@ -34,14 +34,18 @@
},
"TerritoryId": 138,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -52,14 +56,18 @@
"TerritoryId": 138,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1006500,

View File

@ -94,14 +94,18 @@
"TerritoryId": 156,
"InteractionType": "WalkTo",
"Comment": "Avoids pit",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -112,14 +116,18 @@
"TerritoryId": 156,
"InteractionType": "WalkTo",
"Comment": "Move into LOS",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2002230,

View File

@ -68,14 +68,18 @@
"TerritoryId": 351,
"InteractionType": "Interact",
"TargetTerritoryId": 156,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-2
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
2
]
}
}
},
{
"DataId": 1009147,

View File

@ -76,14 +76,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"AetheryteShortcut": "Upper La Noscea - Camp Bronze Lake",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -94,14 +98,18 @@
"TerritoryId": 139,
"InteractionType": "WalkTo",
"TargetTerritoryId": 180,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -112,27 +120,35 @@
"TerritoryId": 180,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"TerritoryId": 180,
"InteractionType": "AttuneAetheryte",
"Aetheryte": "Outer La Noscea - Camp Overlook",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -143,14 +159,18 @@
"TerritoryId": 180,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -161,14 +181,18 @@
"TerritoryId": 180,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -179,14 +203,18 @@
"TerritoryId": 180,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2000075,
@ -221,14 +249,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"AetheryteShortcut": "Western La Noscea - Aleport",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2000076,

View File

@ -28,14 +28,18 @@
},
"TerritoryId": 180,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2003715,

View File

@ -28,14 +28,18 @@
},
"TerritoryId": 400,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -46,14 +50,18 @@
"TerritoryId": 400,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -63,14 +71,18 @@
},
"TerritoryId": 400,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 1013424,
@ -118,14 +130,18 @@
},
"TerritoryId": 400,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -144,14 +160,18 @@
"Z": 380.9018
}
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1013421,

View File

@ -28,14 +28,18 @@
},
"TerritoryId": 398,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -46,14 +50,18 @@
"TerritoryId": 398,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -64,14 +72,18 @@
"TerritoryId": 398,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1011932,
@ -99,14 +111,18 @@
},
"TerritoryId": 398,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -117,14 +133,18 @@
"TerritoryId": 398,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 1011924,

View File

@ -34,14 +34,18 @@
},
"TerritoryId": 398,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -52,14 +56,18 @@
"TerritoryId": 398,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -70,14 +78,18 @@
"TerritoryId": 398,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1011932,
@ -106,14 +118,18 @@
},
"TerritoryId": 398,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -124,14 +140,18 @@
"TerritoryId": 398,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 1011924,

View File

@ -29,14 +29,18 @@
"TerritoryId": 401,
"InteractionType": "WalkTo",
"Mount": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -47,14 +51,18 @@
"TerritoryId": 401,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1013498,

View File

@ -86,14 +86,18 @@
},
"TerritoryId": 418,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -104,14 +108,18 @@
"TerritoryId": 418,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1012251,

View File

@ -64,14 +64,18 @@
null,
null
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2009361,
@ -160,14 +164,18 @@
null,
null
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2009360,
@ -253,14 +261,18 @@
null,
null
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2009359,
@ -346,14 +358,18 @@
null,
null
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-4
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
4
]
}
}
},
{
"DataId": 2009364,
@ -436,14 +452,18 @@
null,
null
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-8
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
8
]
}
}
},
{
"DataId": 2009363,
@ -529,14 +549,18 @@
null,
null
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 2009362,

View File

@ -63,14 +63,18 @@
"TerritoryId": 813,
"InteractionType": "WalkTo",
"Mount": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -81,14 +85,18 @@
"TerritoryId": 813,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 1027339,
@ -116,14 +124,18 @@
},
"TerritoryId": 813,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -133,14 +145,18 @@
},
"TerritoryId": 813,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -150,14 +166,18 @@
},
"TerritoryId": 813,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1027420,

View File

@ -29,14 +29,18 @@
"TerritoryId": 813,
"InteractionType": "WalkTo",
"Comment": "Tower Bottom",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -48,14 +52,18 @@
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"Comment": "Tower Bottom Platform 1",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2010618,

View File

@ -74,14 +74,18 @@
},
"TerritoryId": 813,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 1028952,

View File

@ -28,14 +28,18 @@
},
"TerritoryId": 816,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2009820,
@ -66,14 +70,18 @@
"TerritoryId": 816,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2009819,

View File

@ -46,14 +46,18 @@
},
"TerritoryId": 816,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -64,14 +68,18 @@
"TerritoryId": 816,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2009831,

View File

@ -150,14 +150,18 @@
},
"TerritoryId": 816,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -168,14 +172,18 @@
"TerritoryId": 816,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2009836,
@ -214,14 +222,18 @@
},
"DelaySeconds": 0.2
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -241,14 +253,18 @@
},
"DelaySeconds": 0.1
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -268,14 +284,18 @@
},
"DelaySeconds": 0.1
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -295,14 +315,18 @@
},
"DelaySeconds": 0.2
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2009835,

View File

@ -79,14 +79,18 @@
"StopDistance": 2,
"Type": "RepeatedJumps"
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 2009890,
@ -128,14 +132,18 @@
"StopDistance": 2,
"Type": "RepeatedJumps"
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2009887,
@ -166,14 +174,18 @@
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"Mount": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"Position": {
@ -196,14 +208,18 @@
"StopDistance": 2,
"Type": "RepeatedJumps"
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2009888,
@ -245,14 +261,18 @@
"StopDistance": 2,
"Type": "RepeatedJumps"
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2009889,

View File

@ -60,14 +60,18 @@
},
"TerritoryId": 814,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2010088,
@ -114,14 +118,18 @@
},
"TerritoryId": 814,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2010089,

View File

@ -48,14 +48,18 @@
"TerritoryId": 819,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1027246,

View File

@ -29,14 +29,18 @@
"TerritoryId": 816,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2010856,
@ -83,14 +87,18 @@
},
"TerritoryId": 816,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2010857,

View File

@ -31,7 +31,35 @@
"InteractionType": "UseItem",
"ItemId": 2002943,
"AetheryteShortcut": "Il Mheg - Pia Enni",
"Fly": true
"Fly": true,
"RequiredQuestVariables": [
null,
null,
[1],
null,
null,
null
]
},
{
"DataId": 1032202,
"Position": {
"X": 10.849121,
"Y": 100.161,
"Z": -886.22876
},
"TerritoryId": 816,
"InteractionType": "UseItem",
"ItemId": 2002943,
"Fly": true,
"RequiredQuestVariables": [
null,
null,
[2],
null,
null,
null
]
}
]
},

View File

@ -0,0 +1,3 @@
0 0 ? 0 0 0
1 → 1032203
2 → 1032202

View File

@ -0,0 +1,27 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 255,
"Steps": [
{
"Position": {
"X": -435.39066,
"Y": -9.809827,
"Z": -594.5472
},
"TerritoryId": 1187,
"InteractionType": "WalkTo",
"Fly": true,
"RequiredGatheredItems": [
{
"ItemId": 43992,
"ItemCount": 1234
}
]
}
]
}
]
}

View File

@ -29,14 +29,18 @@
"StopDistance": 1,
"TerritoryId": 959,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -56,14 +60,18 @@
},
"Mount": false,
"Comment": "Platform 1",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -82,14 +90,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 2",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -108,14 +120,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 3",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -134,14 +150,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 4",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -160,14 +180,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 5",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -186,14 +210,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 6",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"Position": {
@ -204,14 +232,18 @@
"TerritoryId": 959,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1041789,
@ -287,14 +319,18 @@
},
"Mount": false,
"Comment": "Platform 1",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -314,14 +350,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 2",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -341,14 +381,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 3",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -368,14 +412,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 4",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -395,14 +443,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 5",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"Position": {
@ -422,14 +474,18 @@
"DelaySeconds": 0.25
},
"Comment": "Platform 6",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1041791,

View File

@ -61,14 +61,18 @@
},
"TerritoryId": 957,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2011914,

View File

@ -74,7 +74,7 @@
null,
null,
null,
-64
64
],
"$": "QuestVariables after killing enemy: 17 1 0 0 0 64"
},

View File

@ -66,14 +66,18 @@
},
"TerritoryId": 958,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1037715,

View File

@ -112,14 +112,18 @@
"InteractionType": "WalkTo",
"Mount": true,
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2012111,
@ -180,14 +184,18 @@
},
"TerritoryId": 958,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
],
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
},
"Comment": "Avoids combat"
},
{
@ -219,14 +227,18 @@
"TerritoryId": 958,
"InteractionType": "WalkTo",
"Comment": "Avoids combat",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 2012110,

View File

@ -60,14 +60,18 @@
"TerritoryId": 963,
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
],
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
},
"Sprint": true
},
{

View File

@ -71,14 +71,18 @@
"Z": -1.1141448
}
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 2012128,

View File

@ -109,14 +109,18 @@
},
"TerritoryId": 960,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2012354,

View File

@ -51,14 +51,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"AetheryteShortcut": "Thavnair - Yedlihmad",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1037631,

View File

@ -97,14 +97,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1037655,
@ -151,14 +155,18 @@
},
"TerritoryId": 957,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1037708,
@ -169,14 +177,18 @@
},
"TerritoryId": 957,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
}
]
},

View File

@ -68,14 +68,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2012455,
@ -105,14 +109,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2012457,
@ -141,14 +149,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2012456,

View File

@ -0,0 +1,36 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1038500,
"Position": {
"X": -357.83936,
"Y": 21.84602,
"Z": -91.32526
},
"TerritoryId": 962,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1038500,
"Position": {
"X": -357.83936,
"Y": 21.84602,
"Z": -91.32526
},
"TerritoryId": 962,
"InteractionType": "CompleteQuest"
}
]
}
]
}

View File

@ -0,0 +1,68 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1038504,
"Position": {
"X": -357.62573,
"Y": 21.64856,
"Z": -95.99457
},
"TerritoryId": 962,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1038505,
"Position": {
"X": -376.45538,
"Y": 18.999998,
"Z": 37.00305
},
"TerritoryId": 962,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1038503,
"Position": {
"X": -367.0863,
"Y": 21.84602,
"Z": -101.701416
},
"TerritoryId": 962,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"StopDistance": 7,
"TerritoryId": 962,
"InteractionType": "CompleteQuest",
"NextQuestId": 4154
}
]
}
]
}

View File

@ -0,0 +1,49 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"TerritoryId": 962,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"TerritoryId": 962,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Old Sharlayan",
"AethernetShortcut": [
"[Old Sharlayan] Aetheryte Plaza",
"[Old Sharlayan] The Studium"
],
"RequiredGatheredItems": [
{
"ItemId": 35600,
"ItemCount": 6,
"Collectability": 600
}
],
"NextQuestId": 4155
}
]
}
]
}

View File

@ -0,0 +1,49 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"TerritoryId": 962,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"TerritoryId": 962,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Old Sharlayan",
"AethernetShortcut": [
"[Old Sharlayan] Aetheryte Plaza",
"[Old Sharlayan] The Studium"
],
"RequiredGatheredItems": [
{
"ItemId": 35601,
"ItemCount": 6,
"Collectability": 600
}
],
"NextQuestId": 4156
}
]
}
]
}

View File

@ -0,0 +1,49 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"TerritoryId": 962,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"TerritoryId": 962,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Old Sharlayan",
"AethernetShortcut": [
"[Old Sharlayan] Aetheryte Plaza",
"[Old Sharlayan] The Studium"
],
"RequiredGatheredItems": [
{
"ItemId": 35602,
"ItemCount": 6,
"Collectability": 600
}
],
"NextQuestId": 4157
}
]
}
]
}

View File

@ -0,0 +1,21 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1038501,
"Position": {
"X": -367.3305,
"Y": 21.846018,
"Z": -102.983154
},
"TerritoryId": 962,
"InteractionType": "AcceptQuest"
}
]
}
]
}

View File

@ -45,14 +45,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"Land": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1042372,
@ -84,14 +88,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"Land": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 1042371,
@ -123,14 +131,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"Land": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 1042373,

View File

@ -45,14 +45,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"Land": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2012887,
@ -84,14 +88,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"Land": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2012888,
@ -123,14 +131,18 @@
"InteractionType": "WalkTo",
"Fly": true,
"Land": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2012889,
@ -149,7 +161,7 @@
null,
null,
null,
-32
32
]
}
]

View File

@ -29,14 +29,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2012902,
@ -66,14 +70,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2012901,
@ -103,14 +111,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2012900,

View File

@ -30,14 +30,18 @@
"TerritoryId": 957,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2012907,

View File

@ -34,14 +34,18 @@
"[Radz-at-Han] The Gate of First Sight (Thavnair)"
],
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1042462,

View File

@ -1,7 +1,6 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"Disabled": true,
"QuestSequence": [
{
"Sequence": 0,
@ -21,7 +20,71 @@
{
"Sequence": 1,
"Steps": [
{
"DataId": 2012915,
"Position": {
"X": -383.505,
"Y": 1.0527954,
"Z": 362.99683
},
"TerritoryId": 957,
"InteractionType": "Combat",
"EnemySpawnType": "AfterInteraction",
"KillEnemyDataIds": [
14680
],
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
},
{
"DataId": 2012914,
"Position": {
"X": -399.83215,
"Y": 1.6326294,
"Z": 291.73718
},
"TerritoryId": 957,
"InteractionType": "Interact",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 2012913,
"Position": {
"X": -444.0528,
"Y": 0.38146973,
"Z": 249.53076
},
"TerritoryId": 957,
"InteractionType": "Combat",
"EnemySpawnType": "AfterInteraction",
"KillEnemyDataIds": [
14680
],
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
]
},
{

View File

@ -0,0 +1,134 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1042300,
"Position": {
"X": -76.82922,
"Y": 39.977543,
"Z": 309.98706
},
"TerritoryId": 957,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1042336,
"Position": {
"X": 409.964,
"Y": 18.253498,
"Z": -461.53967
},
"TerritoryId": 957,
"InteractionType": "Interact",
"AetheryteShortcut": "Thavnair - Palaka's Stand",
"Fly": true
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 2012970,
"Position": {
"X": 197.4364,
"Y": 9.323181,
"Z": -438.71216
},
"TerritoryId": 957,
"InteractionType": "Interact",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 2012924,
"Position": {
"X": 179.33923,
"Y": 7.309021,
"Z": -392.44684
},
"TerritoryId": 957,
"InteractionType": "Combat",
"EnemySpawnType": "AfterInteraction",
"KillEnemyDataIds": [
14683
],
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1042339,
"Position": {
"X": 145.95251,
"Y": 9.608223,
"Z": -234.24127
},
"TerritoryId": 957,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 4,
"Steps": [
{
"DataId": 1042343,
"Position": {
"X": 142.53455,
"Y": 10.132848,
"Z": -232.89844
},
"StopDistance": 7,
"TerritoryId": 957,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1042300,
"Position": {
"X": -76.82922,
"Y": 39.977543,
"Z": 309.98706
},
"TerritoryId": 957,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Thavnair - Yedlihmad",
"Fly": true
}
]
}
]
}

View File

@ -111,14 +111,18 @@
},
"DelaySeconds": 0.25
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-64
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
}
},
{
"DataId": 2014134,

View File

@ -0,0 +1,36 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1047095,
"Position": {
"X": 139.5437,
"Y": -13.99,
"Z": 10.60498
},
"TerritoryId": 1185,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1047095,
"Position": {
"X": 139.5437,
"Y": -13.99,
"Z": 10.60498
},
"TerritoryId": 1185,
"InteractionType": "CompleteQuest"
}
]
}
]
}

View File

@ -0,0 +1,36 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1047151,
"Position": {
"X": 130.2052,
"Y": -14,
"Z": 16.952698
},
"TerritoryId": 1185,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1047164,
"Position": {
"X": 217.21204,
"Y": -14,
"Z": -8.316223
},
"TerritoryId": 1185,
"InteractionType": "CompleteQuest"
}
]
}
]
}

View File

@ -0,0 +1,36 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1047132,
"Position": {
"X": 217.36475,
"Y": -14.000001,
"Z": -5.6916504
},
"TerritoryId": 1185,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1047132,
"Position": {
"X": 217.36475,
"Y": -14.000001,
"Z": -5.6916504
},
"TerritoryId": 1185,
"InteractionType": "CompleteQuest"
}
]
}
]
}

View File

@ -47,14 +47,18 @@
},
"TerritoryId": 1187,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 1046874,

View File

@ -142,14 +142,18 @@
"InteractionType": "WalkTo",
"DisableNavmesh": true,
"Mount": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2013653,
@ -177,14 +181,18 @@
},
"TerritoryId": 1189,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2013655,

View File

@ -113,14 +113,18 @@
},
"TerritoryId": 1191,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2013819,

View File

@ -131,14 +131,18 @@
},
"TerritoryId": 1192,
"InteractionType": "WalkTo",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-16
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
}
},
{
"DataId": 1047904,

View File

@ -29,14 +29,18 @@
"TerritoryId": 1191,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-128
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
}
},
{
"DataId": 2014091,
@ -85,14 +89,18 @@
"TerritoryId": 1191,
"InteractionType": "WalkTo",
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
"SkipConditions": {
"StepIf": {
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
}
},
{
"DataId": 2014093,

View File

@ -31,17 +31,17 @@
"Fly": true,
"SkipConditions": {
"StepIf": {
"Flying": "Locked"
"Flying": "Locked",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
},
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
-32
]
}
},
{
"DataId": 2014184,

Some files were not shown because too many files have changed in this diff Show More