forked from liza/Questionable
Load gathering points dynamically, BTN 65-70
This commit is contained in:
parent
e186d34f0d
commit
5c3584b88d
@ -52,6 +52,13 @@ internal sealed class EditorWindow : Window
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (!_clientState.IsLoggedIn || _clientState.LocalPlayer == null)
|
||||
{
|
||||
_target = null;
|
||||
_targetLocation = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_target = _targetManager.Target;
|
||||
var gatheringLocations = _plugin.GetLocationsInTerritory(_clientState.TerritoryType);
|
||||
var location = gatheringLocations.SelectMany(context =>
|
||||
@ -63,7 +70,7 @@ internal sealed class EditorWindow : Window
|
||||
if (_target != null)
|
||||
distance = Vector3.Distance(location.Position, _target.Position);
|
||||
else
|
||||
distance = Vector3.Distance(location.Position, _clientState.LocalPlayer!.Position);
|
||||
distance = Vector3.Distance(location.Position, _clientState.LocalPlayer.Position);
|
||||
|
||||
return new { Context = context, Node = node, Location = location, Distance = distance };
|
||||
})
|
||||
@ -86,7 +93,7 @@ internal sealed class EditorWindow : Window
|
||||
.Select(x => new
|
||||
{
|
||||
Object = x,
|
||||
Distance = Vector3.Distance(location.Location.Position, _clientState.LocalPlayer!.Position)
|
||||
Distance = Vector3.Distance(location.Location.Position, _clientState.LocalPlayer.Position)
|
||||
})
|
||||
.Where(x => x.Distance < 3f)
|
||||
.OrderBy(x => x.Distance)
|
||||
|
@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
|
||||
"Author": "liza",
|
||||
"TerritoryId": 621,
|
||||
"AetheryteShortcut": "Lochs - Porta Praetoria",
|
||||
"Groups": [
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32274,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -737.3265,
|
||||
"Y": 76.50858,
|
||||
"Z": -591.2296
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -787.0406,
|
||||
"Y": 78.22382,
|
||||
"Z": -640.0532
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -670.0129,
|
||||
"Y": 70.42876,
|
||||
"Z": -645.2087
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
|
||||
"Author": "liza",
|
||||
"TerritoryId": 613,
|
||||
"AetheryteShortcut": "Ruby Sea - Onokoro",
|
||||
"Groups": [
|
||||
{
|
||||
"Nodes": [
|
||||
|
@ -0,0 +1,133 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
|
||||
"Author": "liza",
|
||||
"TerritoryId": 613,
|
||||
"AetheryteShortcut": "Ruby Sea - Onokoro",
|
||||
"Groups": [
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32223,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -741.6174,
|
||||
"Y": 6.276045,
|
||||
"Z": -639.2435
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -724.2017,
|
||||
"Y": 2.514658,
|
||||
"Z": -647.5651
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32222,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -719.345,
|
||||
"Y": 2.520793,
|
||||
"Z": -645.692
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32218,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -664.7355,
|
||||
"Y": 15.23751,
|
||||
"Z": -801.2688
|
||||
},
|
||||
"MinimumAngle": -60,
|
||||
"MaximumAngle": 185
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32219,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -673.4941,
|
||||
"Y": 16.74037,
|
||||
"Z": -818.1156
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -677.8458,
|
||||
"Y": 15.77772,
|
||||
"Z": -809.6718
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -663.3188,
|
||||
"Y": 14.57053,
|
||||
"Z": -797.132
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32221,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -502.177,
|
||||
"Y": 36.7399,
|
||||
"Z": -724.8087
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -508.0492,
|
||||
"Y": 33.89026,
|
||||
"Z": -703.5477
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -490.3923,
|
||||
"Y": 36.73062,
|
||||
"Z": -685.7646
|
||||
},
|
||||
"MinimumAngle": -40,
|
||||
"MaximumAngle": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32220,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -493.5531,
|
||||
"Y": 36.08752,
|
||||
"Z": -687.7089
|
||||
},
|
||||
"MinimumAngle": -70,
|
||||
"MaximumAngle": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
|
||||
"Author": "liza",
|
||||
"TerritoryId": 613,
|
||||
"AetheryteShortcut": "Ruby Sea - Tamamizu",
|
||||
"Groups": [
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32225,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 283.2321,
|
||||
"Y": -105.8964,
|
||||
"Z": -89.553
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": 251.241,
|
||||
"Y": -112.7794,
|
||||
"Z": -103.9756
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": 338.0264,
|
||||
"Y": -86.76475,
|
||||
"Z": -30.31015
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32224,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 304.9474,
|
||||
"Y": -98.91968,
|
||||
"Z": -59.39315
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32228,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 260.0728,
|
||||
"Y": -124.0964,
|
||||
"Z": 68.48814
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32229,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 265.4464,
|
||||
"Y": -128.0422,
|
||||
"Z": 88.30737
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": 256.5239,
|
||||
"Y": -113.9164,
|
||||
"Z": -3.19258
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": 237.8169,
|
||||
"Y": -122.1193,
|
||||
"Z": -35.11102
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32226,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 318.7197,
|
||||
"Y": -88.4566,
|
||||
"Z": 91.66042
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32227,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 281.2504,
|
||||
"Y": -113.1205,
|
||||
"Z": 176.6557
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": 309.1248,
|
||||
"Y": -88.04077,
|
||||
"Z": 109.5688
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": 312.3843,
|
||||
"Y": -95.51873,
|
||||
"Z": 79.94166
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
|
||||
"Author": "liza",
|
||||
"TerritoryId": 613,
|
||||
"AetheryteShortcut": "Ruby Sea - Onokoro",
|
||||
"Groups": [
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32282,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -332.5556,
|
||||
"Y": -139.5151,
|
||||
"Z": -276.7727
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -398.5437,
|
||||
"Y": -137.4753,
|
||||
"Z": -264.6068
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32281,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -377.4165,
|
||||
"Y": -151.0521,
|
||||
"Z": -211.4394
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32277,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -509.283,
|
||||
"Y": -107.1854,
|
||||
"Z": -389.3152
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32278,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -470.5726,
|
||||
"Y": -93.28533,
|
||||
"Z": -430.0346
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -549.3453,
|
||||
"Y": -103.2194,
|
||||
"Z": -352.9945
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -548.5269,
|
||||
"Y": -99.45416,
|
||||
"Z": -459.6198
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 32279,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -347.0872,
|
||||
"Y": -72.09894,
|
||||
"Z": -420.7435
|
||||
},
|
||||
"MinimumAngle": -80,
|
||||
"MaximumAngle": 100
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 32280,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -410.6145,
|
||||
"Y": -86.76735,
|
||||
"Z": -432.2196
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -407.9324,
|
||||
"Y": -108.0931,
|
||||
"Z": -384.4449
|
||||
}
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -341.0429,
|
||||
"Y": -89.68655,
|
||||
"Z": -396.5815
|
||||
},
|
||||
"MinimumAngle": -45,
|
||||
"MaximumAngle": 110
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -16,13 +16,15 @@ public static partial class AssemblyGatheringLocationLoader
|
||||
if (_locations == null)
|
||||
{
|
||||
_locations = [];
|
||||
#if RELEASE
|
||||
LoadLocations();
|
||||
#endif
|
||||
}
|
||||
|
||||
return _locations ?? throw new InvalidOperationException("location data is not initialized");
|
||||
}
|
||||
|
||||
public static Stream QuestSchema =>
|
||||
public static Stream GatheringSchema =>
|
||||
typeof(AssemblyGatheringLocationLoader).Assembly.GetManifestResourceStream("Questionable.GatheringPaths.GatheringLocationSchema")!;
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
|
@ -26,7 +26,7 @@
|
||||
<AdditionalFiles Include="..\Questionable.Model\common-schema.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<None Remove="2.x - A Realm Reborn" />
|
||||
<None Remove="3.x - Heavensward" />
|
||||
<None Remove="4.x - Stormblood" />
|
||||
|
@ -0,0 +1,216 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021349,
|
||||
"Position": {
|
||||
"X": -43.930786,
|
||||
"Y": 209.23637,
|
||||
"Z": -90.77594
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Idyllshire",
|
||||
"AethernetShortcut": [
|
||||
"[Idyllshire] Aetheryte Plaza",
|
||||
"[Idyllshire] West Idyllshire"
|
||||
],
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1000815,
|
||||
"Position": {
|
||||
"X": -233.9361,
|
||||
"Y": 6.668152,
|
||||
"Z": -171.03839
|
||||
},
|
||||
"TerritoryId": 133,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Gridania",
|
||||
"AethernetShortcut": [
|
||||
"[Gridania] Aetheryte Plaza",
|
||||
"[Gridania] Botanists' Guild"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1002659,
|
||||
"Position": {
|
||||
"X": 532.8297,
|
||||
"Y": 88.99998,
|
||||
"Z": -72.09894
|
||||
},
|
||||
"TerritoryId": 135,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Limsa Lominsa",
|
||||
"AethernetShortcut": [
|
||||
"[Limsa Lominsa] Aetheryte Plaza",
|
||||
"[Limsa Lominsa] Tempest Gate (Lower La Noscea)"
|
||||
],
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InTerritory": [
|
||||
135
|
||||
]
|
||||
}
|
||||
},
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
64
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1002657,
|
||||
"Position": {
|
||||
"X": 540.52026,
|
||||
"Y": 89,
|
||||
"Z": -74.02161
|
||||
},
|
||||
"TerritoryId": 135,
|
||||
"InteractionType": "Interact",
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
128
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021353,
|
||||
"Position": {
|
||||
"X": 564.17163,
|
||||
"Y": 84.45213,
|
||||
"Z": -100.328125
|
||||
},
|
||||
"TerritoryId": 135,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019064,
|
||||
"Position": {
|
||||
"X": 59.220215,
|
||||
"Y": 4,
|
||||
"Z": 67.70422
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Kugane",
|
||||
"AethernetShortcut": [
|
||||
"[Kugane] Aetheryte Plaza",
|
||||
"[Kugane] Kogane Dori Markets"
|
||||
],
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
},
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
128
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1019065,
|
||||
"Position": {
|
||||
"X": 80.49133,
|
||||
"Y": 4,
|
||||
"Z": 56.443115
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "Interact",
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
64
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019233,
|
||||
"Position": {
|
||||
"X": -734.15735,
|
||||
"Y": 1.9602847,
|
||||
"Z": -611.38324
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ruby Sea - Onokoro",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021349,
|
||||
"Position": {
|
||||
"X": -43.930786,
|
||||
"Y": 209.23637,
|
||||
"Z": -90.77594
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Idyllshire",
|
||||
"AethernetShortcut": [
|
||||
"[Idyllshire] Aetheryte Plaza",
|
||||
"[Idyllshire] West Idyllshire"
|
||||
],
|
||||
"RequiredGatheredItems": [
|
||||
{
|
||||
"ItemId": 17946,
|
||||
"ItemCount": 20
|
||||
}
|
||||
],
|
||||
"NextQuestId": 2623
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021349,
|
||||
"Position": {
|
||||
"X": -43.930786,
|
||||
"Y": 209.23637,
|
||||
"Z": -90.77594
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Idyllshire",
|
||||
"AethernetShortcut": [
|
||||
"[Idyllshire] Aetheryte Plaza",
|
||||
"[Idyllshire] West Idyllshire"
|
||||
],
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1000815,
|
||||
"Position": {
|
||||
"X": -233.9361,
|
||||
"Y": 6.668152,
|
||||
"Z": -171.03839
|
||||
},
|
||||
"TerritoryId": 133,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Gridania",
|
||||
"AethernetShortcut": [
|
||||
"[Gridania] Aetheryte Plaza",
|
||||
"[Gridania] Botanists' Guild"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2008181,
|
||||
"Position": {
|
||||
"X": -46.31122,
|
||||
"Y": 209.49109,
|
||||
"Z": -86.35089
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Idyllshire",
|
||||
"AethernetShortcut": [
|
||||
"[Idyllshire] Aetheryte Plaza",
|
||||
"[Idyllshire] West Idyllshire"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2008181,
|
||||
"Position": {
|
||||
"X": -46.31122,
|
||||
"Y": 209.49109,
|
||||
"Z": -86.35089
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021349,
|
||||
"Position": {
|
||||
"X": -43.930786,
|
||||
"Y": 209.23637,
|
||||
"Z": -90.77594
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "Interact",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "List",
|
||||
"Prompt": "TEXT_CLSHRV680_02623_Q1_000_000",
|
||||
"Answer": "TEXT_CLSHRV680_02623_A1_000_002"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1017106,
|
||||
"Position": {
|
||||
"X": 73.99097,
|
||||
"Y": 214.12,
|
||||
"Z": -92.57648
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 6,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1017106,
|
||||
"Position": {
|
||||
"X": 73.99097,
|
||||
"Y": 214.12,
|
||||
"Z": -92.57648
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Idyllshire",
|
||||
"RequiredGatheredItems": [
|
||||
{
|
||||
"ItemId": 17947,
|
||||
"ItemCount": 20
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021349,
|
||||
"Position": {
|
||||
"X": -43.930786,
|
||||
"Y": 209.23637,
|
||||
"Z": -90.77594
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,184 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021349,
|
||||
"Position": {
|
||||
"X": -43.930786,
|
||||
"Y": 209.23637,
|
||||
"Z": -90.77594
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Idyllshire",
|
||||
"AethernetShortcut": [
|
||||
"[Idyllshire] Aetheryte Plaza",
|
||||
"[Idyllshire] West Idyllshire"
|
||||
],
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1000815,
|
||||
"Position": {
|
||||
"X": -233.9361,
|
||||
"Y": 6.668152,
|
||||
"Z": -171.03839
|
||||
},
|
||||
"TerritoryId": 133,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Gridania",
|
||||
"AethernetShortcut": [
|
||||
"[Gridania] Aetheryte Plaza",
|
||||
"[Gridania] Botanists' Guild"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021358,
|
||||
"Position": {
|
||||
"X": -599.54224,
|
||||
"Y": 130,
|
||||
"Z": -483.32953
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Fringes - Castrum Oriens"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021359,
|
||||
"Position": {
|
||||
"X": -262.25684,
|
||||
"Y": 256.97177,
|
||||
"Z": 695.52136
|
||||
},
|
||||
"TerritoryId": 620,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Peaks - Ala Ghiri"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021591,
|
||||
"Position": {
|
||||
"X": -277.82104,
|
||||
"Y": 258.90652,
|
||||
"Z": 782.77246
|
||||
},
|
||||
"TerritoryId": 620,
|
||||
"InteractionType": "Interact",
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
64
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1021595,
|
||||
"Position": {
|
||||
"X": -232.50171,
|
||||
"Y": 258.90652,
|
||||
"Z": 783.505
|
||||
},
|
||||
"TerritoryId": 620,
|
||||
"InteractionType": "Interact",
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
32
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1020870,
|
||||
"Position": {
|
||||
"X": -218.61603,
|
||||
"Y": 257.52652,
|
||||
"Z": 737.1786
|
||||
},
|
||||
"TerritoryId": 620,
|
||||
"InteractionType": "Interact",
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
128
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1022381,
|
||||
"Position": {
|
||||
"X": -243.12207,
|
||||
"Y": 257.52652,
|
||||
"Z": 744.0145
|
||||
},
|
||||
"TerritoryId": 620,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021349,
|
||||
"Position": {
|
||||
"X": -43.930786,
|
||||
"Y": 209.23637,
|
||||
"Z": -90.77594
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Idyllshire",
|
||||
"AethernetShortcut": [
|
||||
"[Idyllshire] Aetheryte Plaza",
|
||||
"[Idyllshire] West Idyllshire"
|
||||
],
|
||||
"Comment": "Eorzean Time: 4:00-5:59 AM/PM",
|
||||
"RequiredGatheredItems": [
|
||||
{
|
||||
"ItemId": 17948,
|
||||
"ItemCount": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -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": 1012299,
|
||||
"Position": {
|
||||
"X": -16.586609,
|
||||
"Y": 206.49942,
|
||||
"Z": 42.98462
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1018393,
|
||||
"Position": {
|
||||
"X": -60.380005,
|
||||
"Y": 206.50021,
|
||||
"Z": 26.16919
|
||||
},
|
||||
"TerritoryId": 478,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
<EmbeddedResource Include="quest-v1.json">
|
||||
<LogicalName>Questionable.QuestPaths.QuestSchema</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<AdditionalFiles Include="4.x - Stormblood\Class Quests\BTN\2623_The White Death.json" />
|
||||
<AdditionalFiles Include="quest-v1.json" />
|
||||
<AdditionalFiles Include="..\Questionable.Model\common-schema.json" />
|
||||
</ItemGroup>
|
||||
|
56
Questionable.Model/Gathering/GatheringPointId.cs
Normal file
56
Questionable.Model/Gathering/GatheringPointId.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Questionable.Model.Gathering;
|
||||
|
||||
public class GatheringPointId : IComparable<GatheringPointId>, IEquatable<GatheringPointId>
|
||||
{
|
||||
public GatheringPointId(ushort value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public ushort Value { get; }
|
||||
|
||||
public int CompareTo(GatheringPointId? other)
|
||||
{
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
if (ReferenceEquals(null, other)) return 1;
|
||||
return Value.CompareTo(other.Value);
|
||||
}
|
||||
|
||||
public bool Equals(GatheringPointId? other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return Value == other.Value;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((GatheringPointId)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(GatheringPointId? left, GatheringPointId? right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(GatheringPointId? left, GatheringPointId? right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
|
||||
public static GatheringPointId FromString(string value)
|
||||
{
|
||||
return new GatheringPointId(ushort.Parse(value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
@ -98,8 +98,9 @@ internal sealed class ContextMenuController : IDisposable
|
||||
var agentSatisfactionSupply = AgentSatisfactionSupply.Instance();
|
||||
if (agentSatisfactionSupply->IsAgentActive())
|
||||
{
|
||||
int maxTurnIns = agentSatisfactionSupply->NpcInfo.SatisfactionRank == 1 ? 3 : 6;
|
||||
quantityToGather = Math.Min(agentSatisfactionSupply->RemainingAllowances,
|
||||
((AgentSatisfactionSupply2*)agentSatisfactionSupply)->TurnInsToNextRank);
|
||||
((AgentSatisfactionSupply2*)agentSatisfactionSupply)->CalculateTurnInsToNextRank(maxTurnIns));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ namespace Questionable.Controller;
|
||||
internal sealed unsafe class GatheringController : MiniTaskController<GatheringController>
|
||||
{
|
||||
private readonly MovementController _movementController;
|
||||
private readonly GatheringPointRegistry _gatheringPointRegistry;
|
||||
private readonly GameFunctions _gameFunctions;
|
||||
private readonly NavmeshIpc _navmeshIpc;
|
||||
private readonly IObjectTable _objectTable;
|
||||
@ -33,6 +34,7 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
|
||||
|
||||
public GatheringController(
|
||||
MovementController movementController,
|
||||
GatheringPointRegistry gatheringPointRegistry,
|
||||
GameFunctions gameFunctions,
|
||||
NavmeshIpc navmeshIpc,
|
||||
IObjectTable objectTable,
|
||||
@ -43,6 +45,7 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
|
||||
: base(chatGui, logger)
|
||||
{
|
||||
_movementController = movementController;
|
||||
_gatheringPointRegistry = gatheringPointRegistry;
|
||||
_gameFunctions = gameFunctions;
|
||||
_navmeshIpc = navmeshIpc;
|
||||
_objectTable = objectTable;
|
||||
@ -52,8 +55,8 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
|
||||
|
||||
public bool Start(GatheringRequest gatheringRequest)
|
||||
{
|
||||
if (!AssemblyGatheringLocationLoader.GetLocations()
|
||||
.TryGetValue(gatheringRequest.GatheringPointId, out GatheringRoot? gatheringRoot))
|
||||
if (!_gatheringPointRegistry.TryGetGatheringPoint(gatheringRequest.GatheringPointId,
|
||||
out GatheringRoot? gatheringRoot))
|
||||
{
|
||||
_logger.LogError("Unable to resolve gathering point, no path found for {ItemId} / point {PointId}",
|
||||
gatheringRequest.ItemId, gatheringRequest.GatheringPointId);
|
||||
@ -190,7 +193,7 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
|
||||
}
|
||||
|
||||
public sealed record GatheringRequest(
|
||||
ushort GatheringPointId,
|
||||
GatheringPointId GatheringPointId,
|
||||
uint ItemId,
|
||||
int Quantity,
|
||||
ushort Collectability = 0);
|
||||
|
150
Questionable/Controller/GatheringPointRegistry.cs
Normal file
150
Questionable/Controller/GatheringPointRegistry.cs
Normal file
@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Dalamud.Plugin;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.GatheringPaths;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Gathering;
|
||||
|
||||
namespace Questionable.Controller;
|
||||
|
||||
internal sealed class GatheringPointRegistry : IDisposable
|
||||
{
|
||||
private readonly IDalamudPluginInterface _pluginInterface;
|
||||
private readonly QuestRegistry _questRegistry;
|
||||
private readonly ILogger<QuestRegistry> _logger;
|
||||
|
||||
private readonly Dictionary<GatheringPointId, GatheringRoot> _gatheringPoints = new();
|
||||
|
||||
public GatheringPointRegistry(IDalamudPluginInterface pluginInterface, QuestRegistry questRegistry,
|
||||
ILogger<QuestRegistry> logger)
|
||||
{
|
||||
_pluginInterface = pluginInterface;
|
||||
_questRegistry = questRegistry;
|
||||
_logger = logger;
|
||||
|
||||
_questRegistry.Reloaded += OnReloaded;
|
||||
}
|
||||
|
||||
private void OnReloaded(object? sender, EventArgs e) => Reload();
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
_gatheringPoints.Clear();
|
||||
|
||||
LoadGatheringPointsFromAssembly();
|
||||
LoadGatheringPointsFromProjectDirectory();
|
||||
|
||||
try
|
||||
{
|
||||
LoadFromDirectory(new DirectoryInfo(Path.Combine(_pluginInterface.ConfigDirectory.FullName, "GatheringPoints")));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e,
|
||||
"Failed to load gathering points from user directory (some may have been successfully loaded)");
|
||||
}
|
||||
|
||||
_logger.LogInformation("Loaded {Count} gathering points in total", _gatheringPoints.Count);
|
||||
}
|
||||
|
||||
[Conditional("RELEASE")]
|
||||
private void LoadGatheringPointsFromAssembly()
|
||||
{
|
||||
_logger.LogInformation("Loading gathering points from assembly");
|
||||
|
||||
foreach ((ushort gatheringPointId, GatheringRoot gatheringRoot) in
|
||||
AssemblyGatheringLocationLoader.GetLocations())
|
||||
{
|
||||
_gatheringPoints[new GatheringPointId(gatheringPointId)] = gatheringRoot;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Loaded {Count} gathering points from assembly", _gatheringPoints.Count);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void LoadGatheringPointsFromProjectDirectory()
|
||||
{
|
||||
DirectoryInfo? solutionDirectory = _pluginInterface.AssemblyLocation.Directory?.Parent?.Parent;
|
||||
if (solutionDirectory != null)
|
||||
{
|
||||
DirectoryInfo pathProjectDirectory =
|
||||
new DirectoryInfo(Path.Combine(solutionDirectory.FullName, "GatheringPaths"));
|
||||
if (pathProjectDirectory.Exists)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var expansionFolder in ExpansionData.ExpansionFolders.Values)
|
||||
LoadFromDirectory(
|
||||
new DirectoryInfo(Path.Combine(pathProjectDirectory.FullName, expansionFolder)),
|
||||
LogLevel.Trace);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_gatheringPoints.Clear();
|
||||
_logger.LogError(e, "Failed to load gathering points from project directory");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadGatheringPointFromStream(string fileName, Stream stream)
|
||||
{
|
||||
_logger.LogTrace("Loading gathering point from '{FileName}'", fileName);
|
||||
GatheringPointId? gatheringPointId = ExtractGatheringPointIdFromName(fileName);
|
||||
if (gatheringPointId == null)
|
||||
return;
|
||||
|
||||
_gatheringPoints[gatheringPointId] = JsonSerializer.Deserialize<GatheringRoot>(stream)!;
|
||||
}
|
||||
|
||||
private void LoadFromDirectory(DirectoryInfo directory, LogLevel logLevel = LogLevel.Information)
|
||||
{
|
||||
if (!directory.Exists)
|
||||
{
|
||||
_logger.LogInformation("Not loading gathering points from {DirectoryName} (doesn't exist)", directory);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Log(logLevel, "Loading gathering points from {DirectoryName}", directory);
|
||||
foreach (FileInfo fileInfo in directory.GetFiles("*.json"))
|
||||
{
|
||||
try
|
||||
{
|
||||
using FileStream stream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);
|
||||
LoadGatheringPointFromStream(fileInfo.Name, stream);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new InvalidDataException($"Unable to load file {fileInfo.FullName}", e);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo childDirectory in directory.GetDirectories())
|
||||
LoadFromDirectory(childDirectory, logLevel);
|
||||
}
|
||||
|
||||
private static GatheringPointId? ExtractGatheringPointIdFromName(string resourceName)
|
||||
{
|
||||
string name = resourceName.Substring(0, resourceName.Length - ".json".Length);
|
||||
name = name.Substring(name.LastIndexOf('.') + 1);
|
||||
|
||||
if (!name.Contains('_', StringComparison.Ordinal))
|
||||
return null;
|
||||
|
||||
string[] parts = name.Split('_', 2);
|
||||
return GatheringPointId.FromString(parts[0]);
|
||||
}
|
||||
|
||||
public bool TryGetGatheringPoint(GatheringPointId gatheringPointId, [NotNullWhen(true)] out GatheringRoot? gatheringRoot)
|
||||
=> _gatheringPoints.TryGetValue(gatheringPointId, out gatheringRoot);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_questRegistry.Reloaded -= OnReloaded;
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ internal sealed class MovementOverrideController
|
||||
[
|
||||
new BlacklistedArea(1191, new(-223.0412f, 31.937134f, -584.03906f), 5f, 7.75f),
|
||||
|
||||
// limsa, aftcastle to baderon
|
||||
// limsa, aftcastle to Baderon
|
||||
new BlacklistedPoint(128, new(2f, 40.25f, 36.5f), new(0.25f, 40.25f, 36.5f)),
|
||||
|
||||
// New Gridania, Carline Canopy stairs
|
||||
@ -28,7 +28,7 @@ internal sealed class MovementOverrideController
|
||||
new BlacklistedPoint(132, new(45.5f, -8f, 101f), new(50.53978f, -8.046954f, 101.06045f)),
|
||||
new BlacklistedPoint(132, new(48.5f, -8f, 98.25f), new(50.53978f, -8.046954f, 101.06045f)),
|
||||
|
||||
// ul'dah lamp near adventuer's guild
|
||||
// ul'dah lamp near adventurers' guild
|
||||
new BlacklistedPoint(130, new(59.5f, 4.25f, -118f), new(60.551353f, 4f, -119.76446f)),
|
||||
|
||||
// eastern thanalan
|
||||
@ -37,7 +37,7 @@ internal sealed class MovementOverrideController
|
||||
// southern thanalan
|
||||
new BlacklistedPoint(146, new(-201.75f, 10.5f, -265.5f), new(-203.75235f, 10.130764f, -265.15314f)),
|
||||
|
||||
// lower la noscea - moraby drydocks aetheryte
|
||||
// lower la noscea - Moraby Drydocks aetheryte
|
||||
new BlacklistedArea(135, new(156.11499f, 15.518433f, 673.21277f), 0.5f, 5f),
|
||||
|
||||
// coerthas central highlands
|
||||
@ -55,9 +55,13 @@ internal sealed class MovementOverrideController
|
||||
// moghome, mogmug's trial
|
||||
new BlacklistedPoint(400, new(384, -74, 648.75f), new(386.0543f, -72.409454f, 652.0184f), 3),
|
||||
|
||||
// leaving idyllshiret through the west gate attempts to run into this wall
|
||||
// leaving Idyllshire through the west gate attempts to run into this wall
|
||||
new BlacklistedPoint(399, new(-514.4851f, 149.63762f, -480.58087f), new(-528.78656f, 151.17374f, -473.07077f), 5, true),
|
||||
|
||||
// Idyllshire: random rocks in the north, passable one way only
|
||||
new BlacklistedPoint(478, new(14.5f, 215.25f, -101.5f), new(18.133032f, 215.44998f, -107.83075f), 5),
|
||||
new BlacklistedPoint(478, new(11, 215.5f, -104.5f), new(18.133032f, 215.44998f, -107.83075f), 5),
|
||||
|
||||
new BlacklistedPoint(1189, new(574f, -142.25f, 504.25f), new(574.44183f, -142.12766f, 507.60065f)),
|
||||
|
||||
// kholusia, random rocks
|
||||
@ -66,7 +70,7 @@ internal sealed class MovementOverrideController
|
||||
// yak t'el, rock near cenote jayunja
|
||||
new BlacklistedPoint(1189, new(-115.75f, -213.75f, 336.5f), new(-112.40265f, -215.01514f, 339.0067f), 2),
|
||||
|
||||
// sheshenewezi springs aetheryte: couple of barrel rings that get in the way if you go north
|
||||
// sheshenewezi springs aetheryte: a couple of barrel rings that get in the way if you go north
|
||||
new BlacklistedPoint(1190, new(-292.29004f, 18.598045f, -133.83907f), new(-288.20895f, 18.652182f, -132.67445f),
|
||||
4),
|
||||
|
||||
|
@ -19,6 +19,7 @@ internal static class GatheringRequiredItems
|
||||
internal sealed class Factory(
|
||||
IServiceProvider serviceProvider,
|
||||
MovementController movementController,
|
||||
GatheringPointRegistry gatheringPointRegistry,
|
||||
IClientState clientState,
|
||||
GatheringData gatheringData,
|
||||
TerritoryData territoryData,
|
||||
@ -34,11 +35,10 @@ internal static class GatheringRequiredItems
|
||||
classJob = (EClassJob)requiredGatheredItems.ClassJob.Value;
|
||||
|
||||
if (!gatheringData.TryGetGatheringPointId(requiredGatheredItems.ItemId, classJob,
|
||||
out var gatheringPointId))
|
||||
out GatheringPointId? gatheringPointId))
|
||||
throw new TaskException($"No gathering point found for item {requiredGatheredItems.ItemId}");
|
||||
|
||||
if (!AssemblyGatheringLocationLoader.GetLocations()
|
||||
.TryGetValue(gatheringPointId, out GatheringRoot? gatheringRoot))
|
||||
if (!gatheringPointRegistry.TryGetGatheringPoint(gatheringPointId, out GatheringRoot? gatheringRoot))
|
||||
throw new TaskException($"No path found for gathering point {gatheringPointId}");
|
||||
|
||||
if (classJob != currentClassJob)
|
||||
@ -92,10 +92,10 @@ internal static class GatheringRequiredItems
|
||||
|
||||
internal sealed class StartGathering(GatheringController gatheringController) : ITask
|
||||
{
|
||||
private ushort _gatheringPointId;
|
||||
private GatheringPointId _gatheringPointId = null!;
|
||||
private GatheredItem _gatheredItem = null!;
|
||||
|
||||
public ITask With(ushort gatheringPointId, GatheredItem gatheredItem)
|
||||
public ITask With(GatheringPointId gatheringPointId, GatheredItem gatheredItem)
|
||||
{
|
||||
_gatheringPointId = gatheringPointId;
|
||||
_gatheredItem = gatheredItem;
|
||||
|
@ -1,16 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Dalamud.Plugin.Services;
|
||||
using LLib.GameData;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Model.Gathering;
|
||||
|
||||
namespace Questionable.Data;
|
||||
|
||||
internal sealed class GatheringData
|
||||
{
|
||||
private readonly Dictionary<uint, ushort> _minerGatheringPoints = [];
|
||||
private readonly Dictionary<uint, ushort> _botanistGatheringPoints = [];
|
||||
private readonly Dictionary<uint, GatheringPointId> _minerGatheringPoints = [];
|
||||
private readonly Dictionary<uint, GatheringPointId> _botanistGatheringPoints = [];
|
||||
private readonly Dictionary<uint, ushort> _itemIdToCollectability;
|
||||
private readonly Dictionary<uint, uint> _npcForCustomDeliveries;
|
||||
|
||||
@ -27,9 +29,9 @@ internal sealed class GatheringData
|
||||
if (gatheringItemToItem.TryGetValue((uint)gatheringItemId, out uint itemId))
|
||||
{
|
||||
if (gatheringPointBase.GatheringType.Row is 0 or 1)
|
||||
_minerGatheringPoints[itemId] = (ushort)gatheringPointBase.RowId;
|
||||
_minerGatheringPoints[itemId] = new GatheringPointId((ushort)gatheringPointBase.RowId);
|
||||
else if (gatheringPointBase.GatheringType.Row is 2 or 3)
|
||||
_botanistGatheringPoints[itemId] = (ushort)gatheringPointBase.RowId;
|
||||
_botanistGatheringPoints[itemId] = new GatheringPointId((ushort)gatheringPointBase.RowId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,7 +61,8 @@ internal sealed class GatheringData
|
||||
.ToDictionary(x => x.ItemId, x => x.NpcId);
|
||||
}
|
||||
|
||||
public bool TryGetGatheringPointId(uint itemId, EClassJob classJobId, out ushort gatheringPointId)
|
||||
public bool TryGetGatheringPointId(uint itemId, EClassJob classJobId,
|
||||
[NotNullWhen(true)] out GatheringPointId? gatheringPointId)
|
||||
{
|
||||
if (classJobId == EClassJob.Miner)
|
||||
return _minerGatheringPoints.TryGetValue(itemId, out gatheringPointId);
|
||||
@ -67,7 +70,7 @@ internal sealed class GatheringData
|
||||
return _botanistGatheringPoints.TryGetValue(itemId, out gatheringPointId);
|
||||
else
|
||||
{
|
||||
gatheringPointId = 0;
|
||||
gatheringPointId = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
|
@ -15,14 +15,11 @@ internal struct AgentSatisfactionSupply2
|
||||
[FieldOffset(0x70)] public ushort CurrentSatisfaction;
|
||||
[FieldOffset(0x72)] public ushort MaxSatisfaction;
|
||||
|
||||
public int TurnInsToNextRank
|
||||
public int CalculateTurnInsToNextRank(int maxTurnIns)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (MaxSatisfaction == 0)
|
||||
return 6;
|
||||
if (MaxSatisfaction == 0)
|
||||
return maxTurnIns;
|
||||
|
||||
return 6 * (MaxSatisfaction - CurrentSatisfaction) / MaxSatisfaction;
|
||||
}
|
||||
return maxTurnIns * (MaxSatisfaction - CurrentSatisfaction) / MaxSatisfaction;
|
||||
}
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
||||
{
|
||||
serviceCollection.AddSingleton<MovementController>();
|
||||
serviceCollection.AddSingleton<MovementOverrideController>();
|
||||
serviceCollection.AddSingleton<GatheringPointRegistry>();
|
||||
serviceCollection.AddSingleton<QuestRegistry>();
|
||||
serviceCollection.AddSingleton<QuestController>();
|
||||
serviceCollection.AddSingleton<GameUiController>();
|
||||
@ -211,6 +212,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
||||
private static void Initialize(IServiceProvider serviceProvider)
|
||||
{
|
||||
serviceProvider.GetRequiredService<QuestRegistry>().Reload();
|
||||
serviceProvider.GetRequiredService<GatheringPointRegistry>().Reload();
|
||||
serviceProvider.GetRequiredService<CommandHandler>();
|
||||
serviceProvider.GetRequiredService<ContextMenuController>();
|
||||
serviceProvider.GetRequiredService<DalamudInitializer>();
|
||||
|
Loading…
Reference in New Issue
Block a user