forked from liza/Questionable
Compare commits
10 Commits
5375ec25bc
...
f4ff18e9f4
Author | SHA1 | Date | |
---|---|---|---|
f4ff18e9f4 | |||
8aaabacc2d | |||
b5f66bb9e8 | |||
7ca783bade | |||
034d2704e9 | |||
440a746e46 | |||
9c414d44cd | |||
fb3aa0e0d4 | |||
2d22657d41 | |||
9be1579f99 |
@ -1,5 +1,5 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>2.11</Version>
|
||||
<Version>2.13</Version>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
@ -238,8 +238,10 @@ public sealed class RendererPlugin : IDalamudPlugin
|
||||
maximumAngle = x.MaximumAngle.GetValueOrDefault();
|
||||
}
|
||||
|
||||
#if false
|
||||
var a = GatheringMath.CalculateLandingLocation(x, 0, 0);
|
||||
var b = GatheringMath.CalculateLandingLocation(x, 1, 1);
|
||||
#endif
|
||||
return new List<Element>
|
||||
{
|
||||
new Element(isCone
|
||||
|
78
GatheringPaths/6.x - Endwalker/Elysion/319__MIN.json
Normal file
78
GatheringPaths/6.x - Endwalker/Elysion/319__MIN.json
Normal file
@ -0,0 +1,78 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
|
||||
"Author": "liza",
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2013074,
|
||||
"Position": {
|
||||
"X": 304.3412,
|
||||
"Y": 483.48206,
|
||||
"Z": 143.11438
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 1073,
|
||||
"SkipConditions": {
|
||||
"StepIf": {
|
||||
"InTerritory": [
|
||||
1073
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"TerritoryId": 1073,
|
||||
"InteractionType": "None"
|
||||
}
|
||||
],
|
||||
"Groups": [
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 33840,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 10.28351,
|
||||
"Y": 486.144,
|
||||
"Z": -136.9586
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 33841,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 19.46428,
|
||||
"Y": 485.9226,
|
||||
"Z": -136.738
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 33643,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 14.21117,
|
||||
"Y": 486.0551,
|
||||
"Z": -143.435
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
78
GatheringPaths/6.x - Endwalker/Elysion/396__BTN.json
Normal file
78
GatheringPaths/6.x - Endwalker/Elysion/396__BTN.json
Normal file
@ -0,0 +1,78 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
|
||||
"Author": "liza",
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2013074,
|
||||
"Position": {
|
||||
"X": 304.3412,
|
||||
"Y": 483.48206,
|
||||
"Z": 143.11438
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 1073,
|
||||
"SkipConditions": {
|
||||
"StepIf": {
|
||||
"InTerritory": [
|
||||
1073
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"TerritoryId": 1073,
|
||||
"InteractionType": "None"
|
||||
}
|
||||
],
|
||||
"Groups": [
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 34350,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 18.9518,
|
||||
"Y": 485.9131,
|
||||
"Z": -133.3762
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 34351,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 15.71416,
|
||||
"Y": 486.0302,
|
||||
"Z": -136.2497
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"DataId": 34349,
|
||||
"Locations": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 9.524881,
|
||||
"Y": 486.2234,
|
||||
"Z": -142.2316
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -114,7 +114,7 @@
|
||||
},
|
||||
"TerritoryId": 401,
|
||||
"InteractionType": "Action",
|
||||
"Action": "Buffet",
|
||||
"Action": "Buffet (Sanuwa)",
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
@ -134,7 +134,7 @@
|
||||
},
|
||||
"TerritoryId": 401,
|
||||
"InteractionType": "Action",
|
||||
"Action": "Buffet",
|
||||
"Action": "Buffet (Sanuwa)",
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
@ -154,7 +154,7 @@
|
||||
},
|
||||
"TerritoryId": 401,
|
||||
"InteractionType": "Action",
|
||||
"Action": "Buffet",
|
||||
"Action": "Buffet (Sanuwa)",
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"Disabled": true,
|
||||
"$": "TODO Check if this is a sp1ecial mount that can always fly",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
@ -22,7 +22,61 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
{
|
||||
"DataId": 1024775,
|
||||
"Position": {
|
||||
"X": -35.599304,
|
||||
"Y": 55.9782,
|
||||
"Z": 214.58752
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025170,
|
||||
"Position": {
|
||||
"X": 253.10132,
|
||||
"Y": 45.434376,
|
||||
"Z": 416.98328
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "Action",
|
||||
"Action": "Buffet (Griffin)",
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
128
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1025171,
|
||||
"Position": {
|
||||
"X": 349.8435,
|
||||
"Y": 51.839485,
|
||||
"Z": 229.66345
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "Action",
|
||||
"Action": "Buffet (Griffin)",
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
64
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -48,7 +102,7 @@
|
||||
"StopDistance": 7,
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"Fly": true
|
||||
"Mount": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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,
|
||||
@ -22,7 +21,20 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
{
|
||||
"Position": {
|
||||
"X": -50.436653,
|
||||
"Y": 41.158955,
|
||||
"Z": -264.4358
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "Instruction",
|
||||
"Comment": "Use item on enemy, then kill it",
|
||||
"EnemySpawnType": "AutoOnEnterArea",
|
||||
"KillEnemyDataIds": [
|
||||
7030
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -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,
|
||||
@ -22,7 +21,126 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
{
|
||||
"DataId": 2009344,
|
||||
"Position": {
|
||||
"X": 101.304565,
|
||||
"Y": 41.031494,
|
||||
"Z": -180.89569
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "WaitForManualProgress",
|
||||
"Comment": "Kill enemy, then use item",
|
||||
"ItemId": 2002439,
|
||||
"EnemySpawnType": "AfterItemUse",
|
||||
"KillEnemyDataIds": [
|
||||
8591
|
||||
],
|
||||
"Fly": true,
|
||||
"RequiredQuestVariables": [
|
||||
null,
|
||||
null,
|
||||
[
|
||||
{
|
||||
"Low": 2
|
||||
},
|
||||
{
|
||||
"Low": 3
|
||||
}
|
||||
],
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
128
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 2009345,
|
||||
"Position": {
|
||||
"X": 136.40039,
|
||||
"Y": 50.369995,
|
||||
"Z": -397.69592
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "WaitForManualProgress",
|
||||
"Comment": "Kill enemy, then use item",
|
||||
"ItemId": 2002439,
|
||||
"EnemySpawnType": "AfterItemUse",
|
||||
"KillEnemyDataIds": [
|
||||
8591
|
||||
],
|
||||
"Fly": true,
|
||||
"RequiredQuestVariables": [
|
||||
null,
|
||||
null,
|
||||
[
|
||||
{
|
||||
"Low": 1
|
||||
},
|
||||
{
|
||||
"Low": 3
|
||||
}
|
||||
],
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
64
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 2009346,
|
||||
"Position": {
|
||||
"X": 12.588623,
|
||||
"Y": 41.672363,
|
||||
"Z": -294.02612
|
||||
},
|
||||
"TerritoryId": 612,
|
||||
"InteractionType": "WaitForManualProgress",
|
||||
"Comment": "Kill enemy, then use item",
|
||||
"ItemId": 2002439,
|
||||
"EnemySpawnType": "AfterItemUse",
|
||||
"KillEnemyDataIds": [
|
||||
8591
|
||||
],
|
||||
"Fly": true,
|
||||
"RequiredQuestVariables": [
|
||||
null,
|
||||
null,
|
||||
[
|
||||
{
|
||||
"Low": 1
|
||||
},
|
||||
{
|
||||
"Low": 2
|
||||
}
|
||||
],
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
32
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -0,0 +1,6 @@
|
||||
```
|
||||
0 0 xx 0 0 0 | 2009344 2009345 2009346
|
||||
33 x x | unconfirmed
|
||||
34 x x
|
||||
35 x x
|
||||
```
|
@ -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,
|
||||
|
@ -0,0 +1,70 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019468,
|
||||
"Position": {
|
||||
"X": 170.58057,
|
||||
"Y": 13.02367,
|
||||
"Z": -91.96619
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Rhalgr's Reach",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024136,
|
||||
"Position": {
|
||||
"X": -29.34314,
|
||||
"Y": -0.1424195,
|
||||
"Z": -124.52893
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -63.63005,
|
||||
"Y": -0.0012056828,
|
||||
"Z": -101.09714
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "WalkTo"
|
||||
},
|
||||
{
|
||||
"DataId": 2009050,
|
||||
"Position": {
|
||||
"X": 49.66809,
|
||||
"Y": -0.015319824,
|
||||
"Z": 58.182617
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AethernetShortcut": [
|
||||
"[Rhalgr's Reach] Western Rhalgr's Reach",
|
||||
"[Rhalgr's Reach] Aetheryte Plaza"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024137,
|
||||
"Position": {
|
||||
"X": 47.77588,
|
||||
"Y": 0,
|
||||
"Z": 58.64038
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Rhalgr's Reach",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024130,
|
||||
"Position": {
|
||||
"X": 614.61804,
|
||||
"Y": 80.000015,
|
||||
"Z": 624.567
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter",
|
||||
"$": "QW: 0 0 0 0 0 0 -> QW: 1 0 0 0 0 128"
|
||||
},
|
||||
{
|
||||
"DataId": 1024131,
|
||||
"Position": {
|
||||
"X": 585.3512,
|
||||
"Y": 70,
|
||||
"Z": 564.0801
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"$": "QW: 1 0 0 0 0 128 -> QW: 2 0 0 0 0 192",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1024132,
|
||||
"Position": {
|
||||
"X": 683.71094,
|
||||
"Y": 70,
|
||||
"Z": 540.5508
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024133,
|
||||
"Position": {
|
||||
"X": 745.20483,
|
||||
"Y": 69.99999,
|
||||
"Z": 489.76868
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024103,
|
||||
"Position": {
|
||||
"X": 532.494,
|
||||
"Y": 70,
|
||||
"Z": 576.1653
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024104,
|
||||
"Position": {
|
||||
"X": 530.81555,
|
||||
"Y": 70,
|
||||
"Z": 576.0128
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024134,
|
||||
"Position": {
|
||||
"X": 207.84314,
|
||||
"Y": -0.3,
|
||||
"Z": 338.55188
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 196.67705,
|
||||
"Y": -0.6,
|
||||
"Z": 318.12054
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Dive",
|
||||
"StopDistance": 0.25
|
||||
},
|
||||
{
|
||||
"DataId": 2009052,
|
||||
"Position": {
|
||||
"X": 144.97595,
|
||||
"Y": -270.98505,
|
||||
"Z": -12.283508
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009054,
|
||||
"Position": {
|
||||
"X": 258.19788,
|
||||
"Y": -274.06738,
|
||||
"Z": -12.588745
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Duty",
|
||||
"ContentFinderConditionId": 279
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024104,
|
||||
"Position": {
|
||||
"X": 530.81555,
|
||||
"Y": 70,
|
||||
"Z": 576.0128
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024103,
|
||||
"Position": {
|
||||
"X": 532.494,
|
||||
"Y": 70,
|
||||
"Z": 576.1653
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024105,
|
||||
"Position": {
|
||||
"X": 739.22327,
|
||||
"Y": 70,
|
||||
"Z": 537.6515
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024107,
|
||||
"Position": {
|
||||
"X": 788.3878,
|
||||
"Y": 69.999916,
|
||||
"Z": 637.3845
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024112,
|
||||
"Position": {
|
||||
"X": 796.933,
|
||||
"Y": 69.9999,
|
||||
"Z": 634.76
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024125,
|
||||
"Position": {
|
||||
"X": 775.6007,
|
||||
"Y": 69.99993,
|
||||
"Z": 639.4292
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024113,
|
||||
"Position": {
|
||||
"X": 754.26855,
|
||||
"Y": 70,
|
||||
"Z": 424.70435
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024114,
|
||||
"Position": {
|
||||
"X": 5.2338257,
|
||||
"Y": 0.054396715,
|
||||
"Z": -3.3417358
|
||||
},
|
||||
"TerritoryId": 738,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -2.9216702,
|
||||
"Y": -2.0000002,
|
||||
"Z": -34.863174
|
||||
},
|
||||
"TerritoryId": 738,
|
||||
"InteractionType": "Jump",
|
||||
"JumpDestination": {
|
||||
"Position": {
|
||||
"X": -2.9769177,
|
||||
"Y": -1.3092512,
|
||||
"Z": -36.29651
|
||||
}
|
||||
},
|
||||
"StopDistance": 0.25
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -2.9769177,
|
||||
"Y": -1.3092512,
|
||||
"Z": -36.29651
|
||||
},
|
||||
"TerritoryId": 738,
|
||||
"InteractionType": "Jump",
|
||||
"JumpDestination": {
|
||||
"Position": {
|
||||
"X": -2.8188858,
|
||||
"Y": 0.16235979,
|
||||
"Z": -38.626305
|
||||
}
|
||||
},
|
||||
"StopDistance": 0.25
|
||||
},
|
||||
{
|
||||
"DataId": 2009058,
|
||||
"Position": {
|
||||
"X": -2.8188858,
|
||||
"Y": 0.16235979,
|
||||
"Z": -38.626305
|
||||
},
|
||||
"TerritoryId": 738,
|
||||
"InteractionType": "Interact",
|
||||
"StopDistance": 4,
|
||||
"$": "QW: 0 0 0 0 0 0 -> QW: 16 16 0 0 0 128"
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -0.01923807,
|
||||
"Y": -2.0000002,
|
||||
"Z": -35.31207
|
||||
},
|
||||
"TerritoryId": 738,
|
||||
"InteractionType": "WalkTo",
|
||||
"DisableNavmesh": true
|
||||
},
|
||||
{
|
||||
"DataId": 1024118,
|
||||
"Position": {
|
||||
"X": 24.612793,
|
||||
"Y": -0.3670061,
|
||||
"Z": 5.0201416
|
||||
},
|
||||
"TerritoryId": 738,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024114,
|
||||
"Position": {
|
||||
"X": 5.2338257,
|
||||
"Y": 0.054396715,
|
||||
"Z": -3.3417358
|
||||
},
|
||||
"TerritoryId": 738,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024119,
|
||||
"Position": {
|
||||
"X": 758.6632,
|
||||
"Y": 70,
|
||||
"Z": 446.31104
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024120,
|
||||
"Position": {
|
||||
"X": 757.68665,
|
||||
"Y": 70,
|
||||
"Z": 444.3275
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1001821,
|
||||
"Position": {
|
||||
"X": -24.124573,
|
||||
"Y": 38.000004,
|
||||
"Z": 85.31323
|
||||
},
|
||||
"TerritoryId": 131,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ul'dah",
|
||||
"AethernetShortcut": [
|
||||
"[Ul'dah] Aetheryte Plaza",
|
||||
"[Ul'dah] The Chamber of Rule"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024122,
|
||||
"Position": {
|
||||
"X": 57.968994,
|
||||
"Y": 4,
|
||||
"Z": -121.53815
|
||||
},
|
||||
"TerritoryId": 130,
|
||||
"InteractionType": "Interact",
|
||||
"AethernetShortcut": [
|
||||
"[Ul'dah] The Chamber of Rule",
|
||||
"[Ul'dah] Adventurers' Guild"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024123,
|
||||
"Position": {
|
||||
"X": -132.9519,
|
||||
"Y": 4.590753,
|
||||
"Z": 238.7273
|
||||
},
|
||||
"TerritoryId": 141,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"AethernetShortcut": [
|
||||
"[Ul'dah] Adventurers' Guild",
|
||||
"[Ul'dah] Gate of Nald (Central Thanalan)"
|
||||
],
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "List",
|
||||
"Prompt": "TEXT_STMBDB106_02967_Q1_000_000",
|
||||
"Answer": "TEXT_STMBDB106_02967_A1_000_002"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024124,
|
||||
"Position": {
|
||||
"X": 254.35254,
|
||||
"Y": -6.26633,
|
||||
"Z": -152.36133
|
||||
},
|
||||
"TerritoryId": 141,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"AetheryteShortcut": "Central Thanalan - Black Brush Station"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024102,
|
||||
"Position": {
|
||||
"X": -105.7298,
|
||||
"Y": 6.9839897,
|
||||
"Z": -4.135254
|
||||
},
|
||||
"TerritoryId": 131,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ul'dah",
|
||||
"AethernetShortcut": [
|
||||
"[Ul'dah] Aetheryte Plaza",
|
||||
"[Ul'dah] Gladiators' Guild"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024102,
|
||||
"Position": {
|
||||
"X": -105.7298,
|
||||
"Y": 6.9839897,
|
||||
"Z": -4.135254
|
||||
},
|
||||
"TerritoryId": 131,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
116
QuestPaths/4.x - Stormblood/MSQ/B-4.1/2968_A Sultana's Duty.json
Normal file
116
QuestPaths/4.x - Stormblood/MSQ/B-4.1/2968_A Sultana's Duty.json
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024102,
|
||||
"Position": {
|
||||
"X": -105.7298,
|
||||
"Y": 6.9839897,
|
||||
"Z": -4.135254
|
||||
},
|
||||
"TerritoryId": 131,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024040,
|
||||
"Position": {
|
||||
"X": -201.06812,
|
||||
"Y": 18,
|
||||
"Z": 78.62964
|
||||
},
|
||||
"TerritoryId": 130,
|
||||
"InteractionType": "Interact",
|
||||
"AethernetShortcut": [
|
||||
"[Ul'dah] Gladiators' Guild",
|
||||
"[Ul'dah] Thaumaturges' Guild"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024041,
|
||||
"Position": {
|
||||
"X": -22.781738,
|
||||
"Y": 83.19999,
|
||||
"Z": -7.5532227
|
||||
},
|
||||
"TerritoryId": 130,
|
||||
"InteractionType": "Interact",
|
||||
"AethernetShortcut": [
|
||||
"[Ul'dah] Thaumaturges' Guild",
|
||||
"[Ul'dah] Airship Landing"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1004433,
|
||||
"Position": {
|
||||
"X": -23.605713,
|
||||
"Y": 83.19999,
|
||||
"Z": -2.3041382
|
||||
},
|
||||
"TerritoryId": 130,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 144
|
||||
},
|
||||
{
|
||||
"DataId": 1024042,
|
||||
"Position": {
|
||||
"X": -51.682373,
|
||||
"Y": 0.04428002,
|
||||
"Z": 53.94055
|
||||
},
|
||||
"TerritoryId": 144,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 12.5078335,
|
||||
"Y": 4.1552944,
|
||||
"Z": 45.718685
|
||||
},
|
||||
"TerritoryId": 144,
|
||||
"InteractionType": "Jump",
|
||||
"JumpDestination": {
|
||||
"Position": {
|
||||
"X": 12.60962,
|
||||
"Y": 4.2181597,
|
||||
"Z": 49.651253
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"DataId": 1024043,
|
||||
"Position": {
|
||||
"X": -12.77179,
|
||||
"Y": 20.999727,
|
||||
"Z": 47.837036
|
||||
},
|
||||
"TerritoryId": 144,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024043,
|
||||
"Position": {
|
||||
"X": -12.77179,
|
||||
"Y": 20.999727,
|
||||
"Z": 47.837036
|
||||
},
|
||||
"TerritoryId": 144,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Gold Saucer",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019070,
|
||||
"Position": {
|
||||
"X": 151.20166,
|
||||
"Y": 14.7757225,
|
||||
"Z": 95.78088
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 639,
|
||||
"AetheryteShortcut": "Kugane",
|
||||
"AethernetShortcut": [
|
||||
"[Kugane] Aetheryte Plaza",
|
||||
"[Kugane] The Ruby Bazaar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1020622,
|
||||
"Position": {
|
||||
"X": 0.045776367,
|
||||
"Y": 0,
|
||||
"Z": -2.3041382
|
||||
},
|
||||
"TerritoryId": 639,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024044,
|
||||
"Position": {
|
||||
"X": -110.36853,
|
||||
"Y": 4,
|
||||
"Z": -114.00018
|
||||
},
|
||||
"TerritoryId": 130,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ul'dah"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024045,
|
||||
"Position": {
|
||||
"X": -2.822998,
|
||||
"Y": -2.0000012,
|
||||
"Z": -17.166443
|
||||
},
|
||||
"TerritoryId": 212,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024045,
|
||||
"Position": {
|
||||
"X": -2.822998,
|
||||
"Y": -2.0000012,
|
||||
"Z": -17.166443
|
||||
},
|
||||
"TerritoryId": 212,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024045,
|
||||
"Position": {
|
||||
"X": -2.822998,
|
||||
"Y": -2.0000012,
|
||||
"Z": -17.166443
|
||||
},
|
||||
"TerritoryId": 212,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024046,
|
||||
"Position": {
|
||||
"X": 592.70605,
|
||||
"Y": 80.00001,
|
||||
"Z": 618.6465
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1023036,
|
||||
"Position": {
|
||||
"X": -285.23688,
|
||||
"Y": 11.183244,
|
||||
"Z": 188.83032
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024052,
|
||||
"Position": {
|
||||
"X": -238.54431,
|
||||
"Y": 0.9244179,
|
||||
"Z": 196.55139
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Comment": "Aim at jaw"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024340,
|
||||
"Position": {
|
||||
"X": -208.20941,
|
||||
"Y": -0.3,
|
||||
"Z": 207.6294
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024053,
|
||||
"Position": {
|
||||
"X": 8.590759,
|
||||
"Y": 5.3881354,
|
||||
"Z": 282.7954
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"Comment": "Aim at nearest eye"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 6,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024341,
|
||||
"Position": {
|
||||
"X": -3.5248413,
|
||||
"Y": 3.1742485,
|
||||
"Z": 249.34766
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1023036,
|
||||
"Position": {
|
||||
"X": -285.23688,
|
||||
"Y": 11.183244,
|
||||
"Z": 188.83032
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024051,
|
||||
"Position": {
|
||||
"X": -285.29797,
|
||||
"Y": 11.183233,
|
||||
"Z": 187.02979
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009047,
|
||||
"Position": {
|
||||
"X": 526.8176,
|
||||
"Y": 69.962524,
|
||||
"Z": 577.3861
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024055,
|
||||
"Position": {
|
||||
"X": 525.0781,
|
||||
"Y": 70,
|
||||
"Z": 574.6699
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024057,
|
||||
"Position": {
|
||||
"X": 340.23022,
|
||||
"Y": 74.00002,
|
||||
"Z": 70.66455
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024063,
|
||||
"Position": {
|
||||
"X": 339.62,
|
||||
"Y": 74.00002,
|
||||
"Z": 75.48633
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "List",
|
||||
"Prompt": "TEXT_STMBDB111_02972_Q1_000_000",
|
||||
"Answer": "TEXT_STMBDB111_02972_A1_000_001"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009048,
|
||||
"Position": {
|
||||
"X": 593.56055,
|
||||
"Y": 79.972534,
|
||||
"Z": 621.9425
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024065,
|
||||
"Position": {
|
||||
"X": 749.9961,
|
||||
"Y": 70.139626,
|
||||
"Z": 522.88086
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024066,
|
||||
"Position": {
|
||||
"X": 245.07507,
|
||||
"Y": 122,
|
||||
"Z": -349.0807
|
||||
},
|
||||
"TerritoryId": 737,
|
||||
"InteractionType": "SinglePlayerDuty"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024206,
|
||||
"Position": {
|
||||
"X": 251.69751,
|
||||
"Y": 122,
|
||||
"Z": -345.5406
|
||||
},
|
||||
"TerritoryId": 737,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 6,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024068,
|
||||
"Position": {
|
||||
"X": 741.1764,
|
||||
"Y": 70,
|
||||
"Z": 525.5055
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 7,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024068,
|
||||
"Position": {
|
||||
"X": 741.1764,
|
||||
"Y": 70,
|
||||
"Z": 525.5055
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019468,
|
||||
"Position": {
|
||||
"X": 170.58057,
|
||||
"Y": 13.02367,
|
||||
"Z": -91.96619
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Rhalgr's Reach",
|
||||
"AethernetShortcut": [
|
||||
"[Rhalgr's Reach] Aetheryte Plaza",
|
||||
"[Rhalgr's Reach] Northeastern Rhalgr's Reach"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019468,
|
||||
"Position": {
|
||||
"X": 170.58057,
|
||||
"Y": 13.02367,
|
||||
"Z": -91.96619
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Rhalgr's Reach",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1020463,
|
||||
"Position": {
|
||||
"X": 151.20166,
|
||||
"Y": 14.7757225,
|
||||
"Z": 95.750244
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 639,
|
||||
"AetheryteShortcut": "Kugane",
|
||||
"AethernetShortcut": [
|
||||
"[Kugane] Aetheryte Plaza",
|
||||
"[Kugane] The Ruby Bazaar"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024726,
|
||||
"Position": {
|
||||
"X": -11.367981,
|
||||
"Y": 10.503965,
|
||||
"Z": -212.75659
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AethernetShortcut": [
|
||||
"[Kugane] The Ruby Bazaar",
|
||||
"[Kugane] Rakuza District"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024727,
|
||||
"Position": {
|
||||
"X": -12.375122,
|
||||
"Y": 10.503965,
|
||||
"Z": -213.76367
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Kugane",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024731,
|
||||
"Position": {
|
||||
"X": 89.92139,
|
||||
"Y": 3.9999497,
|
||||
"Z": 52.262085
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "Interact",
|
||||
"AethernetShortcut": [
|
||||
"[Kugane] Rakuza District",
|
||||
"[Kugane] Kogane Dori Markets"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019061,
|
||||
"Position": {
|
||||
"X": -0.045776367,
|
||||
"Y": -7.9738514E-11,
|
||||
"Z": -80.857605
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AethernetShortcut": [
|
||||
"[Kugane] Kogane Dori Markets",
|
||||
"[Kugane] Aetheryte Plaza"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024738,
|
||||
"Position": {
|
||||
"X": 1.3884888,
|
||||
"Y": -7.717861E-11,
|
||||
"Z": -78.14148
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Kugane",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024743,
|
||||
"Position": {
|
||||
"X": -123.1861,
|
||||
"Y": -6.9999976,
|
||||
"Z": -58.854065
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024822,
|
||||
"Position": {
|
||||
"X": 885.0995,
|
||||
"Y": 1.1792068,
|
||||
"Z": 861.38696
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "SinglePlayerDuty"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024826,
|
||||
"Position": {
|
||||
"X": 458.94556,
|
||||
"Y": 30.580631,
|
||||
"Z": 748.74475
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024830,
|
||||
"Position": {
|
||||
"X": 577.26404,
|
||||
"Y": 0.93538165,
|
||||
"Z": 852.7809
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024836,
|
||||
"Position": {
|
||||
"X": -788.2658,
|
||||
"Y": 11.709066,
|
||||
"Z": -283.0091
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024837,
|
||||
"Position": {
|
||||
"X": -791.04297,
|
||||
"Y": 12.349811,
|
||||
"Z": -283.8026
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -831.06116,
|
||||
"Y": 20.168653,
|
||||
"Z": -266.25217
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "WalkTo",
|
||||
"TargetTerritoryId": 614,
|
||||
"Mount": true
|
||||
},
|
||||
{
|
||||
"DataId": 1024842,
|
||||
"Position": {
|
||||
"X": 789.6085,
|
||||
"Y": 99.21144,
|
||||
"Z": -288.5329
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019285,
|
||||
"Position": {
|
||||
"X": 195.63586,
|
||||
"Y": 5.16971,
|
||||
"Z": -437.2473
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"$": "QW: 0 0 0 0 0 0 -> QW: 1 0 0 0 0 128"
|
||||
},
|
||||
{
|
||||
"DataId": 1019286,
|
||||
"Position": {
|
||||
"X": 233.60034,
|
||||
"Y": 5.2518563,
|
||||
"Z": -425.3758
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024846,
|
||||
"Position": {
|
||||
"X": 309.46814,
|
||||
"Y": 17.755785,
|
||||
"Z": -445.97546
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024847,
|
||||
"Position": {
|
||||
"X": 59.067627,
|
||||
"Y": 37.21815,
|
||||
"Z": -529.1676
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024849,
|
||||
"Position": {
|
||||
"X": 57.328125,
|
||||
"Y": 36.90612,
|
||||
"Z": -524.71204
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 228.99776,
|
||||
"Y": 5.218606,
|
||||
"Z": -407.7175
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "WalkTo",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1020524,
|
||||
"Position": {
|
||||
"X": 173.20508,
|
||||
"Y": 5.1910434,
|
||||
"Z": -433.24945
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1020524,
|
||||
"Position": {
|
||||
"X": 173.20508,
|
||||
"Y": 5.1910434,
|
||||
"Z": -433.24945
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Yanxia - House of the Fierce",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024955,
|
||||
"Position": {
|
||||
"X": 350.14868,
|
||||
"Y": 26.448109,
|
||||
"Z": 609.1859
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"AetheryteShortcut": "Yanxia - Namai"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024957,
|
||||
"Position": {
|
||||
"X": 365.9265,
|
||||
"Y": 1.7862457,
|
||||
"Z": 738.9486
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024966,
|
||||
"Position": {
|
||||
"X": -472.3125,
|
||||
"Y": 1.2300053,
|
||||
"Z": 537.77356
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024794,
|
||||
"Position": {
|
||||
"X": -493.98032,
|
||||
"Y": 1.3011811,
|
||||
"Z": 542.90063
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 759
|
||||
},
|
||||
{
|
||||
"DataId": 162,
|
||||
"Position": {
|
||||
"X": 96.269165,
|
||||
"Y": -3.4332886,
|
||||
"Z": 81.01013
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"Comment": "Aethernet Attunement: [Doman Enclave] Ferry Docks"
|
||||
},
|
||||
{
|
||||
"DataId": 130,
|
||||
"Position": {
|
||||
"X": -61.57019,
|
||||
"Y": 0.77819824,
|
||||
"Z": 90.684326
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"Comment": "Aethernet Attunement: [Doman Enclave] The Southern Enclave"
|
||||
},
|
||||
{
|
||||
"DataId": 129,
|
||||
"Position": {
|
||||
"X": 8.987488,
|
||||
"Y": 0.8086548,
|
||||
"Z": -105.85187
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"Comment": "Aethernet Attunement: [Doman Enclave] The Northern Enclave"
|
||||
},
|
||||
{
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "AttuneAetheryte",
|
||||
"Aetheryte": "Doman Enclave"
|
||||
},
|
||||
{
|
||||
"DataId": 1024970,
|
||||
"Position": {
|
||||
"X": 40.238037,
|
||||
"Y": 0,
|
||||
"Z": 5.874695
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "List",
|
||||
"Prompt": "TEXT_STMBDC105_03026_Q1_000_000",
|
||||
"Answer": "TEXT_STMBDC105_03026_A1_000_001"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024974,
|
||||
"Position": {
|
||||
"X": -10.330383,
|
||||
"Y": 0.19997318,
|
||||
"Z": 12.893799
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "YesNo",
|
||||
"Prompt": "TEXT_STMBDC105_03026_EVENTAREA_WARP_000_000",
|
||||
"Yes": true
|
||||
}
|
||||
],
|
||||
"TargetTerritoryId": 744
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 6
|
||||
},
|
||||
{
|
||||
"Sequence": 7,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025049,
|
||||
"Position": {
|
||||
"X": -0.015319824,
|
||||
"Y": 0.19999999,
|
||||
"Z": -4.837158
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009289,
|
||||
"Position": {
|
||||
"X": 0.02468622,
|
||||
"Y": 0.9079783,
|
||||
"Z": 18.30971
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 759
|
||||
},
|
||||
{
|
||||
"DataId": 1024971,
|
||||
"Position": {
|
||||
"X": 6.0272217,
|
||||
"Y": 0,
|
||||
"Z": 18.631226
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024971,
|
||||
"Position": {
|
||||
"X": 6.0272217,
|
||||
"Y": 0,
|
||||
"Z": 18.631226
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Doman Enclave",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024980,
|
||||
"Position": {
|
||||
"X": -276.26465,
|
||||
"Y": 53.240116,
|
||||
"Z": -368.8869
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Yanxia - House of the Fierce",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024983,
|
||||
"Position": {
|
||||
"X": -260.60883,
|
||||
"Y": 53.217503,
|
||||
"Z": -645.594
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024986,
|
||||
"Position": {
|
||||
"X": -348.9281,
|
||||
"Y": 1.230035,
|
||||
"Z": -344.13672
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "SinglePlayerDuty",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024989,
|
||||
"Position": {
|
||||
"X": 464.10315,
|
||||
"Y": 17.720512,
|
||||
"Z": 301.59448
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024989,
|
||||
"Position": {
|
||||
"X": 464.10315,
|
||||
"Y": 17.720512,
|
||||
"Z": 301.59448
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025026,
|
||||
"Position": {
|
||||
"X": 3.7078857,
|
||||
"Y": 0,
|
||||
"Z": 17.471558
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Doman Enclave"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024974,
|
||||
"Position": {
|
||||
"X": -10.330383,
|
||||
"Y": 0.19997318,
|
||||
"Z": 12.893799
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "YesNo",
|
||||
"Prompt": "TEXT_STMBDC107_03028_EVENTAREA_WARP_000_056",
|
||||
"Yes": true
|
||||
}
|
||||
],
|
||||
"TargetTerritoryId": 744
|
||||
},
|
||||
{
|
||||
"DataId": 1024999,
|
||||
"Position": {
|
||||
"X": 0.19836426,
|
||||
"Y": 0.021091364,
|
||||
"Z": -3.0975952
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025008,
|
||||
"Position": {
|
||||
"X": -0.19836426,
|
||||
"Y": 0.021091364,
|
||||
"Z": -2.7619019
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009289,
|
||||
"Position": {
|
||||
"X": 0.02468622,
|
||||
"Y": 0.9079783,
|
||||
"Z": 18.30971
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 759
|
||||
},
|
||||
{
|
||||
"DataId": 1025012,
|
||||
"Position": {
|
||||
"X": 1.5715942,
|
||||
"Y": 0,
|
||||
"Z": 18.631226
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025019,
|
||||
"Position": {
|
||||
"X": 366.53687,
|
||||
"Y": 1.286227,
|
||||
"Z": 746.2118
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019070,
|
||||
"Position": {
|
||||
"X": 151.20166,
|
||||
"Y": 14.7757225,
|
||||
"Z": 95.78088
|
||||
},
|
||||
"TerritoryId": 628,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 639,
|
||||
"AetheryteShortcut": "Kugane",
|
||||
"AethernetShortcut": [
|
||||
"[Kugane] Aetheryte Plaza",
|
||||
"[Kugane] The Ruby Bazaar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1020622,
|
||||
"Position": {
|
||||
"X": 0.045776367,
|
||||
"Y": 0,
|
||||
"Z": -2.3041382
|
||||
},
|
||||
"TerritoryId": 639,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025023,
|
||||
"Position": {
|
||||
"X": -1.7853394,
|
||||
"Y": 0.024148807,
|
||||
"Z": -0.015319824
|
||||
},
|
||||
"TerritoryId": 639,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024974,
|
||||
"Position": {
|
||||
"X": -10.330383,
|
||||
"Y": 0.19997318,
|
||||
"Z": 12.893799
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Doman Enclave",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "YesNo",
|
||||
"Prompt": "TEXT_STMBDD101_03070_EVENTAREA_WARP_100_027",
|
||||
"Yes": true
|
||||
}
|
||||
],
|
||||
"TargetTerritoryId": 744
|
||||
},
|
||||
{
|
||||
"DataId": 1025552,
|
||||
"Position": {
|
||||
"X": 0.045776367,
|
||||
"Y": 0.021091362,
|
||||
"Z": -2.9145508
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009289,
|
||||
"Position": {
|
||||
"X": 0.02468622,
|
||||
"Y": 0.9079783,
|
||||
"Z": 18.30971
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 759
|
||||
},
|
||||
{
|
||||
"DataId": 1025555,
|
||||
"Position": {
|
||||
"X": 148.05823,
|
||||
"Y": -4.178815,
|
||||
"Z": 60.135742
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"Comment": "AethernetShortcut: [Doman Enclave] Aetheryte Plaza -> [Doman Enclave] Ferry Docks"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025557,
|
||||
"Position": {
|
||||
"X": 146.37976,
|
||||
"Y": -4.178755,
|
||||
"Z": 60.135742
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Doman Enclave",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019297,
|
||||
"Position": {
|
||||
"X": -275.9289,
|
||||
"Y": 17.31996,
|
||||
"Z": 512.9625
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"$": "QW: 0 0 0 0 0 0 -> QW: 1 0 0 0 0 128"
|
||||
},
|
||||
{
|
||||
"DataId": 1019303,
|
||||
"Position": {
|
||||
"X": -308.94946,
|
||||
"Y": 17.73554,
|
||||
"Z": 512.47424
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009474,
|
||||
"Position": {
|
||||
"X": 67.185425,
|
||||
"Y": 17.440979,
|
||||
"Z": 349.3247
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009527,
|
||||
"Position": {
|
||||
"X": 457.26697,
|
||||
"Y": 31.265625,
|
||||
"Z": 234.79053
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009528,
|
||||
"Position": {
|
||||
"X": 545.3727,
|
||||
"Y": 84.70276,
|
||||
"Z": 126.32947
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009475,
|
||||
"Position": {
|
||||
"X": 546.9595,
|
||||
"Y": 72.129395,
|
||||
"Z": 39.78015
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025095,
|
||||
"Position": {
|
||||
"X": 466.23938,
|
||||
"Y": 70.27501,
|
||||
"Z": -58.701477
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Yanxia - Namai",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InSameTerritory": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025104,
|
||||
"Position": {
|
||||
"X": 408.71277,
|
||||
"Y": 14.6418705,
|
||||
"Z": 622.8275
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024999,
|
||||
"Position": {
|
||||
"X": 0.19836426,
|
||||
"Y": 0.021091364,
|
||||
"Z": -3.0975952
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024999,
|
||||
"Position": {
|
||||
"X": 0.19836426,
|
||||
"Y": 0.021091364,
|
||||
"Z": -3.0975952
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024999,
|
||||
"Position": {
|
||||
"X": 0.19836426,
|
||||
"Y": 0.021091364,
|
||||
"Z": -3.0975952
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1021505,
|
||||
"Position": {
|
||||
"X": 79.42322,
|
||||
"Y": 33.00897,
|
||||
"Z": -669.9474
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ruby Sea - Onokoro",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": 116.05634,
|
||||
"Y": 3.799895,
|
||||
"Z": -868.98865
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "WalkTo",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 2009420,
|
||||
"Position": {
|
||||
"X": 106.30957,
|
||||
"Y": 0.47296143,
|
||||
"Z": -874.38776
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"DisableNavmesh": true
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": 63.579952,
|
||||
"Y": -1.1090306,
|
||||
"Z": -869.52625
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "WalkTo",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 2009469,
|
||||
"Position": {
|
||||
"X": 78.20239,
|
||||
"Y": 0.47296143,
|
||||
"Z": -870.66455
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "Interact",
|
||||
"Mount": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025106,
|
||||
"Position": {
|
||||
"X": 97.00159,
|
||||
"Y": 5.1987257,
|
||||
"Z": -877.0428
|
||||
},
|
||||
"TerritoryId": 613,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024974,
|
||||
"Position": {
|
||||
"X": -10.330383,
|
||||
"Y": 0.19997318,
|
||||
"Z": 12.893799
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Doman Enclave",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "YesNo",
|
||||
"Prompt": "TEXT_STMBDD104_03073_EVENTAREA_WARP_100_004",
|
||||
"Yes": true
|
||||
}
|
||||
],
|
||||
"TargetTerritoryId": 744
|
||||
},
|
||||
{
|
||||
"DataId": 1024999,
|
||||
"Position": {
|
||||
"X": 0.19836426,
|
||||
"Y": 0.021091364,
|
||||
"Z": -3.0975952
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024999,
|
||||
"Position": {
|
||||
"X": 0.19836426,
|
||||
"Y": 0.021091364,
|
||||
"Z": -3.0975952
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025523,
|
||||
"Position": {
|
||||
"X": 239.12415,
|
||||
"Y": 0.9334852,
|
||||
"Z": 754.1161
|
||||
},
|
||||
"TerritoryId": 614,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"AetheryteShortcut": "Yanxia - Namai"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 786,
|
||||
"InteractionType": "Duty",
|
||||
"ContentFinderConditionId": 537
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025528,
|
||||
"Position": {
|
||||
"X": 4.3182373,
|
||||
"Y": -8.000055,
|
||||
"Z": 44.327393
|
||||
},
|
||||
"TerritoryId": 786,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 6
|
||||
},
|
||||
{
|
||||
"Sequence": 7,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025538,
|
||||
"Position": {
|
||||
"X": 4.7455444,
|
||||
"Y": 0,
|
||||
"Z": 16.067688
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1024974,
|
||||
"Position": {
|
||||
"X": -10.330383,
|
||||
"Y": 0.19997318,
|
||||
"Z": 12.893799
|
||||
},
|
||||
"TerritoryId": 759,
|
||||
"InteractionType": "Interact",
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "YesNo",
|
||||
"Prompt": "TEXT_STMBDD105_03074_EVENTAREA_WARP_100_004",
|
||||
"Yes": true
|
||||
}
|
||||
],
|
||||
"TargetTerritoryId": 744
|
||||
},
|
||||
{
|
||||
"DataId": 1025597,
|
||||
"Position": {
|
||||
"X": 0.19836426,
|
||||
"Y": 0.021091362,
|
||||
"Z": -3.0060425
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025009,
|
||||
"Position": {
|
||||
"X": 1.3274536,
|
||||
"Y": 0.021091362,
|
||||
"Z": 0.59503174
|
||||
},
|
||||
"TerritoryId": 744,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1019468,
|
||||
"Position": {
|
||||
"X": 170.58057,
|
||||
"Y": 13.02367,
|
||||
"Z": -91.96619
|
||||
},
|
||||
"TerritoryId": 635,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Rhalgr's Reach",
|
||||
"AethernetShortcut": [
|
||||
"[Rhalgr's Reach] Aetheryte Plaza",
|
||||
"[Rhalgr's Reach] Northeastern Rhalgr's Reach"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025546,
|
||||
"Position": {
|
||||
"X": 70.87805,
|
||||
"Y": 26.199663,
|
||||
"Z": -609.43005
|
||||
},
|
||||
"TerritoryId": 621,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"AetheryteShortcut": "Lochs - Porta Praetoria"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025549,
|
||||
"Position": {
|
||||
"X": 1.4800415,
|
||||
"Y": -1.1041565E-05,
|
||||
"Z": -11.734253
|
||||
},
|
||||
"TerritoryId": 351,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "JerryWester",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025549,
|
||||
"Position": {
|
||||
"X": 1.4800415,
|
||||
"Y": -1.1041565E-05,
|
||||
"Z": -11.734253
|
||||
},
|
||||
"TerritoryId": 351,
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2009467,
|
||||
"Position": {
|
||||
"X": -5.189492,
|
||||
"Y": 0.4746897,
|
||||
"Z": 0.3689831
|
||||
},
|
||||
"TerritoryId": 351,
|
||||
"InteractionType": "SinglePlayerDuty"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1025549,
|
||||
"Position": {
|
||||
"X": 1.4800415,
|
||||
"Y": -1.1041565E-05,
|
||||
"Z": -11.734253
|
||||
},
|
||||
"TerritoryId": 351,
|
||||
"InteractionType": "CompleteQuest"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -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,
|
||||
@ -30,8 +29,39 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
|
||||
{
|
||||
"DataId": 1033750,
|
||||
"Position": {
|
||||
"X": -591.3329,
|
||||
"Y": 72.00111,
|
||||
"Z": -451.01093
|
||||
},
|
||||
"StopDistance": 5,
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 31167,
|
||||
"ItemCount": 1
|
||||
},
|
||||
{
|
||||
"DataId": 1033750,
|
||||
"Position": {
|
||||
"X": -591.3329,
|
||||
"Y": 72.00111,
|
||||
"Z": -451.01093
|
||||
},
|
||||
"StopDistance": 5,
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -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,
|
||||
@ -30,8 +29,154 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
|
||||
{
|
||||
"DataId": 2011169,
|
||||
"Position": {
|
||||
"X": -95.903015,
|
||||
"Y": 1.6326294,
|
||||
"Z": 41.244995
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"RequiredQuestVariables": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
[
|
||||
{
|
||||
"High": 1
|
||||
},
|
||||
{
|
||||
"High": 4
|
||||
},
|
||||
{
|
||||
"High": 5
|
||||
}
|
||||
],
|
||||
null,
|
||||
null
|
||||
],
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
128
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 2011170,
|
||||
"Position": {
|
||||
"X": -84.916504,
|
||||
"Y": 2.39563,
|
||||
"Z": 36.850464
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"RequiredQuestVariables": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
[
|
||||
{
|
||||
"High": 1
|
||||
},
|
||||
{
|
||||
"High": 2
|
||||
},
|
||||
{
|
||||
"High": 6
|
||||
}
|
||||
],
|
||||
null,
|
||||
null
|
||||
],
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
64
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 2011171,
|
||||
"Position": {
|
||||
"X": -68.55884,
|
||||
"Y": 2.5177002,
|
||||
"Z": 38.04065
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"RequiredQuestVariables": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
[
|
||||
{
|
||||
"High": 3
|
||||
},
|
||||
{
|
||||
"High": 5
|
||||
},
|
||||
{
|
||||
"High": 6
|
||||
}
|
||||
],
|
||||
null,
|
||||
null
|
||||
],
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
32
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 2011172,
|
||||
"Position": {
|
||||
"X": -70.2984,
|
||||
"Y": 1.449585,
|
||||
"Z": 62.210938
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true,
|
||||
"RequiredQuestVariables": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
[
|
||||
{
|
||||
"High": 2
|
||||
},
|
||||
{
|
||||
"High": 3
|
||||
},
|
||||
{
|
||||
"High": 4
|
||||
}
|
||||
],
|
||||
null,
|
||||
null
|
||||
],
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
16
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -45,6 +190,7 @@
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "WalkTo",
|
||||
"AetheryteShortcut": "Lakeland - Ostall Imperative",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
|
@ -0,0 +1,9 @@
|
||||
```
|
||||
0 0 0 xx 0 0 | 2011169 2011170 2011171 2011172
|
||||
16(1) x x
|
||||
32(2) x x
|
||||
48(3) x x
|
||||
64(4) x x
|
||||
80(5) x x
|
||||
96(6) x x
|
||||
```
|
@ -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,
|
||||
@ -30,8 +29,39 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
|
||||
{
|
||||
"DataId": 1033767,
|
||||
"Position": {
|
||||
"X": -608.6061,
|
||||
"Y": 65.60222,
|
||||
"Z": -431.81506
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 31169,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"DataId": 1033694,
|
||||
"Position": {
|
||||
"X": 593.19434,
|
||||
"Y": 5.8981767,
|
||||
"Z": 704.86
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Lakeland - Fort Jobb",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -45,6 +75,7 @@
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "WalkTo",
|
||||
"AetheryteShortcut": "Lakeland - Ostall Imperative",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
|
@ -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,
|
||||
@ -30,8 +29,26 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
|
||||
{
|
||||
"Position": {
|
||||
"X": -27.174656,
|
||||
"Y": 1.063369,
|
||||
"Z": 661.43774
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "WalkTo",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1034072,
|
||||
"Position": {
|
||||
"X": -25.92511,
|
||||
"Y": 1.3904266,
|
||||
"Z": 662.8976
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -45,6 +62,7 @@
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "WalkTo",
|
||||
"AetheryteShortcut": "Lakeland - Ostall Imperative",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
|
@ -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,
|
||||
@ -30,8 +29,38 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
|
||||
{
|
||||
"DataId": 1033767,
|
||||
"Position": {
|
||||
"X": -608.6061,
|
||||
"Y": 65.60222,
|
||||
"Z": -431.81506
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 31181,
|
||||
"ItemCount": 1
|
||||
},
|
||||
{
|
||||
"DataId": 1034073,
|
||||
"Position": {
|
||||
"X": -504.0513,
|
||||
"Y": 3.623286,
|
||||
"Z": 25.802979
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -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,
|
||||
@ -30,13 +29,38 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
|
||||
|
||||
{
|
||||
"Position": {
|
||||
"X": -134.17696,
|
||||
"Y": 14.623874,
|
||||
"Z": -124.68204
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "WalkTo",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1034075,
|
||||
"Position": {
|
||||
"X": -137.71265,
|
||||
"Y": 14.623856,
|
||||
"Z": -124.89508
|
||||
},
|
||||
"StopDistance": 5,
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 31183,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -615.73865,
|
||||
|
@ -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,
|
||||
@ -18,6 +17,25 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1032413,
|
||||
"Position": {
|
||||
"X": 144.36548,
|
||||
"Y": -19.982845,
|
||||
"Z": -459.8001
|
||||
},
|
||||
"TerritoryId": 817,
|
||||
"InteractionType": "Say",
|
||||
"ChatMessage": {
|
||||
"Key": "TEXT_BANQIQ114_03819_SAYTODO_000_000"
|
||||
},
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
@ -30,12 +48,7 @@
|
||||
"TerritoryId": 817,
|
||||
"InteractionType": "WalkTo",
|
||||
"AetheryteShortcut": "Rak'tika - Fanow",
|
||||
"Fly": true,
|
||||
"RequiredGatheredItems": [
|
||||
|
||||
|
||||
|
||||
]
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1032643,
|
||||
|
@ -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,
|
||||
@ -32,7 +31,16 @@
|
||||
"AetheryteShortcut": "Rak'tika - Fanow",
|
||||
"Fly": true,
|
||||
"RequiredGatheredItems": [
|
||||
|
||||
{
|
||||
"QuestAcceptedAsClass": "Miner",
|
||||
"ItemId": 29528,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"QuestAcceptedAsClass": "Botanist",
|
||||
"ItemId": 29554,
|
||||
"ItemCount": 3
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
|
@ -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,
|
||||
@ -32,9 +31,16 @@
|
||||
"AetheryteShortcut": "Rak'tika - Fanow",
|
||||
"Fly": true,
|
||||
"RequiredGatheredItems": [
|
||||
|
||||
|
||||
|
||||
{
|
||||
"QuestAcceptedAsClass": "Miner",
|
||||
"ItemId": 29529,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"QuestAcceptedAsClass": "Botanist",
|
||||
"ItemId": 29555,
|
||||
"ItemCount": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -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,
|
||||
@ -17,6 +16,89 @@
|
||||
"InteractionType": "AcceptQuest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1027264,
|
||||
"Position": {
|
||||
"X": 60.593506,
|
||||
"Y": 36.247692,
|
||||
"Z": -171.80133
|
||||
},
|
||||
"TerritoryId": 819,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 815,
|
||||
"AethernetShortcut": [
|
||||
"[Crystarium] The Pendants",
|
||||
"[Crystarium] The Amaro Launch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1030623,
|
||||
"Position": {
|
||||
"X": 665.6748,
|
||||
"Y": -50.355476,
|
||||
"Z": -641.5351
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2010165,
|
||||
"Position": {
|
||||
"X": 483.48206,
|
||||
"Y": -50.46167,
|
||||
"Z": -631.52515
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Combat",
|
||||
"EnemySpawnType": "AfterInteraction",
|
||||
"KillEnemyDataIds": [
|
||||
10836
|
||||
],
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030624,
|
||||
"Position": {
|
||||
"X": 500.54163,
|
||||
"Y": -50.72601,
|
||||
"Z": -647.5471
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"NextQuestId": 3624
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -0,0 +1,110 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"NearPosition": {
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"MaximumDistance": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2010166,
|
||||
"Position": {
|
||||
"X": 599.115,
|
||||
"Y": -33.61566,
|
||||
"Z": -304.49384
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Combat",
|
||||
"EnemySpawnType": "AfterInteraction",
|
||||
"KillEnemyDataIds": [
|
||||
10837
|
||||
],
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2010214,
|
||||
"Position": {
|
||||
"X": 488.85327,
|
||||
"Y": -26.16925,
|
||||
"Z": -12.008911
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"Fly": true,
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "List",
|
||||
"Prompt": "TEXT_LUCKBA411_03624_Q1_000_100",
|
||||
"Answer": "TEXT_LUCKBA411_03624_A1_000_100"
|
||||
}
|
||||
],
|
||||
"NextQuestId": 3625
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"NearPosition": {
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"MaximumDistance": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030626,
|
||||
"Position": {
|
||||
"X": 331.62415,
|
||||
"Y": 1.4685826,
|
||||
"Z": -244.95312
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030627,
|
||||
"Position": {
|
||||
"X": 330.06775,
|
||||
"Y": 1.4685818,
|
||||
"Z": -164.0498
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030628,
|
||||
"Position": {
|
||||
"X": 407.6753,
|
||||
"Y": -28.443933,
|
||||
"Z": 260.8224
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Amh Araeng - Inn at Journey's Head",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030630,
|
||||
"Position": {
|
||||
"X": 368.39856,
|
||||
"Y": -28.620693,
|
||||
"Z": 353.78027
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030632,
|
||||
"Position": {
|
||||
"X": 550.225,
|
||||
"Y": -45.678886,
|
||||
"Z": 282.82593
|
||||
},
|
||||
"StopDistance": 0.5,
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Combat",
|
||||
"EnemySpawnType": "AutoOnEnterArea",
|
||||
"KillEnemyDataIds": [
|
||||
10838
|
||||
],
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 6,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030632,
|
||||
"Position": {
|
||||
"X": 550.225,
|
||||
"Y": -45.678886,
|
||||
"Z": 282.82593
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 7,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030631,
|
||||
"Position": {
|
||||
"X": 367.72717,
|
||||
"Y": -28.562725,
|
||||
"Z": 356.19116
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"Fly": true,
|
||||
"NextQuestId": 3626
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"NearPosition": {
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"MaximumDistance": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030636,
|
||||
"Position": {
|
||||
"X": 342.8855,
|
||||
"Y": -35.843185,
|
||||
"Z": 76.58496
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "SinglePlayerDuty",
|
||||
"AetheryteShortcut": "Amh Araeng - Inn at Journey's Head",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"Fly": true,
|
||||
"NextQuestId": 3627
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"NearPosition": {
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"MaximumDistance": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030638,
|
||||
"Position": {
|
||||
"X": 543.8773,
|
||||
"Y": -6.503428,
|
||||
"Z": 811.7036
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Crystarium",
|
||||
"AethernetShortcut": [
|
||||
"[Crystarium] Aetheryte Plaza",
|
||||
"[Crystarium] Tessellation (Lakeland)"
|
||||
],
|
||||
"Fly": true,
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"InTerritory": [
|
||||
813
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2010215,
|
||||
"Position": {
|
||||
"X": 523.9795,
|
||||
"Y": -2.0599976,
|
||||
"Z": 795.1018
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Combat",
|
||||
"EnemySpawnType": "AfterInteraction",
|
||||
"KillEnemyDataIds": [
|
||||
10839
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030639,
|
||||
"Position": {
|
||||
"X": 542.8092,
|
||||
"Y": -6.489782,
|
||||
"Z": 811.79517
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1031033,
|
||||
"Position": {
|
||||
"X": 540.6727,
|
||||
"Y": -6.4392195,
|
||||
"Z": 801.87683
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1031033,
|
||||
"Position": {
|
||||
"X": 540.6727,
|
||||
"Y": -6.4392195,
|
||||
"Z": 801.87683
|
||||
},
|
||||
"TerritoryId": 813,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"Fly": true,
|
||||
"NextQuestId": 3628
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "AcceptQuest",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq",
|
||||
"SkipConditions": {
|
||||
"AetheryteShortcutIf": {
|
||||
"NearPosition": {
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"MaximumDistance": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030697,
|
||||
"Position": {
|
||||
"X": 288.74634,
|
||||
"Y": 7.1558266,
|
||||
"Z": -219.2569
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030641,
|
||||
"Position": {
|
||||
"X": -255.8786,
|
||||
"Y": 23.447075,
|
||||
"Z": -288.4718
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "SinglePlayerDuty",
|
||||
"AetheryteShortcut": "Amh Araeng - Twine",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 4
|
||||
},
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030641,
|
||||
"Position": {
|
||||
"X": -255.8786,
|
||||
"Y": 23.447075,
|
||||
"Z": -288.4718
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 6,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030625,
|
||||
"Position": {
|
||||
"X": 218.73804,
|
||||
"Y": 7.1558266,
|
||||
"Z": -249.1341
|
||||
},
|
||||
"TerritoryId": 815,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Amh Araeng - Mord Souq"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1030643,
|
||||
"Position": {
|
||||
"X": -0.16790771,
|
||||
"Y": 3.9998174,
|
||||
"Z": 201.9226
|
||||
},
|
||||
"TerritoryId": 819,
|
||||
"InteractionType": "CompleteQuest",
|
||||
"AetheryteShortcut": "Crystarium",
|
||||
"AethernetShortcut": [
|
||||
"[Crystarium] Aetheryte Plaza",
|
||||
"[Crystarium] The Pendants"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -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,
|
||||
|
@ -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,
|
||||
@ -30,6 +29,52 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1045113,
|
||||
"Position": {
|
||||
"X": -315.66345,
|
||||
"Y": -144,
|
||||
"Z": -492.0272
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044585,
|
||||
"Position": {
|
||||
"X": -496.14713,
|
||||
"Y": -154.93994,
|
||||
"Z": -484.88593
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Say",
|
||||
"Fly": true,
|
||||
"ChatMessage": {
|
||||
"Key": "TEXT_BANLOP114_04700_SAYTODO_000_050"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 3,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1045113,
|
||||
"Position": {
|
||||
"X": -315.66345,
|
||||
"Y": -144,
|
||||
"Z": -492.0272
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -42,7 +87,8 @@
|
||||
"Z": -273.68756
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "WalkTo"
|
||||
"InteractionType": "WalkTo",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1044403,
|
||||
|
@ -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,
|
||||
@ -30,11 +29,27 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044412,
|
||||
"Position": {
|
||||
"X": -181.56714,
|
||||
"Y": -49.19972,
|
||||
"Z": -304.76843
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 38873,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -201.42024,
|
||||
|
@ -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,
|
||||
@ -30,6 +29,39 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044586,
|
||||
"Position": {
|
||||
"X": -524.19324,
|
||||
"Y": -158.8955,
|
||||
"Z": -521.17194
|
||||
},
|
||||
"StopDistance": 0.5,
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 38875,
|
||||
"ItemCount": 1
|
||||
},
|
||||
{
|
||||
"DataId": 1044586,
|
||||
"Position": {
|
||||
"X": -524.19324,
|
||||
"Y": -158.8955,
|
||||
"Z": -521.17194
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -42,7 +74,9 @@
|
||||
"Z": -273.68756
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "WalkTo"
|
||||
"InteractionType": "WalkTo",
|
||||
"AetheryteShortcut": "Mare Lamentorum - Bestways Burrow",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1044403,
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"Disabled": true,
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
@ -31,6 +30,25 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044613,
|
||||
"Position": {
|
||||
"X": 493.55298,
|
||||
"Y": -163.52985,
|
||||
"Z": -711.54346
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Mare Lamentorum - Bestways Burrow",
|
||||
"Fly": true,
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "List",
|
||||
"Prompt": "TEXT_BANLOP125_04711_Q1_000_000",
|
||||
"Answer": "TEXT_BANLOP125_04711_A3_000_003"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -43,7 +61,9 @@
|
||||
"Z": -273.68756
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "WalkTo"
|
||||
"InteractionType": "WalkTo",
|
||||
"AetheryteShortcut": "Mare Lamentorum - Bestways Burrow",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1044403,
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"Disabled": true,
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
@ -31,6 +30,38 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044615,
|
||||
"Position": {
|
||||
"X": -84.7334,
|
||||
"Y": -49.589592,
|
||||
"Z": -351.73578
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 38887,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"DataId": 1044615,
|
||||
"Position": {
|
||||
"X": -84.7334,
|
||||
"Y": -49.589592,
|
||||
"Z": -351.73578
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -43,7 +74,8 @@
|
||||
"Z": -273.68756
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "WalkTo"
|
||||
"InteractionType": "WalkTo",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1044403,
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"Disabled": true,
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
@ -31,11 +30,29 @@
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044616,
|
||||
"Position": {
|
||||
"X": -630.67065,
|
||||
"Y": -140.39087,
|
||||
"Z": -789.79175
|
||||
},
|
||||
"StopDistance": 0.5,
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Interact",
|
||||
"Fly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "Craft",
|
||||
"ItemId": 38889,
|
||||
"ItemCount": 1
|
||||
},
|
||||
{
|
||||
"Position": {
|
||||
"X": -201.42024,
|
||||
@ -43,7 +60,9 @@
|
||||
"Z": -273.68756
|
||||
},
|
||||
"TerritoryId": 959,
|
||||
"InteractionType": "WalkTo"
|
||||
"InteractionType": "WalkTo",
|
||||
"AetheryteShortcut": "Mare Lamentorum - Bestways Burrow",
|
||||
"Fly": true
|
||||
},
|
||||
{
|
||||
"DataId": 1044403,
|
||||
|
@ -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,
|
||||
@ -18,9 +17,73 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2013074,
|
||||
"Position": {
|
||||
"X": 304.3412,
|
||||
"Y": 483.48206,
|
||||
"Z": 143.11438
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 1073
|
||||
},
|
||||
{
|
||||
"DataId": 1044059,
|
||||
"Position": {
|
||||
"X": -15.304871,
|
||||
"Y": 494.9991,
|
||||
"Z": -68.16211
|
||||
},
|
||||
"TerritoryId": 1073,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044059,
|
||||
"Position": {
|
||||
"X": -15.304871,
|
||||
"Y": 494.9991,
|
||||
"Z": -68.16211
|
||||
},
|
||||
"TerritoryId": 1073,
|
||||
"InteractionType": "Interact",
|
||||
"RequiredGatheredItems": [
|
||||
{
|
||||
"QuestAcceptedAsClass": "Miner",
|
||||
"ItemId": 38289,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"QuestAcceptedAsClass": "Botanist",
|
||||
"ItemId": 38313,
|
||||
"ItemCount": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1043421,
|
||||
"Position": {
|
||||
"X": 2.4261475,
|
||||
"Y": 499.87805,
|
||||
"Z": 46.036377
|
||||
},
|
||||
"TerritoryId": 1073,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 960
|
||||
},
|
||||
{
|
||||
"DataId": 1043417,
|
||||
"Position": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||
"Author": "liza",
|
||||
"Disabled": true,
|
||||
"$": "TODO Check if this is a special mount that can always fly",
|
||||
"QuestSequence": [
|
||||
{
|
||||
"Sequence": 0,
|
||||
@ -18,9 +18,82 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044060,
|
||||
"Position": {
|
||||
"X": 57.75537,
|
||||
"Y": 269.00012,
|
||||
"Z": -674.49457
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ultima Thule - Abode of the Ea"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044063,
|
||||
"Position": {
|
||||
"X": -193.53015,
|
||||
"Y": 269.23087,
|
||||
"Z": -315.63293
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Action",
|
||||
"Action": "Electric Flux",
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
64
|
||||
]
|
||||
},
|
||||
{
|
||||
"DataId": 1044062,
|
||||
"Position": {
|
||||
"X": -213.42798,
|
||||
"Y": 268.01166,
|
||||
"Z": -299.5194
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Action",
|
||||
"Action": "Electric Flux",
|
||||
"Fly": true,
|
||||
"CompletionQuestVariablesFlags": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
128
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2013072,
|
||||
"Position": {
|
||||
"X": 456.65674,
|
||||
"Y": 438.04077,
|
||||
"Z": 310.2312
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 960,
|
||||
"AetheryteShortcut": "Ultima Thule - Base Omicron"
|
||||
},
|
||||
{
|
||||
"DataId": 1043417,
|
||||
"Position": {
|
||||
|
@ -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,
|
||||
@ -18,9 +17,50 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044064,
|
||||
"Position": {
|
||||
"X": 86.503296,
|
||||
"Y": 269.08234,
|
||||
"Z": -515.0683
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ultima Thule - Abode of the Ea",
|
||||
"Fly": true,
|
||||
"RequiredGatheredItems": [
|
||||
{
|
||||
"QuestAcceptedAsClass": "Miner",
|
||||
"ItemId": 38290,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"QuestAcceptedAsClass": "Botanist",
|
||||
"ItemId": 38314,
|
||||
"ItemCount": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2013072,
|
||||
"Position": {
|
||||
"X": 456.65674,
|
||||
"Y": 438.04077,
|
||||
"Z": 310.2312
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 960,
|
||||
"AetheryteShortcut": "Ultima Thule - Base Omicron"
|
||||
},
|
||||
{
|
||||
"DataId": 1043417,
|
||||
"Position": {
|
||||
|
@ -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,
|
||||
@ -18,9 +17,50 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044076,
|
||||
"Position": {
|
||||
"X": -499.96188,
|
||||
"Y": 77.00467,
|
||||
"Z": 241.07727
|
||||
},
|
||||
"StopDistance": 9,
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ultima Thule - Reah Tahra",
|
||||
"RequiredGatheredItems": [
|
||||
{
|
||||
"QuestAcceptedAsClass": "Miner",
|
||||
"ItemId": 38297,
|
||||
"ItemCount": 3
|
||||
},
|
||||
{
|
||||
"QuestAcceptedAsClass": "Botanist",
|
||||
"ItemId": 38321,
|
||||
"ItemCount": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2013072,
|
||||
"Position": {
|
||||
"X": 456.65674,
|
||||
"Y": 438.04077,
|
||||
"Z": 310.2312
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 960,
|
||||
"AetheryteShortcut": "Ultima Thule - Base Omicron"
|
||||
},
|
||||
{
|
||||
"DataId": 1043417,
|
||||
"Position": {
|
||||
|
@ -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,
|
||||
@ -18,9 +17,61 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 1,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044078,
|
||||
"Position": {
|
||||
"X": 97.154175,
|
||||
"Y": 269.09738,
|
||||
"Z": -498.3139
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"AetheryteShortcut": "Ultima Thule - Abode of the Ea",
|
||||
"Fly": true,
|
||||
"DialogueChoices": [
|
||||
{
|
||||
"Type": "List",
|
||||
"Prompt": "TEXT_BANOMI127_04633_Q1_000_000",
|
||||
"Answer": "TEXT_BANOMI127_04633_A1_000_002"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 2,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 1044079,
|
||||
"Position": {
|
||||
"X": 99.412476,
|
||||
"Y": 269.09763,
|
||||
"Z": -497.1237
|
||||
},
|
||||
"StopDistance": 5,
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sequence": 255,
|
||||
"Steps": [
|
||||
{
|
||||
"DataId": 2013072,
|
||||
"Position": {
|
||||
"X": 456.65674,
|
||||
"Y": 438.04077,
|
||||
"Z": 310.2312
|
||||
},
|
||||
"TerritoryId": 960,
|
||||
"InteractionType": "Interact",
|
||||
"TargetTerritoryId": 960,
|
||||
"AetheryteShortcut": "Ultima Thule - Base Omicron"
|
||||
},
|
||||
{
|
||||
"DataId": 1043417,
|
||||
"Position": {
|
||||
|
@ -835,12 +835,14 @@
|
||||
"Cure",
|
||||
"Esuna",
|
||||
"Physick",
|
||||
"Buffet",
|
||||
"Buffet (Sanuwa)",
|
||||
"Buffet (Griffin)",
|
||||
"Fumigate",
|
||||
"Siphon Snout",
|
||||
"Red Gulal",
|
||||
"Yellow Gulal",
|
||||
"Blue Gulal"
|
||||
"Blue Gulal",
|
||||
"Electric Flux"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -10,11 +10,13 @@ public sealed class ActionConverter() : EnumConverter<EAction>(Values)
|
||||
{ EAction.Cure, "Cure" },
|
||||
{ EAction.Esuna, "Esuna" },
|
||||
{ EAction.Physick, "Physick" },
|
||||
{ EAction.Buffet, "Buffet" },
|
||||
{ EAction.BuffetSanuwa, "Buffet (Sanuwa)" },
|
||||
{ EAction.BuffetGriffin, "Buffet (Griffin)" },
|
||||
{ EAction.Fumigate, "Fumigate" },
|
||||
{ EAction.SiphonSnout, "Siphon Snout" },
|
||||
{ EAction.RedGulal, "Red Gulal" },
|
||||
{ EAction.YellowGulal, "Yellow Gulal" },
|
||||
{ EAction.BlueGulal, "Blue Gulal" },
|
||||
{ EAction.ElectrixFlux, "Electric Flux" },
|
||||
};
|
||||
}
|
||||
|
@ -9,12 +9,14 @@ public enum EAction
|
||||
Cure = 120,
|
||||
Esuna = 7568,
|
||||
Physick = 190,
|
||||
Buffet = 4931,
|
||||
BuffetSanuwa = 4931,
|
||||
BuffetGriffin = 4583,
|
||||
Fumigate = 5872,
|
||||
SiphonSnout = 18187,
|
||||
RedGulal = 29382,
|
||||
YellowGulal = 29383,
|
||||
BlueGulal = 29384,
|
||||
ElectrixFlux = 29718,
|
||||
|
||||
CollectMiner = 240,
|
||||
ScourMiner = 22182,
|
||||
@ -39,11 +41,13 @@ public static class EActionExtensions
|
||||
public static bool RequiresMount(this EAction action)
|
||||
{
|
||||
return action
|
||||
is EAction.Buffet
|
||||
is EAction.BuffetSanuwa
|
||||
or EAction.BuffetGriffin
|
||||
or EAction.Fumigate
|
||||
or EAction.SiphonSnout
|
||||
or EAction.RedGulal
|
||||
or EAction.YellowGulal
|
||||
or EAction.BlueGulal;
|
||||
or EAction.BlueGulal
|
||||
or EAction.ElectrixFlux;
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,6 @@ internal sealed class InteractionUiController : IDisposable
|
||||
QuestData questData,
|
||||
IGameGui gameGui,
|
||||
ITargetManager targetManager,
|
||||
IFramework framework,
|
||||
IPluginLog pluginLog,
|
||||
IClientState clientState,
|
||||
ILogger<InteractionUiController> logger)
|
||||
@ -92,6 +91,14 @@ internal sealed class InteractionUiController : IDisposable
|
||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "PointMenu", PointMenuPostSetup);
|
||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "HousingSelectBlock", HousingSelectBlockPostSetup);
|
||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "TelepotTown", TeleportTownPostSetup);
|
||||
|
||||
unsafe
|
||||
{
|
||||
if (_gameGui.TryGetAddonByName("RhythmAction", out AtkUnitBase* addon))
|
||||
{
|
||||
addon->Close(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShouldHandleUiInteractions => _isInitialCheck || _questController.IsRunning;
|
||||
@ -778,7 +785,7 @@ internal sealed class InteractionUiController : IDisposable
|
||||
{
|
||||
if (ShouldHandleUiInteractions &&
|
||||
_questController.HasCurrentTaskMatching(out AethernetShortcut.UseAethernetShortcut? aethernetShortcut) &&
|
||||
EAetheryteLocationExtensions.IsFirmamentAetheryte(aethernetShortcut.From))
|
||||
aethernetShortcut.From.IsFirmamentAetheryte())
|
||||
{
|
||||
// this might be better via atkvalues; but this works for now
|
||||
uint toIndex = aethernetShortcut.To switch
|
||||
|
@ -76,7 +76,7 @@ internal sealed class LeveUiController : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void GuildLevePostSetup(AddonEvent type, AddonArgs args)
|
||||
private void GuildLevePostSetup(AddonEvent type, AddonArgs args)
|
||||
{
|
||||
var target = _targetManager.Target;
|
||||
if (target == null)
|
||||
@ -85,8 +85,8 @@ internal sealed class LeveUiController : IDisposable
|
||||
if (_questController is { IsRunning: true, NextQuest: { Quest.Id: LeveId } nextQuest } &&
|
||||
_questFunctions.IsReadyToAcceptQuest(nextQuest.Quest.Id))
|
||||
{
|
||||
var addon = (AddonGuildLeve*)args.Addon;
|
||||
/*
|
||||
var addon = (AddonGuildLeve*)args.Addon;
|
||||
var atkValues = addon->AtkValues;
|
||||
|
||||
var availableLeves = _questData.GetAllByIssuerDataId(target.DataId);
|
||||
|
@ -25,43 +25,59 @@ using Questionable.Functions;
|
||||
using Questionable.GatheringPaths;
|
||||
using Questionable.Model.Gathering;
|
||||
using Questionable.Model.Questing;
|
||||
using Mount = Questionable.Controller.Steps.Common.Mount;
|
||||
|
||||
namespace Questionable.Controller;
|
||||
|
||||
internal sealed unsafe class GatheringController : MiniTaskController<GatheringController>
|
||||
{
|
||||
private readonly MovementController _movementController;
|
||||
private readonly MoveTo.Factory _moveFactory;
|
||||
private readonly Mount.Factory _mountFactory;
|
||||
private readonly Interact.Factory _interactFactory;
|
||||
private readonly GatheringPointRegistry _gatheringPointRegistry;
|
||||
private readonly GameFunctions _gameFunctions;
|
||||
private readonly NavmeshIpc _navmeshIpc;
|
||||
private readonly IObjectTable _objectTable;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ICondition _condition;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly IGameGui _gameGui;
|
||||
private readonly IClientState _clientState;
|
||||
private readonly Regex _revisitRegex;
|
||||
|
||||
private CurrentRequest? _currentRequest;
|
||||
|
||||
public GatheringController(
|
||||
MovementController movementController,
|
||||
MoveTo.Factory moveFactory,
|
||||
Mount.Factory mountFactory,
|
||||
Interact.Factory interactFactory,
|
||||
GatheringPointRegistry gatheringPointRegistry,
|
||||
GameFunctions gameFunctions,
|
||||
NavmeshIpc navmeshIpc,
|
||||
IObjectTable objectTable,
|
||||
IChatGui chatGui,
|
||||
ILogger<GatheringController> logger,
|
||||
IServiceProvider serviceProvider,
|
||||
ICondition condition,
|
||||
IDataManager dataManager,
|
||||
ILoggerFactory loggerFactory,
|
||||
IGameGui gameGui,
|
||||
IClientState clientState,
|
||||
IPluginLog pluginLog)
|
||||
: base(chatGui, logger)
|
||||
{
|
||||
_movementController = movementController;
|
||||
_moveFactory = moveFactory;
|
||||
_mountFactory = mountFactory;
|
||||
_interactFactory = interactFactory;
|
||||
_gatheringPointRegistry = gatheringPointRegistry;
|
||||
_gameFunctions = gameFunctions;
|
||||
_navmeshIpc = navmeshIpc;
|
||||
_objectTable = objectTable;
|
||||
_serviceProvider = serviceProvider;
|
||||
_condition = condition;
|
||||
_loggerFactory = loggerFactory;
|
||||
_gameGui = gameGui;
|
||||
_clientState = clientState;
|
||||
|
||||
_revisitRegex = dataManager.GetRegex<LogMessage>(5574, x => x.Text, pluginLog)
|
||||
?? throw new InvalidDataException("No regex found for revisit message");
|
||||
@ -152,8 +168,7 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
|
||||
return;
|
||||
|
||||
ushort territoryId = _currentRequest.Root.Steps.Last().TerritoryId;
|
||||
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<MountTask>()
|
||||
.With(territoryId, MountTask.EMountIf.Always));
|
||||
_taskQueue.Enqueue(_mountFactory.Mount(territoryId, Mount.EMountIf.Always));
|
||||
|
||||
bool fly = currentNode.Fly.GetValueOrDefault(_currentRequest.Root.FlyBetweenNodes.GetValueOrDefault(true)) &&
|
||||
_gameFunctions.IsFlyingUnlocked(territoryId);
|
||||
@ -170,24 +185,28 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
|
||||
if (pointOnFloor != null)
|
||||
pointOnFloor = pointOnFloor.Value with { Y = pointOnFloor.Value.Y + (fly ? 3f : 0f) };
|
||||
|
||||
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<Move.MoveInternal>()
|
||||
.With(territoryId, pointOnFloor ?? averagePosition, 50f, fly: fly,
|
||||
ignoreDistanceToObject: true));
|
||||
_taskQueue.Enqueue(_moveFactory.Move(new MoveTo.MoveParams(territoryId, pointOnFloor ?? averagePosition,
|
||||
50f,
|
||||
Fly: fly, IgnoreDistanceToObject: true)));
|
||||
}
|
||||
|
||||
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<MoveToLandingLocation>()
|
||||
.With(territoryId, fly, currentNode));
|
||||
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<Interact.DoInteract>()
|
||||
.With(currentNode.DataId, null, EInteractionType.InternalGather, true));
|
||||
_taskQueue.Enqueue(new MoveToLandingLocation(territoryId, fly, currentNode, _moveFactory, _gameFunctions,
|
||||
_objectTable, _loggerFactory.CreateLogger<MoveToLandingLocation>()));
|
||||
_taskQueue.Enqueue(_interactFactory.Interact(currentNode.DataId, null, EInteractionType.InternalGather, true));
|
||||
|
||||
QueueGatherNode(currentNode);
|
||||
}
|
||||
|
||||
private void QueueGatherNode(GatheringNode currentNode)
|
||||
{
|
||||
foreach (bool revisitRequired in new[] { false, true })
|
||||
{
|
||||
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<DoGather>()
|
||||
.With(_currentRequest.Data, currentNode, revisitRequired));
|
||||
_taskQueue.Enqueue(new DoGather(_currentRequest!.Data, currentNode, revisitRequired, this, _gameFunctions,
|
||||
_gameGui, _clientState, _condition, _loggerFactory.CreateLogger<DoGather>()));
|
||||
if (_currentRequest.Data.Collectability > 0)
|
||||
{
|
||||
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<DoGatherCollectable>()
|
||||
.With(_currentRequest.Data, currentNode, revisitRequired));
|
||||
_taskQueue.Enqueue(new DoGatherCollectable(_currentRequest.Data, currentNode, revisitRequired, this,
|
||||
_gameFunctions, _clientState, _gameGui, _loggerFactory.CreateLogger<DoGatherCollectable>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,8 +151,9 @@ internal sealed class MovementController : IDisposable
|
||||
|
||||
if (IsPathRunning && Destination != null)
|
||||
{
|
||||
if (_gameFunctions.IsLoadingScreenVisible())
|
||||
if (_gameFunctions.IsLoadingScreenVisible(false))
|
||||
{
|
||||
_logger.LogInformation("Stopping movement, loading screen visible");
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
183
Questionable/Controller/Steps/Common/Mount.cs
Normal file
183
Questionable/Controller/Steps/Common/Mount.cs
Normal file
@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using FFXIVClientStructs.FFXIV.Common.Math;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Data;
|
||||
using Questionable.Functions;
|
||||
|
||||
namespace Questionable.Controller.Steps.Common;
|
||||
|
||||
internal static class Mount
|
||||
{
|
||||
internal sealed class Factory(
|
||||
GameFunctions gameFunctions,
|
||||
ICondition condition,
|
||||
TerritoryData territoryData,
|
||||
IClientState clientState,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
public ITask Mount(ushort territoryId, EMountIf mountIf, Vector3? position = null)
|
||||
{
|
||||
if (mountIf == EMountIf.AwayFromPosition)
|
||||
ArgumentNullException.ThrowIfNull(position);
|
||||
|
||||
return new MountTask(territoryId, mountIf, position, gameFunctions, condition, territoryData, clientState,
|
||||
loggerFactory.CreateLogger<MountTask>());
|
||||
}
|
||||
|
||||
public ITask Unmount()
|
||||
{
|
||||
return new UnmountTask(condition, loggerFactory.CreateLogger<UnmountTask>(), gameFunctions);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class MountTask(
|
||||
ushort territoryId,
|
||||
EMountIf mountIf,
|
||||
Vector3? position,
|
||||
GameFunctions gameFunctions,
|
||||
ICondition condition,
|
||||
TerritoryData territoryData,
|
||||
IClientState clientState,
|
||||
ILogger<MountTask> logger) : ITask
|
||||
{
|
||||
private bool _mountTriggered;
|
||||
private DateTime _retryAt = DateTime.MinValue;
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (condition[ConditionFlag.Mounted])
|
||||
return false;
|
||||
|
||||
if (!territoryData.CanUseMount(territoryId))
|
||||
{
|
||||
logger.LogInformation("Can't use mount in current territory {Id}", territoryId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gameFunctions.HasStatusPreventingMount())
|
||||
{
|
||||
logger.LogInformation("Can't mount due to status preventing sprint or mount");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mountIf == EMountIf.AwayFromPosition)
|
||||
{
|
||||
Vector3 playerPosition = clientState.LocalPlayer?.Position ?? Vector3.Zero;
|
||||
float distance = System.Numerics.Vector3.Distance(playerPosition, position.GetValueOrDefault());
|
||||
if (territoryId == clientState.TerritoryType && distance < 30f && !Conditions.IsDiving)
|
||||
{
|
||||
logger.LogInformation("Not using mount, as we're close to the target");
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.LogInformation(
|
||||
"Want to use mount if away from destination ({Distance} yalms), trying (in territory {Id})...",
|
||||
distance, territoryId);
|
||||
}
|
||||
else
|
||||
logger.LogInformation("Want to use mount, trying (in territory {Id})...", territoryId);
|
||||
|
||||
if (!condition[ConditionFlag.InCombat])
|
||||
{
|
||||
_retryAt = DateTime.Now.AddSeconds(0.5);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (_mountTriggered && !condition[ConditionFlag.Mounted] && DateTime.Now > _retryAt)
|
||||
{
|
||||
logger.LogInformation("Not mounted, retrying...");
|
||||
_mountTriggered = false;
|
||||
_retryAt = DateTime.MaxValue;
|
||||
}
|
||||
|
||||
if (!_mountTriggered)
|
||||
{
|
||||
if (gameFunctions.HasStatusPreventingMount())
|
||||
{
|
||||
logger.LogInformation("Can't mount due to status preventing sprint or mount");
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
_mountTriggered = gameFunctions.Mount();
|
||||
_retryAt = DateTime.Now.AddSeconds(5);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
return condition[ConditionFlag.Mounted]
|
||||
? ETaskResult.TaskComplete
|
||||
: ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
public override string ToString() => "Mount";
|
||||
}
|
||||
|
||||
private sealed class UnmountTask(ICondition condition, ILogger<UnmountTask> logger, GameFunctions gameFunctions)
|
||||
: ITask
|
||||
{
|
||||
private bool _unmountTriggered;
|
||||
private DateTime _continueAt = DateTime.MinValue;
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!condition[ConditionFlag.Mounted])
|
||||
return false;
|
||||
|
||||
logger.LogInformation("Step explicitly wants no mount, trying to unmount...");
|
||||
if (condition[ConditionFlag.InFlight])
|
||||
{
|
||||
gameFunctions.Unmount();
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
_unmountTriggered = gameFunctions.Unmount();
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (_continueAt >= DateTime.Now)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
if (!_unmountTriggered)
|
||||
{
|
||||
// if still flying, we still need to land
|
||||
if (condition[ConditionFlag.InFlight])
|
||||
gameFunctions.Unmount();
|
||||
else
|
||||
_unmountTriggered = gameFunctions.Unmount();
|
||||
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
if (condition[ConditionFlag.Mounted] && condition[ConditionFlag.InCombat])
|
||||
{
|
||||
_unmountTriggered = gameFunctions.Unmount();
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
return condition[ConditionFlag.Mounted]
|
||||
? ETaskResult.StillRunning
|
||||
: ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => "Unmount";
|
||||
}
|
||||
|
||||
public enum EMountIf
|
||||
{
|
||||
Always,
|
||||
AwayFromPosition,
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Data;
|
||||
using Questionable.Functions;
|
||||
|
||||
namespace Questionable.Controller.Steps.Common;
|
||||
|
||||
internal sealed class MountTask(
|
||||
GameFunctions gameFunctions,
|
||||
ICondition condition,
|
||||
TerritoryData territoryData,
|
||||
IClientState clientState,
|
||||
ILogger<MountTask> logger) : ITask
|
||||
{
|
||||
private ushort _territoryId;
|
||||
private EMountIf _mountIf;
|
||||
private Vector3? _position;
|
||||
|
||||
private bool _mountTriggered;
|
||||
private DateTime _retryAt = DateTime.MinValue;
|
||||
|
||||
public ITask With(ushort territoryId, EMountIf mountIf, Vector3? position = null)
|
||||
{
|
||||
_territoryId = territoryId;
|
||||
_mountIf = mountIf;
|
||||
_position = position;
|
||||
|
||||
if (_mountIf == EMountIf.AwayFromPosition)
|
||||
ArgumentNullException.ThrowIfNull(position);
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (condition[ConditionFlag.Mounted])
|
||||
return false;
|
||||
|
||||
if (!territoryData.CanUseMount(_territoryId))
|
||||
{
|
||||
logger.LogInformation("Can't use mount in current territory {Id}", _territoryId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gameFunctions.HasStatusPreventingMount())
|
||||
{
|
||||
logger.LogInformation("Can't mount due to status preventing sprint or mount");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_mountIf == EMountIf.AwayFromPosition)
|
||||
{
|
||||
Vector3 playerPosition = clientState.LocalPlayer?.Position ?? Vector3.Zero;
|
||||
float distance = (playerPosition - _position.GetValueOrDefault()).Length();
|
||||
if (_territoryId == clientState.TerritoryType && distance < 30f && !Conditions.IsDiving)
|
||||
{
|
||||
logger.LogInformation("Not using mount, as we're close to the target");
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.LogInformation(
|
||||
"Want to use mount if away from destination ({Distance} yalms), trying (in territory {Id})...",
|
||||
distance, _territoryId);
|
||||
}
|
||||
else
|
||||
logger.LogInformation("Want to use mount, trying (in territory {Id})...", _territoryId);
|
||||
|
||||
if (!condition[ConditionFlag.InCombat])
|
||||
{
|
||||
_retryAt = DateTime.Now.AddSeconds(0.5);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (_mountTriggered && !condition[ConditionFlag.Mounted] && DateTime.Now > _retryAt)
|
||||
{
|
||||
logger.LogInformation("Not mounted, retrying...");
|
||||
_mountTriggered = false;
|
||||
_retryAt = DateTime.MaxValue;
|
||||
}
|
||||
|
||||
if (!_mountTriggered)
|
||||
{
|
||||
if (gameFunctions.HasStatusPreventingMount())
|
||||
{
|
||||
logger.LogInformation("Can't mount due to status preventing sprint or mount");
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
_mountTriggered = gameFunctions.Mount();
|
||||
_retryAt = DateTime.Now.AddSeconds(5);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
return condition[ConditionFlag.Mounted]
|
||||
? ETaskResult.TaskComplete
|
||||
: ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
public override string ToString() => "Mount";
|
||||
|
||||
public enum EMountIf
|
||||
{
|
||||
Always,
|
||||
AwayFromPosition,
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
@ -9,7 +7,7 @@ namespace Questionable.Controller.Steps.Common;
|
||||
|
||||
internal static class NextQuest
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(QuestRegistry questRegistry, QuestController questController, QuestFunctions questFunctions, ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -22,37 +20,26 @@ internal static class NextQuest
|
||||
if (step.NextQuestId == quest.Id)
|
||||
return null;
|
||||
|
||||
return serviceProvider.GetRequiredService<SetQuest>()
|
||||
.With(step.NextQuestId, quest.Id);
|
||||
return new SetQuest(step.NextQuestId, quest.Id, questRegistry, questController, questFunctions, loggerFactory.CreateLogger<SetQuest>());
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class SetQuest(QuestRegistry questRegistry, QuestController questController, QuestFunctions questFunctions, ILogger<SetQuest> logger) : ITask
|
||||
private sealed class SetQuest(ElementId nextQuestId, ElementId currentQuestId, QuestRegistry questRegistry, QuestController questController, QuestFunctions questFunctions, ILogger<SetQuest> logger) : ITask
|
||||
{
|
||||
public ElementId NextQuestId { get; set; } = null!;
|
||||
public ElementId CurrentQuestId { get; set; } = null!;
|
||||
|
||||
public ITask With(ElementId nextQuestId, ElementId currentQuestId)
|
||||
{
|
||||
NextQuestId = nextQuestId;
|
||||
CurrentQuestId = currentQuestId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (questFunctions.IsQuestLocked(NextQuestId, CurrentQuestId))
|
||||
if (questFunctions.IsQuestLocked(nextQuestId, currentQuestId))
|
||||
{
|
||||
logger.LogInformation("Can't set next quest to {QuestId}, quest is locked", NextQuestId);
|
||||
logger.LogInformation("Can't set next quest to {QuestId}, quest is locked", nextQuestId);
|
||||
}
|
||||
else if (questRegistry.TryGetQuest(NextQuestId, out Quest? quest))
|
||||
else if (questRegistry.TryGetQuest(nextQuestId, out Quest? quest))
|
||||
{
|
||||
logger.LogInformation("Setting next quest to {QuestId}: '{QuestName}'", NextQuestId, quest.Info.Name);
|
||||
logger.LogInformation("Setting next quest to {QuestId}: '{QuestName}'", nextQuestId, quest.Info.Name);
|
||||
questController.SetNextQuest(quest);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("Next quest with id {QuestId} not found", NextQuestId);
|
||||
logger.LogInformation("Next quest with id {QuestId} not found", nextQuestId);
|
||||
questController.SetNextQuest(null);
|
||||
}
|
||||
|
||||
@ -61,6 +48,6 @@ internal static class NextQuest
|
||||
|
||||
public ETaskResult Update() => ETaskResult.TaskComplete;
|
||||
|
||||
public override string ToString() => $"SetNextQuest({NextQuestId})";
|
||||
public override string ToString() => $"SetNextQuest({nextQuestId})";
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
using System;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Functions;
|
||||
|
||||
namespace Questionable.Controller.Steps.Common;
|
||||
|
||||
internal sealed class UnmountTask(ICondition condition, ILogger<UnmountTask> logger, GameFunctions gameFunctions)
|
||||
: ITask
|
||||
{
|
||||
private bool _unmountTriggered;
|
||||
private DateTime _continueAt = DateTime.MinValue;
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!condition[ConditionFlag.Mounted])
|
||||
return false;
|
||||
|
||||
logger.LogInformation("Step explicitly wants no mount, trying to unmount...");
|
||||
if (condition[ConditionFlag.InFlight])
|
||||
{
|
||||
gameFunctions.Unmount();
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
_unmountTriggered = gameFunctions.Unmount();
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (_continueAt >= DateTime.Now)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
if (!_unmountTriggered)
|
||||
{
|
||||
// if still flying, we still need to land
|
||||
if (condition[ConditionFlag.InFlight])
|
||||
gameFunctions.Unmount();
|
||||
else
|
||||
_unmountTriggered = gameFunctions.Unmount();
|
||||
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
if (condition[ConditionFlag.Mounted] && condition[ConditionFlag.InCombat])
|
||||
{
|
||||
_unmountTriggered = gameFunctions.Unmount();
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
return condition[ConditionFlag.Mounted]
|
||||
? ETaskResult.StillRunning
|
||||
: ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => "Unmount";
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Memory;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
@ -17,6 +16,9 @@ using Questionable.Model.Questing;
|
||||
namespace Questionable.Controller.Steps.Gathering;
|
||||
|
||||
internal sealed class DoGather(
|
||||
GatheringController.GatheringRequest currentRequest,
|
||||
GatheringNode currentNode,
|
||||
bool revisitRequired,
|
||||
GatheringController gatheringController,
|
||||
GameFunctions gameFunctions,
|
||||
IGameGui gameGui,
|
||||
@ -26,34 +28,22 @@ internal sealed class DoGather(
|
||||
{
|
||||
private const uint StatusGatheringRateUp = 218;
|
||||
|
||||
private GatheringController.GatheringRequest _currentRequest = null!;
|
||||
private GatheringNode _currentNode = null!;
|
||||
private bool _revisitRequired;
|
||||
private bool _revisitTriggered;
|
||||
private bool _wasGathering;
|
||||
private SlotInfo? _slotToGather;
|
||||
private Queue<EAction>? _actionQueue;
|
||||
|
||||
public ITask With(GatheringController.GatheringRequest currentRequest, GatheringNode currentNode,
|
||||
bool revisitRequired)
|
||||
{
|
||||
_currentRequest = currentRequest;
|
||||
_currentNode = currentNode;
|
||||
_revisitRequired = revisitRequired;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start() => true;
|
||||
|
||||
public unsafe ETaskResult Update()
|
||||
{
|
||||
if (_revisitRequired && !_revisitTriggered)
|
||||
if (revisitRequired && !_revisitTriggered)
|
||||
{
|
||||
logger.LogInformation("No revisit");
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
if (gatheringController.HasNodeDisappeared(_currentNode))
|
||||
if (gatheringController.HasNodeDisappeared(currentNode))
|
||||
{
|
||||
logger.LogInformation("Node disappeared");
|
||||
return ETaskResult.TaskComplete;
|
||||
@ -78,9 +68,9 @@ internal sealed class DoGather(
|
||||
else
|
||||
{
|
||||
var slots = ReadSlots(addonGathering);
|
||||
if (_currentRequest.Collectability > 0)
|
||||
if (currentRequest.Collectability > 0)
|
||||
{
|
||||
var slot = slots.Single(x => x.ItemId == _currentRequest.ItemId);
|
||||
var slot = slots.Single(x => x.ItemId == currentRequest.ItemId);
|
||||
addonGathering->FireCallbackInt(slot.Index);
|
||||
}
|
||||
else
|
||||
@ -103,7 +93,7 @@ internal sealed class DoGather(
|
||||
_actionQueue = GetNextActions(nodeCondition, slots);
|
||||
if (_actionQueue.Count == 0)
|
||||
{
|
||||
var slot = _slotToGather ?? slots.Single(x => x.ItemId == _currentRequest.ItemId);
|
||||
var slot = _slotToGather ?? slots.Single(x => x.ItemId == currentRequest.ItemId);
|
||||
addonGathering->FireCallbackInt(slot.Index);
|
||||
}
|
||||
}
|
||||
@ -149,17 +139,18 @@ internal sealed class DoGather(
|
||||
return slots;
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedParameter.Local")]
|
||||
private Queue<EAction> GetNextActions(NodeCondition nodeCondition, List<SlotInfo> slots)
|
||||
{
|
||||
uint gp = clientState.LocalPlayer!.CurrentGp;
|
||||
//uint gp = clientState.LocalPlayer!.CurrentGp;
|
||||
Queue<EAction> actions = new();
|
||||
|
||||
if (!gameFunctions.HasStatus(StatusGatheringRateUp))
|
||||
{
|
||||
// do we have an alternative item? only happens for 'evaluation' leve quests
|
||||
if (_currentRequest.AlternativeItemId != 0)
|
||||
if (currentRequest.AlternativeItemId != 0)
|
||||
{
|
||||
var alternativeSlot = slots.Single(x => x.ItemId == _currentRequest.AlternativeItemId);
|
||||
var alternativeSlot = slots.Single(x => x.ItemId == currentRequest.AlternativeItemId);
|
||||
|
||||
if (alternativeSlot.GatheringChance == 100)
|
||||
{
|
||||
@ -195,7 +186,7 @@ internal sealed class DoGather(
|
||||
}
|
||||
}
|
||||
|
||||
var slot = slots.Single(x => x.ItemId == _currentRequest.ItemId);
|
||||
var slot = slots.Single(x => x.ItemId == currentRequest.ItemId);
|
||||
if (slot.GatheringChance > 0 && slot.GatheringChance < 100)
|
||||
{
|
||||
if (slot.GatheringChance >= 95 &&
|
||||
@ -243,10 +234,12 @@ internal sealed class DoGather(
|
||||
_revisitTriggered = true;
|
||||
}
|
||||
|
||||
public override string ToString() => $"DoGather{(_revisitRequired ? " if revist" : "")}";
|
||||
public override string ToString() => $"DoGather{(revisitRequired ? " if revist" : "")}";
|
||||
|
||||
[SuppressMessage("ReSharper", "NotAccessedPositionalProperty.Local")]
|
||||
private sealed record SlotInfo(int Index, uint ItemId, int GatheringChance, int BoonChance, int Quantity);
|
||||
|
||||
[SuppressMessage("ReSharper", "NotAccessedPositionalProperty.Local")]
|
||||
private sealed record NodeCondition(
|
||||
uint CurrentIntegrity,
|
||||
uint MaxIntegrity);
|
||||
|
@ -14,40 +14,31 @@ using Questionable.Model.Questing;
|
||||
namespace Questionable.Controller.Steps.Gathering;
|
||||
|
||||
internal sealed class DoGatherCollectable(
|
||||
GatheringController.GatheringRequest currentRequest,
|
||||
GatheringNode currentNode,
|
||||
bool revisitRequired,
|
||||
GatheringController gatheringController,
|
||||
GameFunctions gameFunctions,
|
||||
IClientState clientState,
|
||||
IGameGui gameGui,
|
||||
ILogger<DoGatherCollectable> logger) : ITask, IRevisitAware
|
||||
{
|
||||
private GatheringController.GatheringRequest _currentRequest = null!;
|
||||
private GatheringNode _currentNode = null!;
|
||||
private bool _revisitRequired;
|
||||
private bool _revisitTriggered;
|
||||
private Queue<EAction>? _actionQueue;
|
||||
|
||||
private bool? _expectedScrutiny;
|
||||
|
||||
public ITask With(GatheringController.GatheringRequest currentRequest, GatheringNode currentNode,
|
||||
bool revisitRequired)
|
||||
{
|
||||
_currentRequest = currentRequest;
|
||||
_currentNode = currentNode;
|
||||
_revisitRequired = revisitRequired;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start() => true;
|
||||
|
||||
public unsafe ETaskResult Update()
|
||||
{
|
||||
if (_revisitRequired && !_revisitTriggered)
|
||||
if (revisitRequired && !_revisitTriggered)
|
||||
{
|
||||
logger.LogInformation("No revisit");
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
if (gatheringController.HasNodeDisappeared(_currentNode))
|
||||
if (gatheringController.HasNodeDisappeared(currentNode))
|
||||
{
|
||||
logger.LogInformation("Node disappeared");
|
||||
return ETaskResult.TaskComplete;
|
||||
@ -103,7 +94,7 @@ internal sealed class DoGatherCollectable(
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
if (nodeCondition.CollectabilityToGoal(_currentRequest.Collectability) > 0)
|
||||
if (nodeCondition.CollectabilityToGoal(currentRequest.Collectability) > 0)
|
||||
{
|
||||
_actionQueue = GetNextActions(nodeCondition);
|
||||
if (_actionQueue != null)
|
||||
@ -147,7 +138,7 @@ internal sealed class DoGatherCollectable(
|
||||
|
||||
Queue<EAction> actions = new();
|
||||
|
||||
uint neededCollectability = nodeCondition.CollectabilityToGoal(_currentRequest.Collectability);
|
||||
uint neededCollectability = nodeCondition.CollectabilityToGoal(currentRequest.Collectability);
|
||||
if (neededCollectability <= nodeCondition.CollectabilityFromMeticulous)
|
||||
{
|
||||
logger.LogTrace("Can get all needed {NeededCollectability} from {Collectability}~ meticulous",
|
||||
@ -203,7 +194,7 @@ internal sealed class DoGatherCollectable(
|
||||
}
|
||||
|
||||
public override string ToString() =>
|
||||
$"DoGatherCollectable({SeIconChar.Collectible.ToIconString()}/{_expectedScrutiny} {_currentRequest.Collectability}){(_revisitRequired ? " if revist" : "")}";
|
||||
$"DoGatherCollectable({SeIconChar.Collectible.ToIconString()}/{_expectedScrutiny} {currentRequest.Collectability}){(revisitRequired ? " if revist" : "")}";
|
||||
|
||||
[SuppressMessage("ReSharper", "NotAccessedPositionalProperty.Local")]
|
||||
private sealed record NodeCondition(
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Game.ClientState.Objects.Enums;
|
||||
@ -14,49 +13,40 @@ using Questionable.Model.Gathering;
|
||||
namespace Questionable.Controller.Steps.Gathering;
|
||||
|
||||
internal sealed class MoveToLandingLocation(
|
||||
IServiceProvider serviceProvider,
|
||||
ushort territoryId,
|
||||
bool flyBetweenNodes,
|
||||
GatheringNode gatheringNode,
|
||||
MoveTo.Factory moveFactory,
|
||||
GameFunctions gameFunctions,
|
||||
IObjectTable objectTable,
|
||||
ILogger<MoveToLandingLocation> logger) : ITask
|
||||
{
|
||||
private ushort _territoryId;
|
||||
private bool _flyBetweenNodes;
|
||||
private GatheringNode _gatheringNode = null!;
|
||||
private ITask _moveTask = null!;
|
||||
|
||||
public ITask With(ushort territoryId, bool flyBetweenNodes, GatheringNode gatheringNode)
|
||||
{
|
||||
_territoryId = territoryId;
|
||||
_flyBetweenNodes = flyBetweenNodes;
|
||||
_gatheringNode = gatheringNode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
var location = _gatheringNode.Locations.First();
|
||||
if (_gatheringNode.Locations.Count > 1)
|
||||
var location = gatheringNode.Locations.First();
|
||||
if (gatheringNode.Locations.Count > 1)
|
||||
{
|
||||
var gameObject = objectTable.SingleOrDefault(x =>
|
||||
x.ObjectKind == ObjectKind.GatheringPoint && x.DataId == _gatheringNode.DataId && x.IsTargetable);
|
||||
x.ObjectKind == ObjectKind.GatheringPoint && x.DataId == gatheringNode.DataId && x.IsTargetable);
|
||||
if (gameObject == null)
|
||||
return false;
|
||||
|
||||
location = _gatheringNode.Locations.Single(x => Vector3.Distance(x.Position, gameObject.Position) < 0.1f);
|
||||
location = gatheringNode.Locations.Single(x => Vector3.Distance(x.Position, gameObject.Position) < 0.1f);
|
||||
}
|
||||
|
||||
var (target, degrees, range) = GatheringMath.CalculateLandingLocation(location);
|
||||
logger.LogInformation("Preliminary landing location: {Location}, with degrees = {Degrees}, range = {Range}",
|
||||
target.ToString("G", CultureInfo.InvariantCulture), degrees, range);
|
||||
|
||||
bool fly = _flyBetweenNodes && gameFunctions.IsFlyingUnlocked(_territoryId);
|
||||
_moveTask = serviceProvider.GetRequiredService<Move.MoveInternal>()
|
||||
.With(_territoryId, target, 0.25f, dataId: _gatheringNode.DataId, fly: fly,
|
||||
ignoreDistanceToObject: true);
|
||||
bool fly = flyBetweenNodes && gameFunctions.IsFlyingUnlocked(territoryId);
|
||||
_moveTask = moveFactory.Move(new MoveTo.MoveParams(territoryId, target, 0.25f, DataId: gatheringNode.DataId,
|
||||
Fly: fly, IgnoreDistanceToObject: true));
|
||||
return _moveTask.Start();
|
||||
}
|
||||
|
||||
public ETaskResult Update() => _moveTask.Update();
|
||||
|
||||
public override string ToString() => $"Land/{_moveTask}/{_flyBetweenNodes}";
|
||||
public override string ToString() => $"Land/{_moveTask}/{flyBetweenNodes}";
|
||||
}
|
||||
|
@ -13,18 +13,18 @@ namespace Questionable.Controller.Steps.Gathering;
|
||||
|
||||
internal static class TurnInDelivery
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (quest.Id is not SatisfactionSupplyNpcId || sequence.Sequence != 1)
|
||||
return null;
|
||||
|
||||
return serviceProvider.GetRequiredService<SatisfactionSupplyTurnIn>();
|
||||
return new SatisfactionSupplyTurnIn(loggerFactory.CreateLogger<SatisfactionSupplyTurnIn>());
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class SatisfactionSupplyTurnIn(ILogger<SatisfactionSupplyTurnIn> logger) : ITask
|
||||
private sealed class SatisfactionSupplyTurnIn(ILogger<SatisfactionSupplyTurnIn> logger) : ITask
|
||||
{
|
||||
private ushort? _remainingAllowances;
|
||||
|
||||
|
@ -14,7 +14,8 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Action
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory
|
||||
internal sealed class Factory(GameFunctions gameFunctions, Mount.Factory mountFactory, ILoggerFactory loggerFactory)
|
||||
: ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -23,54 +24,45 @@ internal static class Action
|
||||
|
||||
ArgumentNullException.ThrowIfNull(step.Action);
|
||||
|
||||
var task = serviceProvider.GetRequiredService<UseOnObject>()
|
||||
.With(step.DataId, step.Action.Value);
|
||||
var task = new UseOnObject(step.DataId, step.Action.Value, gameFunctions,
|
||||
loggerFactory.CreateLogger<UseOnObject>());
|
||||
if (step.Action.Value.RequiresMount())
|
||||
return [task];
|
||||
else
|
||||
{
|
||||
var unmount = serviceProvider.GetRequiredService<UnmountTask>();
|
||||
return [unmount, task];
|
||||
}
|
||||
return [mountFactory.Unmount(), task];
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class UseOnObject(GameFunctions gameFunctions, ILogger<UseOnObject> logger) : ITask
|
||||
private sealed class UseOnObject(
|
||||
uint? dataId,
|
||||
EAction action,
|
||||
GameFunctions gameFunctions,
|
||||
ILogger<UseOnObject> logger) : ITask
|
||||
{
|
||||
private bool _usedAction;
|
||||
private DateTime _continueAt = DateTime.MinValue;
|
||||
|
||||
public uint? DataId { get; set; }
|
||||
public EAction Action { get; set; }
|
||||
|
||||
public ITask With(uint? dataId, EAction action)
|
||||
{
|
||||
DataId = dataId;
|
||||
Action = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (DataId != null)
|
||||
if (dataId != null)
|
||||
{
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId.Value);
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId.Value);
|
||||
if (gameObject == null)
|
||||
{
|
||||
logger.LogWarning("No game object with dataId {DataId}", DataId);
|
||||
logger.LogWarning("No game object with dataId {DataId}", dataId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gameObject.IsTargetable)
|
||||
{
|
||||
_usedAction = gameFunctions.UseAction(gameObject, Action);
|
||||
_usedAction = gameFunctions.UseAction(gameObject, action);
|
||||
_continueAt = DateTime.Now.AddSeconds(0.5);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_usedAction = gameFunctions.UseAction(Action);
|
||||
_usedAction = gameFunctions.UseAction(action);
|
||||
_continueAt = DateTime.Now.AddSeconds(0.5);
|
||||
return true;
|
||||
}
|
||||
@ -85,18 +77,18 @@ internal static class Action
|
||||
|
||||
if (!_usedAction)
|
||||
{
|
||||
if (DataId != null)
|
||||
if (dataId != null)
|
||||
{
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId.Value);
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId.Value);
|
||||
if (gameObject == null || !gameObject.IsTargetable)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
_usedAction = gameFunctions.UseAction(gameObject, Action);
|
||||
_usedAction = gameFunctions.UseAction(gameObject, action);
|
||||
_continueAt = DateTime.Now.AddSeconds(0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
_usedAction = gameFunctions.UseAction(Action);
|
||||
_usedAction = gameFunctions.UseAction(action);
|
||||
_continueAt = DateTime.Now.AddSeconds(0.5);
|
||||
}
|
||||
|
||||
@ -106,6 +98,6 @@ internal static class Action
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Action({Action})";
|
||||
public override string ToString() => $"Action({action})";
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,11 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class AetherCurrent
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider, AetherCurrentData aetherCurrentData, IChatGui chatGui) : SimpleTaskFactory
|
||||
internal sealed class Factory(
|
||||
GameFunctions gameFunctions,
|
||||
AetherCurrentData aetherCurrentData,
|
||||
IChatGui chatGui,
|
||||
ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -23,47 +27,37 @@ internal static class AetherCurrent
|
||||
|
||||
if (!aetherCurrentData.IsValidAetherCurrent(step.TerritoryId, step.AetherCurrentId.Value))
|
||||
{
|
||||
chatGui.PrintError($"[Questionable] Aether current with id {step.AetherCurrentId} is referencing an invalid aether current, will skip attunement");
|
||||
chatGui.PrintError(
|
||||
$"[Questionable] Aether current with id {step.AetherCurrentId} is referencing an invalid aether current, will skip attunement");
|
||||
return null;
|
||||
}
|
||||
|
||||
return serviceProvider.GetRequiredService<DoAttune>()
|
||||
.With(step.DataId.Value, step.AetherCurrentId.Value);
|
||||
return new DoAttune(step.DataId.Value, step.AetherCurrentId.Value, gameFunctions, loggerFactory.CreateLogger<DoAttune>());
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DoAttune(GameFunctions gameFunctions, ILogger<DoAttune> logger) : ITask
|
||||
private sealed class DoAttune(uint dataId, uint aetherCurrentId, GameFunctions gameFunctions, ILogger<DoAttune> logger) : ITask
|
||||
{
|
||||
public uint DataId { get; set; }
|
||||
public uint AetherCurrentId { get; set; }
|
||||
|
||||
public ITask With(uint dataId, uint aetherCurrentId)
|
||||
{
|
||||
DataId = dataId;
|
||||
AetherCurrentId = aetherCurrentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!gameFunctions.IsAetherCurrentUnlocked(AetherCurrentId))
|
||||
if (!gameFunctions.IsAetherCurrentUnlocked(aetherCurrentId))
|
||||
{
|
||||
logger.LogInformation("Attuning to aether current {AetherCurrentId} / {DataId}", AetherCurrentId,
|
||||
DataId);
|
||||
gameFunctions.InteractWith(DataId);
|
||||
logger.LogInformation("Attuning to aether current {AetherCurrentId} / {DataId}", aetherCurrentId,
|
||||
dataId);
|
||||
gameFunctions.InteractWith(dataId);
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.LogInformation("Already attuned to aether current {AetherCurrentId} / {DataId}", AetherCurrentId,
|
||||
DataId);
|
||||
logger.LogInformation("Already attuned to aether current {AetherCurrentId} / {DataId}", aetherCurrentId,
|
||||
dataId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public ETaskResult Update() =>
|
||||
gameFunctions.IsAetherCurrentUnlocked(AetherCurrentId)
|
||||
gameFunctions.IsAetherCurrentUnlocked(aetherCurrentId)
|
||||
? ETaskResult.TaskComplete
|
||||
: ETaskResult.StillRunning;
|
||||
|
||||
public override string ToString() => $"AttuneAetherCurrent({AetherCurrentId})";
|
||||
public override string ToString() => $"AttuneAetherCurrent({aetherCurrentId})";
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,10 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class AethernetShard
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
GameFunctions gameFunctions,
|
||||
ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -20,42 +23,35 @@ internal static class AethernetShard
|
||||
|
||||
ArgumentNullException.ThrowIfNull(step.AethernetShard);
|
||||
|
||||
return serviceProvider.GetRequiredService<DoAttune>()
|
||||
.With(step.AethernetShard.Value);
|
||||
return new DoAttune(step.AethernetShard.Value, aetheryteFunctions, gameFunctions,
|
||||
loggerFactory.CreateLogger<DoAttune>());
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DoAttune(
|
||||
private sealed class DoAttune(
|
||||
EAetheryteLocation aetheryteLocation,
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
GameFunctions gameFunctions,
|
||||
ILogger<DoAttune> logger) : ITask
|
||||
{
|
||||
public EAetheryteLocation AetheryteLocation { get; set; }
|
||||
|
||||
public ITask With(EAetheryteLocation aetheryteLocation)
|
||||
{
|
||||
AetheryteLocation = aetheryteLocation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!aetheryteFunctions.IsAetheryteUnlocked(AetheryteLocation))
|
||||
if (!aetheryteFunctions.IsAetheryteUnlocked(aetheryteLocation))
|
||||
{
|
||||
logger.LogInformation("Attuning to aethernet shard {AethernetShard}", AetheryteLocation);
|
||||
gameFunctions.InteractWith((uint)AetheryteLocation, ObjectKind.Aetheryte);
|
||||
logger.LogInformation("Attuning to aethernet shard {AethernetShard}", aetheryteLocation);
|
||||
gameFunctions.InteractWith((uint)aetheryteLocation, ObjectKind.Aetheryte);
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.LogInformation("Already attuned to aethernet shard {AethernetShard}", AetheryteLocation);
|
||||
logger.LogInformation("Already attuned to aethernet shard {AethernetShard}", aetheryteLocation);
|
||||
return false;
|
||||
}
|
||||
|
||||
public ETaskResult Update() =>
|
||||
aetheryteFunctions.IsAetheryteUnlocked(AetheryteLocation)
|
||||
aetheryteFunctions.IsAetheryteUnlocked(aetheryteLocation)
|
||||
? ETaskResult.TaskComplete
|
||||
: ETaskResult.StillRunning;
|
||||
|
||||
public override string ToString() => $"AttuneAethernetShard({AetheryteLocation})";
|
||||
public override string ToString() => $"AttuneAethernetShard({aetheryteLocation})";
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,10 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Aetheryte
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
GameFunctions gameFunctions,
|
||||
ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -19,42 +22,35 @@ internal static class Aetheryte
|
||||
|
||||
ArgumentNullException.ThrowIfNull(step.Aetheryte);
|
||||
|
||||
return serviceProvider.GetRequiredService<DoAttune>()
|
||||
.With(step.Aetheryte.Value);
|
||||
return new DoAttune(step.Aetheryte.Value, aetheryteFunctions, gameFunctions,
|
||||
loggerFactory.CreateLogger<DoAttune>());
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DoAttune(
|
||||
private sealed class DoAttune(
|
||||
EAetheryteLocation aetheryteLocation,
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
GameFunctions gameFunctions,
|
||||
ILogger<DoAttune> logger) : ITask
|
||||
{
|
||||
public EAetheryteLocation AetheryteLocation { get; set; }
|
||||
|
||||
public ITask With(EAetheryteLocation aetheryteLocation)
|
||||
{
|
||||
AetheryteLocation = aetheryteLocation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!aetheryteFunctions.IsAetheryteUnlocked(AetheryteLocation))
|
||||
if (!aetheryteFunctions.IsAetheryteUnlocked(aetheryteLocation))
|
||||
{
|
||||
logger.LogInformation("Attuning to aetheryte {Aetheryte}", AetheryteLocation);
|
||||
gameFunctions.InteractWith((uint)AetheryteLocation);
|
||||
logger.LogInformation("Attuning to aetheryte {Aetheryte}", aetheryteLocation);
|
||||
gameFunctions.InteractWith((uint)aetheryteLocation);
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.LogInformation("Already attuned to aetheryte {Aetheryte}", AetheryteLocation);
|
||||
logger.LogInformation("Already attuned to aetheryte {Aetheryte}", aetheryteLocation);
|
||||
return false;
|
||||
}
|
||||
|
||||
public ETaskResult Update() =>
|
||||
aetheryteFunctions.IsAetheryteUnlocked(AetheryteLocation)
|
||||
aetheryteFunctions.IsAetheryteUnlocked(aetheryteLocation)
|
||||
? ETaskResult.TaskComplete
|
||||
: ETaskResult.StillRunning;
|
||||
|
||||
public override string ToString() => $"AttuneAetheryte({AetheryteLocation})";
|
||||
public override string ToString() => $"AttuneAetheryte({aetheryteLocation})";
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,12 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Combat
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory
|
||||
internal sealed class Factory(
|
||||
CombatController combatController,
|
||||
Interact.Factory interactFactory,
|
||||
Mount.Factory mountFactory,
|
||||
UseItem.Factory useItemFactory,
|
||||
QuestFunctions questFunctions) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -22,12 +27,11 @@ internal static class Combat
|
||||
|
||||
ArgumentNullException.ThrowIfNull(step.EnemySpawnType);
|
||||
|
||||
yield return serviceProvider.GetRequiredService<UnmountTask>();
|
||||
yield return mountFactory.Unmount();
|
||||
|
||||
if (step.CombatDelaySecondsAtStart != null)
|
||||
{
|
||||
yield return serviceProvider.GetRequiredService<WaitAtStart.WaitDelay>()
|
||||
.With(TimeSpan.FromSeconds(step.CombatDelaySecondsAtStart.Value));
|
||||
yield return new WaitAtStart.WaitDelay(TimeSpan.FromSeconds(step.CombatDelaySecondsAtStart.Value));
|
||||
}
|
||||
|
||||
switch (step.EnemySpawnType)
|
||||
@ -36,8 +40,7 @@ internal static class Combat
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(step.DataId);
|
||||
|
||||
yield return serviceProvider.GetRequiredService<Interact.DoInteract>()
|
||||
.With(step.DataId.Value, quest, EInteractionType.None, true);
|
||||
yield return interactFactory.Interact(step.DataId.Value, quest, EInteractionType.None, true);
|
||||
yield return CreateTask(quest, sequence, step);
|
||||
break;
|
||||
}
|
||||
@ -47,9 +50,8 @@ internal static class Combat
|
||||
ArgumentNullException.ThrowIfNull(step.DataId);
|
||||
ArgumentNullException.ThrowIfNull(step.ItemId);
|
||||
|
||||
yield return serviceProvider.GetRequiredService<UseItem.UseOnObject>()
|
||||
.With(quest.Id, step.DataId.Value, step.ItemId.Value, step.CompletionQuestVariablesFlags,
|
||||
true);
|
||||
yield return useItemFactory.OnObject(quest.Id, step.DataId.Value, step.ItemId.Value,
|
||||
step.CompletionQuestVariablesFlags, true);
|
||||
yield return CreateTask(quest, sequence, step);
|
||||
break;
|
||||
}
|
||||
@ -73,34 +75,32 @@ internal static class Combat
|
||||
ArgumentNullException.ThrowIfNull(step.EnemySpawnType);
|
||||
|
||||
bool isLastStep = sequence.Steps.Last() == step;
|
||||
return serviceProvider.GetRequiredService<HandleCombat>()
|
||||
.With(quest.Id, isLastStep, step.EnemySpawnType.Value, step.KillEnemyDataIds,
|
||||
return CreateTask(quest.Id, isLastStep, step.EnemySpawnType.Value, step.KillEnemyDataIds,
|
||||
step.CompletionQuestVariablesFlags, step.ComplexCombatData);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class HandleCombat(CombatController combatController, QuestFunctions questFunctions) : ITask
|
||||
private HandleCombat CreateTask(ElementId elementId, bool isLastStep, EEnemySpawnType enemySpawnType,
|
||||
IList<uint> killEnemyDataIds, IList<QuestWorkValue?> completionQuestVariablesFlags,
|
||||
IList<ComplexCombatData> complexCombatData)
|
||||
{
|
||||
private bool _isLastStep;
|
||||
private CombatController.CombatData _combatData = null!;
|
||||
private IList<QuestWorkValue?> _completionQuestVariableFlags = null!;
|
||||
|
||||
public ITask With(ElementId elementId, bool isLastStep, EEnemySpawnType enemySpawnType, IList<uint> killEnemyDataIds,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags, IList<ComplexCombatData> complexCombatData)
|
||||
{
|
||||
_isLastStep = isLastStep;
|
||||
_combatData = new CombatController.CombatData
|
||||
return new HandleCombat(isLastStep, new CombatController.CombatData
|
||||
{
|
||||
ElementId = elementId,
|
||||
SpawnType = enemySpawnType,
|
||||
KillEnemyDataIds = killEnemyDataIds.ToList(),
|
||||
ComplexCombatDatas = complexCombatData.ToList(),
|
||||
};
|
||||
_completionQuestVariableFlags = completionQuestVariablesFlags;
|
||||
return this;
|
||||
}, completionQuestVariablesFlags, combatController, questFunctions);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Start() => combatController.Start(_combatData);
|
||||
private sealed class HandleCombat(
|
||||
bool isLastStep,
|
||||
CombatController.CombatData combatData,
|
||||
IList<QuestWorkValue?> completionQuestVariableFlags,
|
||||
CombatController combatController,
|
||||
QuestFunctions questFunctions) : ITask
|
||||
{
|
||||
public bool Start() => combatController.Start(combatData);
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
@ -108,13 +108,14 @@ internal static class Combat
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
// if our quest step has any completion flags, we need to check if they are set
|
||||
if (QuestWorkUtils.HasCompletionFlags(_completionQuestVariableFlags) && _combatData.ElementId is QuestId questId)
|
||||
if (QuestWorkUtils.HasCompletionFlags(completionQuestVariableFlags) &&
|
||||
combatData.ElementId is QuestId questId)
|
||||
{
|
||||
var questWork = questFunctions.GetQuestProgressInfo(questId);
|
||||
if (questWork == null)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
if (QuestWorkUtils.MatchesQuestWork(_completionQuestVariableFlags, questWork))
|
||||
if (QuestWorkUtils.MatchesQuestWork(completionQuestVariableFlags, questWork))
|
||||
return ETaskResult.TaskComplete;
|
||||
else
|
||||
return ETaskResult.StillRunning;
|
||||
@ -122,7 +123,7 @@ internal static class Combat
|
||||
|
||||
// the last step, by definition, can only be progressed by the game recognizing we're in a new sequence,
|
||||
// so this is an indefinite wait
|
||||
if (_isLastStep)
|
||||
if (isLastStep)
|
||||
return ETaskResult.StillRunning;
|
||||
else
|
||||
{
|
||||
@ -133,9 +134,9 @@ internal static class Combat
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (QuestWorkUtils.HasCompletionFlags(_completionQuestVariableFlags))
|
||||
if (QuestWorkUtils.HasCompletionFlags(completionQuestVariableFlags))
|
||||
return "HandleCombat(wait: QW flags)";
|
||||
else if (_isLastStep)
|
||||
else if (isLastStep)
|
||||
return "HandleCombat(wait: next sequence)";
|
||||
else
|
||||
return "HandleCombat(wait: not in combat)";
|
||||
|
@ -18,18 +18,23 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Dive
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(ICondition condition, ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (step.InteractionType != EInteractionType.Dive)
|
||||
return null;
|
||||
|
||||
return serviceProvider.GetRequiredService<DoDive>();
|
||||
return Dive();
|
||||
}
|
||||
|
||||
public ITask Dive()
|
||||
{
|
||||
return new DoDive(condition, loggerFactory.CreateLogger<DoDive>());
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DoDive(ICondition condition, ILogger<DoDive> logger)
|
||||
private sealed class DoDive(ICondition condition, ILogger<DoDive> logger)
|
||||
: AbstractDelayedTask(TimeSpan.FromSeconds(5))
|
||||
{
|
||||
private readonly Queue<(uint Type, nint Key)> _keysToPress = [];
|
||||
|
@ -10,7 +10,7 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Duty
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(GameFunctions gameFunctions, ICondition condition) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -18,33 +18,26 @@ internal static class Duty
|
||||
return null;
|
||||
|
||||
ArgumentNullException.ThrowIfNull(step.ContentFinderConditionId);
|
||||
|
||||
return serviceProvider.GetRequiredService<OpenDutyFinder>()
|
||||
.With(step.ContentFinderConditionId.Value);
|
||||
return new OpenDutyFinder(step.ContentFinderConditionId.Value, gameFunctions, condition);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class OpenDutyFinder(GameFunctions gameFunctions, ICondition condition) : ITask
|
||||
private sealed class OpenDutyFinder(
|
||||
uint contentFinderConditionId,
|
||||
GameFunctions gameFunctions,
|
||||
ICondition condition) : ITask
|
||||
{
|
||||
public uint ContentFinderConditionId { get; set; }
|
||||
|
||||
public ITask With(uint contentFinderConditionId)
|
||||
{
|
||||
ContentFinderConditionId = contentFinderConditionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (condition[ConditionFlag.InDutyQueue])
|
||||
return false;
|
||||
|
||||
gameFunctions.OpenDutyFinder(ContentFinderConditionId);
|
||||
gameFunctions.OpenDutyFinder(contentFinderConditionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ETaskResult Update() => ETaskResult.TaskComplete;
|
||||
|
||||
public override string ToString() => $"OpenDutyFinder({ContentFinderConditionId})";
|
||||
public override string ToString() => $"OpenDutyFinder({contentFinderConditionId})";
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Emote
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory
|
||||
internal sealed class Factory(ChatFunctions chatFunctions, Mount.Factory mountFactory) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -24,57 +24,39 @@ internal static class Emote
|
||||
|
||||
ArgumentNullException.ThrowIfNull(step.Emote);
|
||||
|
||||
var unmount = serviceProvider.GetRequiredService<UnmountTask>();
|
||||
var unmount = mountFactory.Unmount();
|
||||
if (step.DataId != null)
|
||||
{
|
||||
var task = serviceProvider.GetRequiredService<UseOnObject>().With(step.Emote.Value, step.DataId.Value);
|
||||
var task = new UseOnObject(step.Emote.Value, step.DataId.Value, chatFunctions);
|
||||
return [unmount, task];
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = serviceProvider.GetRequiredService<Use>().With(step.Emote.Value);
|
||||
var task = new UseOnSelf(step.Emote.Value, chatFunctions);
|
||||
return [unmount, task];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class UseOnObject(ChatFunctions chatFunctions) : AbstractDelayedTask
|
||||
private sealed class UseOnObject(EEmote emote, uint dataId, ChatFunctions chatFunctions) : AbstractDelayedTask
|
||||
{
|
||||
public EEmote Emote { get; set; }
|
||||
public uint DataId { get; set; }
|
||||
|
||||
public ITask With(EEmote emote, uint dataId)
|
||||
{
|
||||
Emote = emote;
|
||||
DataId = dataId;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override bool StartInternal()
|
||||
{
|
||||
chatFunctions.UseEmote(DataId, Emote);
|
||||
chatFunctions.UseEmote(dataId, emote);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Emote({Emote} on {DataId})";
|
||||
public override string ToString() => $"Emote({emote} on {dataId})";
|
||||
}
|
||||
|
||||
internal sealed class Use(ChatFunctions chatFunctions) : AbstractDelayedTask
|
||||
private sealed class UseOnSelf(EEmote emote, ChatFunctions chatFunctions) : AbstractDelayedTask
|
||||
{
|
||||
public EEmote Emote { get; set; }
|
||||
|
||||
public ITask With(EEmote emote)
|
||||
{
|
||||
Emote = emote;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override bool StartInternal()
|
||||
{
|
||||
chatFunctions.UseEmote(Emote);
|
||||
chatFunctions.UseEmote(emote);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Emote({Emote})";
|
||||
public override string ToString() => $"Emote({emote})";
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class EquipItem
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(IDataManager dataManager, ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -24,14 +24,39 @@ internal static class EquipItem
|
||||
return null;
|
||||
|
||||
ArgumentNullException.ThrowIfNull(step.ItemId);
|
||||
return serviceProvider.GetRequiredService<DoEquip>()
|
||||
.With(step.ItemId.Value);
|
||||
return Equip(step.ItemId.Value);
|
||||
}
|
||||
|
||||
private DoEquip Equip(uint itemId)
|
||||
{
|
||||
var item = dataManager.GetExcelSheet<Item>()!.GetRow(itemId) ??
|
||||
throw new ArgumentOutOfRangeException(nameof(itemId));
|
||||
var targetSlots = GetEquipSlot(item) ?? throw new InvalidOperationException("Not a piece of equipment");
|
||||
return new DoEquip(itemId, item, targetSlots, dataManager, loggerFactory.CreateLogger<DoEquip>());
|
||||
}
|
||||
|
||||
private static List<ushort>? GetEquipSlot(Item item)
|
||||
{
|
||||
return item.EquipSlotCategory.Row switch
|
||||
{
|
||||
>= 1 and <= 11 => [(ushort)(item.EquipSlotCategory.Row - 1)],
|
||||
12 => [11, 12], // rings
|
||||
13 => [0],
|
||||
17 => [13], // soul crystal
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DoEquip(IDataManager dataManager, ILogger<DoEquip> logger) : ITask, IToastAware
|
||||
private sealed class DoEquip(
|
||||
uint itemId,
|
||||
Item item,
|
||||
List<ushort> targetSlots,
|
||||
IDataManager dataManager,
|
||||
ILogger<DoEquip> logger) : ITask, IToastAware
|
||||
{
|
||||
private const int MaxAttempts = 3;
|
||||
|
||||
private static readonly IReadOnlyList<InventoryType> SourceInventoryTypes =
|
||||
[
|
||||
InventoryType.ArmoryMainHand,
|
||||
@ -55,22 +80,9 @@ internal static class EquipItem
|
||||
InventoryType.Inventory4,
|
||||
];
|
||||
|
||||
private uint _itemId;
|
||||
private Item _item = null!;
|
||||
private List<ushort> _targetSlots = [];
|
||||
private int _attempts;
|
||||
|
||||
private DateTime _continueAt = DateTime.MaxValue;
|
||||
|
||||
public ITask With(uint itemId)
|
||||
{
|
||||
_itemId = itemId;
|
||||
_item = dataManager.GetExcelSheet<Item>()!.GetRow(itemId) ??
|
||||
throw new ArgumentOutOfRangeException(nameof(itemId));
|
||||
_targetSlots = GetEquipSlot(_item) ?? throw new InvalidOperationException("Not a piece of equipment");
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
Equip();
|
||||
@ -87,10 +99,10 @@ internal static class EquipItem
|
||||
if (inventoryManager == null)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
foreach (ushort x in _targetSlots)
|
||||
foreach (ushort x in targetSlots)
|
||||
{
|
||||
var itemSlot = inventoryManager->GetInventorySlot(InventoryType.EquippedItems, x);
|
||||
if (itemSlot != null && itemSlot->ItemId == _itemId)
|
||||
if (itemSlot != null && itemSlot->ItemId == itemId)
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
@ -113,12 +125,12 @@ internal static class EquipItem
|
||||
if (equippedContainer == null)
|
||||
return;
|
||||
|
||||
foreach (ushort slot in _targetSlots)
|
||||
foreach (ushort slot in targetSlots)
|
||||
{
|
||||
var itemSlot = equippedContainer->GetInventorySlot(slot);
|
||||
if (itemSlot != null && itemSlot->ItemId == _itemId)
|
||||
if (itemSlot != null && itemSlot->ItemId == itemId)
|
||||
{
|
||||
logger.LogInformation("Already equipped {Item}, skipping step", _item.Name?.ToString());
|
||||
logger.LogInformation("Already equipped {Item}, skipping step", item.Name?.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -129,24 +141,24 @@ internal static class EquipItem
|
||||
if (sourceContainer == null)
|
||||
continue;
|
||||
|
||||
if (inventoryManager->GetItemCountInContainer(_itemId, sourceInventoryType, true) == 0 &&
|
||||
inventoryManager->GetItemCountInContainer(_itemId, sourceInventoryType) == 0)
|
||||
if (inventoryManager->GetItemCountInContainer(itemId, sourceInventoryType, true) == 0 &&
|
||||
inventoryManager->GetItemCountInContainer(itemId, sourceInventoryType) == 0)
|
||||
continue;
|
||||
|
||||
for (ushort sourceSlot = 0; sourceSlot < sourceContainer->Size; sourceSlot++)
|
||||
{
|
||||
var sourceItem = sourceContainer->GetInventorySlot(sourceSlot);
|
||||
if (sourceItem == null || sourceItem->ItemId != _itemId)
|
||||
if (sourceItem == null || sourceItem->ItemId != itemId)
|
||||
continue;
|
||||
|
||||
// Move the item to the first available slot
|
||||
ushort targetSlot = _targetSlots
|
||||
ushort targetSlot = targetSlots
|
||||
.Where(x =>
|
||||
{
|
||||
var itemSlot = inventoryManager->GetInventorySlot(InventoryType.EquippedItems, x);
|
||||
return itemSlot == null || itemSlot->ItemId == 0;
|
||||
})
|
||||
.Concat(_targetSlots).First();
|
||||
.Concat(targetSlots).First();
|
||||
|
||||
logger.LogInformation(
|
||||
"Equipping item from {SourceInventory}, {SourceSlot} to {TargetInventory}, {TargetSlot}",
|
||||
@ -160,19 +172,7 @@ internal static class EquipItem
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ushort>? GetEquipSlot(Item item)
|
||||
{
|
||||
return item.EquipSlotCategory.Row switch
|
||||
{
|
||||
>= 1 and <= 11 => [(ushort)(item.EquipSlotCategory.Row - 1)],
|
||||
12 => [11, 12], // rings
|
||||
13 => [0],
|
||||
17 => [13], // soul crystal
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString() => $"Equip({_item.Name})";
|
||||
public override string ToString() => $"Equip({item.Name})";
|
||||
|
||||
public bool OnErrorToast(SeString message)
|
||||
{
|
||||
|
@ -10,18 +10,23 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class EquipRecommended
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(IClientState clientState, IChatGui chatGui) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (step.InteractionType != EInteractionType.EquipRecommended)
|
||||
return null;
|
||||
|
||||
return serviceProvider.GetRequiredService<DoEquipRecommended>();
|
||||
return DoEquip();
|
||||
}
|
||||
|
||||
public ITask DoEquip()
|
||||
{
|
||||
return new DoEquipRecommended(clientState, chatGui);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class BeforeDutyOrInstance(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class BeforeDutyOrInstance(IClientState clientState, IChatGui chatGui) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -30,11 +35,11 @@ internal static class EquipRecommended
|
||||
step.InteractionType != EInteractionType.Combat)
|
||||
return null;
|
||||
|
||||
return serviceProvider.GetRequiredService<DoEquipRecommended>();
|
||||
return new DoEquipRecommended(clientState, chatGui);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed unsafe class DoEquipRecommended(IClientState clientState, IChatGui chatGui) : ITask
|
||||
private sealed unsafe class DoEquipRecommended(IClientState clientState, IChatGui chatGui) : ITask
|
||||
{
|
||||
private bool _equipped;
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Interact
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory
|
||||
internal sealed class Factory(GameFunctions gameFunctions, ICondition condition, ILoggerFactory loggerFactory) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -36,41 +36,46 @@ internal static class Interact
|
||||
|
||||
// if we're fast enough, it is possible to get the smalltalk prompt
|
||||
if (sequence.Sequence == 0 && sequence.Steps.IndexOf(step) == 0)
|
||||
yield return serviceProvider.GetRequiredService<WaitAtEnd.WaitDelay>();
|
||||
yield return new WaitAtEnd.WaitDelay();
|
||||
|
||||
yield return serviceProvider.GetRequiredService<DoInteract>()
|
||||
.With(step.DataId.Value, quest, step.InteractionType,
|
||||
yield return Interact(step.DataId.Value, quest, step.InteractionType,
|
||||
step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId);
|
||||
}
|
||||
|
||||
internal ITask Interact(uint dataId, Quest? quest, EInteractionType interactionType, bool skipMarkerCheck = false)
|
||||
{
|
||||
return new DoInteract(dataId, quest, interactionType, skipMarkerCheck, gameFunctions, condition,
|
||||
loggerFactory.CreateLogger<DoInteract>());
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DoInteract(GameFunctions gameFunctions, ICondition condition, ILogger<DoInteract> logger)
|
||||
internal sealed class DoInteract(
|
||||
uint dataId,
|
||||
Quest? quest,
|
||||
EInteractionType interactionType,
|
||||
bool skipMarkerCheck,
|
||||
GameFunctions gameFunctions,
|
||||
ICondition condition,
|
||||
ILogger<DoInteract> logger)
|
||||
: ITask, IConditionChangeAware
|
||||
{
|
||||
private bool _needsUnmount;
|
||||
private EInteractionState _interactionState = EInteractionState.None;
|
||||
private DateTime _continueAt = DateTime.MinValue;
|
||||
|
||||
private uint DataId { get; set; }
|
||||
public Quest? Quest { get; private set; }
|
||||
public EInteractionType InteractionType { get; set; }
|
||||
private bool SkipMarkerCheck { get; set; }
|
||||
|
||||
public DoInteract With(uint dataId, Quest? quest, EInteractionType interactionType, bool skipMarkerCheck)
|
||||
public Quest? Quest => quest;
|
||||
public EInteractionType InteractionType
|
||||
{
|
||||
DataId = dataId;
|
||||
Quest = quest;
|
||||
InteractionType = interactionType;
|
||||
SkipMarkerCheck = skipMarkerCheck;
|
||||
return this;
|
||||
get => interactionType;
|
||||
set => interactionType = value;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId);
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId);
|
||||
if (gameObject == null)
|
||||
{
|
||||
logger.LogWarning("No game object with dataId {DataId}", DataId);
|
||||
logger.LogWarning("No game object with dataId {DataId}", dataId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -78,7 +83,7 @@ internal static class Interact
|
||||
if (!gameObject.IsTargetable && condition[ConditionFlag.Mounted] &&
|
||||
gameObject.ObjectKind != ObjectKind.GatheringPoint)
|
||||
{
|
||||
logger.LogInformation("Preparing interaction for {DataId} by unmounting", DataId);
|
||||
logger.LogInformation("Preparing interaction for {DataId} by unmounting", dataId);
|
||||
_needsUnmount = true;
|
||||
gameFunctions.Unmount();
|
||||
_continueAt = DateTime.Now.AddSeconds(1);
|
||||
@ -117,10 +122,10 @@ internal static class Interact
|
||||
if (_interactionState == EInteractionState.InteractionConfirmed)
|
||||
return ETaskResult.TaskComplete;
|
||||
|
||||
if (InteractionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering])
|
||||
if (interactionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering])
|
||||
return ETaskResult.TaskComplete;
|
||||
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId);
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId);
|
||||
if (gameObject == null || !gameObject.IsTargetable || !HasAnyMarker(gameObject))
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
@ -133,20 +138,21 @@ internal static class Interact
|
||||
|
||||
private unsafe bool HasAnyMarker(IGameObject gameObject)
|
||||
{
|
||||
if (SkipMarkerCheck || gameObject.ObjectKind != ObjectKind.EventNpc)
|
||||
if (skipMarkerCheck || gameObject.ObjectKind != ObjectKind.EventNpc)
|
||||
return true;
|
||||
|
||||
var gameObjectStruct = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)gameObject.Address;
|
||||
return gameObjectStruct->NamePlateIconId != 0;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Interact({DataId})";
|
||||
public override string ToString() => $"Interact({dataId})";
|
||||
|
||||
public void OnConditionChange(ConditionFlag flag, bool value)
|
||||
{
|
||||
logger.LogDebug("Condition change: {Flag} = {Value}", flag, value);
|
||||
if (_interactionState == EInteractionState.InteractionTriggered &&
|
||||
flag == ConditionFlag.OccupiedInQuestEvent && value)
|
||||
flag is ConditionFlag.OccupiedInQuestEvent or ConditionFlag.OccupiedInEvent &&
|
||||
value)
|
||||
{
|
||||
logger.LogInformation("Interaction was most likely triggered");
|
||||
_interactionState = EInteractionState.InteractionConfirmed;
|
||||
|
@ -11,7 +11,11 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Jump
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
|
||||
internal sealed class Factory(
|
||||
MovementController movementController,
|
||||
IClientState clientState,
|
||||
IFramework framework,
|
||||
ILoggerFactory loggerFactory) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -21,43 +25,39 @@ internal static class Jump
|
||||
ArgumentNullException.ThrowIfNull(step.JumpDestination);
|
||||
|
||||
if (step.JumpDestination.Type == EJumpType.SingleJump)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<SingleJump>()
|
||||
.With(step.DataId, step.JumpDestination, step.Comment);
|
||||
}
|
||||
return SingleJump(step.DataId, step.JumpDestination, step.Comment);
|
||||
else
|
||||
{
|
||||
return serviceProvider.GetRequiredService<RepeatedJumps>()
|
||||
.With(step.DataId, step.JumpDestination, step.Comment);
|
||||
return RepeatedJumps(step.DataId, step.JumpDestination, step.Comment);
|
||||
}
|
||||
|
||||
public ITask SingleJump(uint? dataId, JumpDestination jumpDestination, string? comment)
|
||||
{
|
||||
return new DoSingleJump(dataId, jumpDestination, comment, movementController, clientState, framework);
|
||||
}
|
||||
|
||||
public ITask RepeatedJumps(uint? dataId, JumpDestination jumpDestination, string? comment)
|
||||
{
|
||||
return new DoRepeatedJumps(dataId, jumpDestination, comment, movementController, clientState, framework,
|
||||
loggerFactory.CreateLogger<DoRepeatedJumps>());
|
||||
}
|
||||
}
|
||||
|
||||
internal class SingleJump(
|
||||
private class DoSingleJump(
|
||||
uint? dataId,
|
||||
JumpDestination jumpDestination,
|
||||
string? comment,
|
||||
MovementController movementController,
|
||||
IClientState clientState,
|
||||
IFramework framework) : ITask
|
||||
{
|
||||
public uint? DataId { get; set; }
|
||||
public JumpDestination JumpDestination { get; set; } = null!;
|
||||
public string? Comment { get; set; }
|
||||
|
||||
public ITask With(uint? dataId, JumpDestination jumpDestination, string? comment)
|
||||
{
|
||||
DataId = dataId;
|
||||
JumpDestination = jumpDestination;
|
||||
Comment = comment ?? string.Empty;
|
||||
return this;
|
||||
}
|
||||
|
||||
public virtual bool Start()
|
||||
{
|
||||
float stopDistance = JumpDestination.CalculateStopDistance();
|
||||
if ((clientState.LocalPlayer!.Position - JumpDestination.Position).Length() <= stopDistance)
|
||||
float stopDistance = jumpDestination.CalculateStopDistance();
|
||||
if ((clientState.LocalPlayer!.Position - jumpDestination.Position).Length() <= stopDistance)
|
||||
return false;
|
||||
|
||||
movementController.NavigateTo(EMovementType.Quest, DataId, [JumpDestination.Position], false, false,
|
||||
JumpDestination.StopDistance ?? stopDistance);
|
||||
movementController.NavigateTo(EMovementType.Quest, dataId, [jumpDestination.Position], false, false,
|
||||
jumpDestination.StopDistance ?? stopDistance);
|
||||
framework.RunOnTick(() =>
|
||||
{
|
||||
unsafe
|
||||
@ -65,7 +65,7 @@ internal static class Jump
|
||||
ActionManager.Instance()->UseAction(ActionType.GeneralAction, 2);
|
||||
}
|
||||
},
|
||||
TimeSpan.FromSeconds(JumpDestination.DelaySeconds ?? 0.5f));
|
||||
TimeSpan.FromSeconds(jumpDestination.DelaySeconds ?? 0.5f));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -81,22 +81,28 @@ internal static class Jump
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Jump({Comment})";
|
||||
public override string ToString() => $"Jump({comment})";
|
||||
}
|
||||
|
||||
internal sealed class RepeatedJumps(
|
||||
private sealed class DoRepeatedJumps(
|
||||
uint? dataId,
|
||||
JumpDestination jumpDestination,
|
||||
string? comment,
|
||||
MovementController movementController,
|
||||
IClientState clientState,
|
||||
IFramework framework,
|
||||
ILogger<RepeatedJumps> logger) : SingleJump(movementController, clientState, framework)
|
||||
ILogger<DoRepeatedJumps> logger)
|
||||
: DoSingleJump(dataId, jumpDestination, comment, movementController, clientState, framework)
|
||||
{
|
||||
private readonly JumpDestination _jumpDestination = jumpDestination;
|
||||
private readonly string? _comment = comment;
|
||||
private readonly IClientState _clientState = clientState;
|
||||
private DateTime _continueAt = DateTime.MinValue;
|
||||
private int _attempts;
|
||||
|
||||
public override bool Start()
|
||||
{
|
||||
_continueAt = DateTime.Now + TimeSpan.FromSeconds(2 * (JumpDestination.DelaySeconds ?? 0.5f));
|
||||
_continueAt = DateTime.Now + TimeSpan.FromSeconds(2 * (_jumpDestination.DelaySeconds ?? 0.5f));
|
||||
return base.Start();
|
||||
}
|
||||
|
||||
@ -105,13 +111,13 @@ internal static class Jump
|
||||
if (DateTime.Now < _continueAt)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
float stopDistance = JumpDestination.CalculateStopDistance();
|
||||
if ((_clientState.LocalPlayer!.Position - JumpDestination.Position).Length() <= stopDistance ||
|
||||
_clientState.LocalPlayer.Position.Y >= JumpDestination.Position.Y - 0.5f)
|
||||
float stopDistance = _jumpDestination.CalculateStopDistance();
|
||||
if ((_clientState.LocalPlayer!.Position - _jumpDestination.Position).Length() <= stopDistance ||
|
||||
_clientState.LocalPlayer.Position.Y >= _jumpDestination.Position.Y - 0.5f)
|
||||
return ETaskResult.TaskComplete;
|
||||
|
||||
logger.LogTrace("Y-Heights for jumps: player={A}, target={B}", _clientState.LocalPlayer.Position.Y,
|
||||
JumpDestination.Position.Y - 0.5f);
|
||||
_jumpDestination.Position.Y - 0.5f);
|
||||
unsafe
|
||||
{
|
||||
ActionManager.Instance()->UseAction(ActionType.GeneralAction, 2);
|
||||
@ -121,10 +127,10 @@ internal static class Jump
|
||||
if (_attempts >= 50)
|
||||
throw new TaskException("Tried to jump too many times, didn't reach the target");
|
||||
|
||||
_continueAt = DateTime.Now + TimeSpan.FromSeconds(JumpDestination.DelaySeconds ?? 0.5f);
|
||||
_continueAt = DateTime.Now + TimeSpan.FromSeconds(_jumpDestination.DelaySeconds ?? 0.5f);
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
public override string ToString() => $"RepeatedJump({Comment})";
|
||||
public override string ToString() => $"RepeatedJump({_comment})";
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,10 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Say
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider, ExcelFunctions excelFunctions) : ITaskFactory
|
||||
internal sealed class Factory(
|
||||
ChatFunctions chatFunctions,
|
||||
Mount.Factory mountFactory,
|
||||
ExcelFunctions excelFunctions) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -21,31 +24,24 @@ internal static class Say
|
||||
ArgumentNullException.ThrowIfNull(step.ChatMessage);
|
||||
|
||||
string? excelString =
|
||||
excelFunctions.GetDialogueText(quest, step.ChatMessage.ExcelSheet, step.ChatMessage.Key, false).GetString();
|
||||
excelFunctions.GetDialogueText(quest, step.ChatMessage.ExcelSheet, step.ChatMessage.Key, false)
|
||||
.GetString();
|
||||
ArgumentNullException.ThrowIfNull(excelString);
|
||||
|
||||
var unmount = serviceProvider.GetRequiredService<UnmountTask>();
|
||||
var task = serviceProvider.GetRequiredService<UseChat>().With(excelString);
|
||||
var unmount = mountFactory.Unmount();
|
||||
var task = new UseChat(excelString, chatFunctions);
|
||||
return [unmount, task];
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class UseChat(ChatFunctions chatFunctions) : AbstractDelayedTask
|
||||
private sealed class UseChat(string chatMessage, ChatFunctions chatFunctions) : AbstractDelayedTask
|
||||
{
|
||||
public string ChatMessage { get; set; } = null!;
|
||||
|
||||
public ITask With(string chatMessage)
|
||||
{
|
||||
ChatMessage = chatMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override bool StartInternal()
|
||||
{
|
||||
chatFunctions.ExecuteCommand($"/say {ChatMessage}");
|
||||
chatFunctions.ExecuteCommand($"/say {chatMessage}");
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Say({ChatMessage})";
|
||||
public override string ToString() => $"Say({chatMessage})";
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,17 @@ internal static class UseItem
|
||||
public const int VesperBayAetheryteTicket = 30362;
|
||||
|
||||
internal sealed class Factory(
|
||||
IServiceProvider serviceProvider,
|
||||
Mount.Factory mountFactory,
|
||||
MoveTo.Factory moveFactory,
|
||||
Interact.Factory interactFactory,
|
||||
AetheryteShortcut.Factory aetheryteShortcutFactory,
|
||||
AethernetShortcut.Factory aethernetShortcutFactory,
|
||||
GameFunctions gameFunctions,
|
||||
QuestFunctions questFunctions,
|
||||
ICondition condition,
|
||||
IClientState clientState,
|
||||
TerritoryData territoryData,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<Factory> logger)
|
||||
: ITaskFactory
|
||||
{
|
||||
@ -48,8 +56,7 @@ internal static class UseItem
|
||||
return CreateVesperBayFallbackTask();
|
||||
}
|
||||
|
||||
var task = serviceProvider.GetRequiredService<Use>()
|
||||
.With(quest.Id, step.ItemId.Value, step.CompletionQuestVariablesFlags);
|
||||
var task = OnSelf(quest.Id, step.ItemId.Value, step.CompletionQuestVariablesFlags);
|
||||
|
||||
int currentStepIndex = sequence.Steps.IndexOf(step);
|
||||
QuestStep? nextStep = sequence.Steps.Skip(currentStepIndex + 1).FirstOrDefault();
|
||||
@ -59,28 +66,25 @@ internal static class UseItem
|
||||
task,
|
||||
new WaitConditionTask(() => clientState.TerritoryType == 140,
|
||||
$"Wait(territory: {territoryData.GetNameAndId(140)})"),
|
||||
serviceProvider.GetRequiredService<MountTask>()
|
||||
.With(140,
|
||||
nextPosition != null ? MountTask.EMountIf.AwayFromPosition : MountTask.EMountIf.Always,
|
||||
mountFactory.Mount(140,
|
||||
nextPosition != null ? Mount.EMountIf.AwayFromPosition : Mount.EMountIf.Always,
|
||||
nextPosition),
|
||||
serviceProvider.GetRequiredService<Move.MoveInternal>()
|
||||
.With(140, new(-408.92343f, 23.167036f, -351.16223f), 0.25f, dataId: null, disableNavMesh: true,
|
||||
sprint: false, fly: false)
|
||||
moveFactory.Move(new MoveTo.MoveParams(140, new(-408.92343f, 23.167036f, -351.16223f), 0.25f,
|
||||
DataId: null, DisableNavMesh: true, Sprint: false, Fly: false))
|
||||
];
|
||||
}
|
||||
|
||||
var unmount = serviceProvider.GetRequiredService<UnmountTask>();
|
||||
var unmount = mountFactory.Unmount();
|
||||
if (step.GroundTarget == true)
|
||||
{
|
||||
ITask task;
|
||||
if (step.DataId != null)
|
||||
task = serviceProvider.GetRequiredService<UseOnGround>()
|
||||
.With(quest.Id, step.DataId.Value, step.ItemId.Value, step.CompletionQuestVariablesFlags);
|
||||
task = OnGroundTarget(quest.Id, step.DataId.Value, step.ItemId.Value,
|
||||
step.CompletionQuestVariablesFlags);
|
||||
else
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(step.Position);
|
||||
task = serviceProvider.GetRequiredService<UseOnPosition>()
|
||||
.With(quest.Id, step.Position.Value, step.ItemId.Value,
|
||||
task = OnPosition(quest.Id, step.Position.Value, step.ItemId.Value,
|
||||
step.CompletionQuestVariablesFlags);
|
||||
}
|
||||
|
||||
@ -88,18 +92,43 @@ internal static class UseItem
|
||||
}
|
||||
else if (step.DataId != null)
|
||||
{
|
||||
var task = serviceProvider.GetRequiredService<UseOnObject>()
|
||||
.With(quest.Id, step.DataId.Value, step.ItemId.Value, step.CompletionQuestVariablesFlags);
|
||||
var task = OnObject(quest.Id, step.DataId.Value, step.ItemId.Value, step.CompletionQuestVariablesFlags);
|
||||
return [unmount, task];
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = serviceProvider.GetRequiredService<Use>()
|
||||
.With(quest.Id, step.ItemId.Value, step.CompletionQuestVariablesFlags);
|
||||
var task = OnSelf(quest.Id, step.ItemId.Value, step.CompletionQuestVariablesFlags);
|
||||
return [unmount, task];
|
||||
}
|
||||
}
|
||||
|
||||
public ITask OnGroundTarget(ElementId questId, uint dataId, uint itemId,
|
||||
List<QuestWorkValue?> completionQuestVariablesFlags)
|
||||
{
|
||||
return new UseOnGround(questId, dataId, itemId, completionQuestVariablesFlags, gameFunctions,
|
||||
questFunctions, condition, loggerFactory.CreateLogger<UseOnGround>());
|
||||
}
|
||||
|
||||
public ITask OnPosition(ElementId questId, Vector3 position, uint itemId,
|
||||
List<QuestWorkValue?> completionQuestVariablesFlags)
|
||||
{
|
||||
return new UseOnPosition(questId, position, itemId, completionQuestVariablesFlags, gameFunctions,
|
||||
questFunctions, condition, loggerFactory.CreateLogger<UseOnPosition>());
|
||||
}
|
||||
|
||||
public ITask OnObject(ElementId questId, uint dataId, uint itemId,
|
||||
List<QuestWorkValue?> completionQuestVariablesFlags, bool startingCombat = false)
|
||||
{
|
||||
return new UseOnObject(questId, dataId, itemId, completionQuestVariablesFlags, startingCombat,
|
||||
questFunctions, gameFunctions, condition, loggerFactory.CreateLogger<UseOnObject>());
|
||||
}
|
||||
|
||||
public ITask OnSelf(ElementId questId, uint itemId, List<QuestWorkValue?> completionQuestVariablesFlags)
|
||||
{
|
||||
return new Use(questId, itemId, completionQuestVariablesFlags, gameFunctions, questFunctions, condition,
|
||||
loggerFactory.CreateLogger<Use>());
|
||||
}
|
||||
|
||||
private IEnumerable<ITask> CreateVesperBayFallbackTask()
|
||||
{
|
||||
logger.LogWarning("No vesper bay aetheryte tickets in inventory, navigating via ferry in Limsa instead");
|
||||
@ -107,28 +136,32 @@ internal static class UseItem
|
||||
uint npcId = 1003540;
|
||||
ushort territoryId = 129;
|
||||
Vector3 destination = new(-360.9217f, 8f, 38.92566f);
|
||||
yield return serviceProvider.GetRequiredService<AetheryteShortcut.UseAetheryteShortcut>()
|
||||
.With(null, null, EAetheryteLocation.Limsa, territoryId);
|
||||
yield return serviceProvider.GetRequiredService<AethernetShortcut.UseAethernetShortcut>()
|
||||
.With(EAetheryteLocation.Limsa, EAetheryteLocation.LimsaArcanist);
|
||||
yield return serviceProvider.GetRequiredService<WaitAtEnd.WaitDelay>();
|
||||
yield return serviceProvider.GetRequiredService<Move.MoveInternal>()
|
||||
.With(territoryId, destination, dataId: npcId, sprint: false);
|
||||
yield return serviceProvider.GetRequiredService<Interact.DoInteract>()
|
||||
.With(npcId, null, EInteractionType.None, true);
|
||||
yield return aetheryteShortcutFactory.Use(null, null, EAetheryteLocation.Limsa, territoryId);
|
||||
yield return aethernetShortcutFactory.Use(EAetheryteLocation.Limsa, EAetheryteLocation.LimsaArcanist);
|
||||
yield return new WaitAtEnd.WaitDelay();
|
||||
yield return
|
||||
moveFactory.Move(new MoveTo.MoveParams(territoryId, destination, DataId: npcId, Sprint: false));
|
||||
yield return interactFactory.Interact(npcId, null, EInteractionType.None, true);
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class UseItemBase(QuestFunctions questFunctions, ICondition condition, ILogger logger) : ITask
|
||||
private abstract class UseItemBase(
|
||||
ElementId? questId,
|
||||
uint itemId,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags,
|
||||
bool startingCombat,
|
||||
QuestFunctions questFunctions,
|
||||
ICondition condition,
|
||||
ILogger logger) : ITask
|
||||
{
|
||||
private bool _usedItem;
|
||||
private DateTime _continueAt;
|
||||
private int _itemCount;
|
||||
|
||||
public ElementId? QuestId { get; set; }
|
||||
public uint ItemId { get; set; }
|
||||
public IList<QuestWorkValue?> CompletionQuestVariablesFlags { get; set; } = new List<QuestWorkValue?>();
|
||||
public bool StartingCombat { get; set; }
|
||||
public ElementId? QuestId => questId;
|
||||
public uint ItemId => itemId;
|
||||
public IList<QuestWorkValue?> CompletionQuestVariablesFlags => completionQuestVariablesFlags;
|
||||
public bool StartingCombat => startingCombat;
|
||||
|
||||
protected abstract bool UseItem();
|
||||
|
||||
@ -149,9 +182,9 @@ internal static class UseItem
|
||||
|
||||
public unsafe ETaskResult Update()
|
||||
{
|
||||
if (QuestId is QuestId questId && QuestWorkUtils.HasCompletionFlags(CompletionQuestVariablesFlags))
|
||||
if (QuestId is QuestId realQuestId && QuestWorkUtils.HasCompletionFlags(CompletionQuestVariablesFlags))
|
||||
{
|
||||
QuestProgressInfo? questWork = questFunctions.GetQuestProgressInfo(questId);
|
||||
QuestProgressInfo? questWork = questFunctions.GetQuestProgressInfo(realQuestId);
|
||||
if (questWork != null &&
|
||||
QuestWorkUtils.MatchesQuestWork(CompletionQuestVariablesFlags, questWork))
|
||||
return ETaskResult.TaskComplete;
|
||||
@ -203,96 +236,66 @@ internal static class UseItem
|
||||
}
|
||||
|
||||
|
||||
internal sealed class UseOnGround(
|
||||
private sealed class UseOnGround(
|
||||
ElementId? questId,
|
||||
uint dataId,
|
||||
uint itemId,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags,
|
||||
GameFunctions gameFunctions,
|
||||
QuestFunctions questFunctions,
|
||||
ICondition condition,
|
||||
ILogger<UseOnGround> logger)
|
||||
: UseItemBase(questFunctions, condition, logger)
|
||||
: UseItemBase(questId, itemId, completionQuestVariablesFlags, false, questFunctions, condition, logger)
|
||||
{
|
||||
public uint DataId { get; set; }
|
||||
protected override bool UseItem() => gameFunctions.UseItemOnGround(dataId, ItemId);
|
||||
|
||||
public ITask With(ElementId? questId, uint dataId, uint itemId,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags)
|
||||
{
|
||||
QuestId = questId;
|
||||
DataId = dataId;
|
||||
ItemId = itemId;
|
||||
CompletionQuestVariablesFlags = completionQuestVariablesFlags;
|
||||
return this;
|
||||
public override string ToString() => $"UseItem({ItemId} on ground at {dataId})";
|
||||
}
|
||||
|
||||
protected override bool UseItem() => gameFunctions.UseItemOnGround(DataId, ItemId);
|
||||
|
||||
public override string ToString() => $"UseItem({ItemId} on ground at {DataId})";
|
||||
}
|
||||
|
||||
internal sealed class UseOnPosition(
|
||||
private sealed class UseOnPosition(
|
||||
ElementId? questId,
|
||||
Vector3 position,
|
||||
uint itemId,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags,
|
||||
GameFunctions gameFunctions,
|
||||
QuestFunctions questFunctions,
|
||||
ICondition condition,
|
||||
ILogger<UseOnPosition> logger)
|
||||
: UseItemBase(questFunctions, condition, logger)
|
||||
: UseItemBase(questId, itemId, completionQuestVariablesFlags, false, questFunctions, condition, logger)
|
||||
{
|
||||
public Vector3 Position { get; set; }
|
||||
|
||||
public ITask With(ElementId? questId, Vector3 position, uint itemId,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags)
|
||||
{
|
||||
QuestId = questId;
|
||||
Position = position;
|
||||
ItemId = itemId;
|
||||
CompletionQuestVariablesFlags = completionQuestVariablesFlags;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override bool UseItem() => gameFunctions.UseItemOnPosition(Position, ItemId);
|
||||
protected override bool UseItem() => gameFunctions.UseItemOnPosition(position, ItemId);
|
||||
|
||||
public override string ToString() =>
|
||||
$"UseItem({ItemId} on ground at {Position.ToString("G", CultureInfo.InvariantCulture)})";
|
||||
$"UseItem({ItemId} on ground at {position.ToString("G", CultureInfo.InvariantCulture)})";
|
||||
}
|
||||
|
||||
internal sealed class UseOnObject(
|
||||
private sealed class UseOnObject(
|
||||
ElementId? questId,
|
||||
uint dataId,
|
||||
uint itemId,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags,
|
||||
bool startingCombat,
|
||||
QuestFunctions questFunctions,
|
||||
GameFunctions gameFunctions,
|
||||
ICondition condition,
|
||||
ILogger<UseOnObject> logger)
|
||||
: UseItemBase(questFunctions, condition, logger)
|
||||
: UseItemBase(questId, itemId, completionQuestVariablesFlags, startingCombat, questFunctions, condition, logger)
|
||||
{
|
||||
public uint DataId { get; set; }
|
||||
protected override bool UseItem() => gameFunctions.UseItem(dataId, ItemId);
|
||||
|
||||
public ITask With(ElementId? questId, uint dataId, uint itemId,
|
||||
public override string ToString() => $"UseItem({ItemId} on {dataId})";
|
||||
}
|
||||
|
||||
private sealed class Use(
|
||||
ElementId? questId,
|
||||
uint itemId,
|
||||
IList<QuestWorkValue?> completionQuestVariablesFlags,
|
||||
bool startingCombat = false)
|
||||
{
|
||||
QuestId = questId;
|
||||
DataId = dataId;
|
||||
ItemId = itemId;
|
||||
StartingCombat = startingCombat;
|
||||
CompletionQuestVariablesFlags = completionQuestVariablesFlags;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override bool UseItem() => gameFunctions.UseItem(DataId, ItemId);
|
||||
|
||||
public override string ToString() => $"UseItem({ItemId} on {DataId})";
|
||||
}
|
||||
|
||||
internal sealed class Use(
|
||||
GameFunctions gameFunctions,
|
||||
QuestFunctions questFunctions,
|
||||
ICondition condition,
|
||||
ILogger<Use> logger)
|
||||
: UseItemBase(questFunctions, condition, logger)
|
||||
: UseItemBase(questId, itemId, completionQuestVariablesFlags, false, questFunctions, condition, logger)
|
||||
{
|
||||
public ITask With(ElementId? questId, uint itemId, IList<QuestWorkValue?> completionQuestVariablesFlags)
|
||||
{
|
||||
QuestId = questId;
|
||||
ItemId = itemId;
|
||||
CompletionQuestVariablesFlags = completionQuestVariablesFlags;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override bool UseItem() => gameFunctions.UseItem(ItemId);
|
||||
|
||||
public override string ToString() => $"UseItem({ItemId})";
|
||||
|
@ -9,6 +9,7 @@ using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using LLib.GameUI;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
|
||||
@ -17,31 +18,23 @@ namespace Questionable.Controller.Steps.Leves;
|
||||
|
||||
internal static class InitiateLeve
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider, ICondition condition) : ITaskFactory
|
||||
internal sealed class Factory(IGameGui gameGui, ICondition condition) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (step.InteractionType != EInteractionType.InitiateLeve)
|
||||
yield break;
|
||||
|
||||
yield return serviceProvider.GetRequiredService<SkipInitiateIfActive>().With(quest.Id);
|
||||
yield return serviceProvider.GetRequiredService<OpenJournal>().With(quest.Id);
|
||||
yield return serviceProvider.GetRequiredService<Initiate>().With(quest.Id);
|
||||
yield return serviceProvider.GetRequiredService<SelectDifficulty>();
|
||||
yield return new SkipInitiateIfActive(quest.Id);
|
||||
yield return new OpenJournal(quest.Id);
|
||||
yield return new Initiate(quest.Id, gameGui);
|
||||
yield return new SelectDifficulty(gameGui);
|
||||
yield return new WaitConditionTask(() => condition[ConditionFlag.BoundByDuty], "Wait(BoundByDuty)");
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed unsafe class SkipInitiateIfActive : ITask
|
||||
internal sealed unsafe class SkipInitiateIfActive(ElementId elementId) : ITask
|
||||
{
|
||||
private ElementId _elementId = null!;
|
||||
|
||||
public ITask With(ElementId elementId)
|
||||
{
|
||||
_elementId = elementId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start() => true;
|
||||
|
||||
public ETaskResult Update()
|
||||
@ -50,31 +43,23 @@ internal static class InitiateLeve
|
||||
if (director != null &&
|
||||
director->EventHandlerInfo != null &&
|
||||
director->EventHandlerInfo->EventId.ContentId == EventHandlerType.GatheringLeveDirector &&
|
||||
director->ContentId == _elementId.Value)
|
||||
director->ContentId == elementId.Value)
|
||||
return ETaskResult.SkipRemainingTasksForStep;
|
||||
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => $"CheckIfAlreadyActive({_elementId})";
|
||||
public override string ToString() => $"CheckIfAlreadyActive({elementId})";
|
||||
}
|
||||
|
||||
internal sealed unsafe class OpenJournal : ITask
|
||||
internal sealed unsafe class OpenJournal(ElementId elementId) : ITask
|
||||
{
|
||||
private ElementId _elementId = null!;
|
||||
private uint _questType;
|
||||
private readonly uint _questType = elementId is LeveId ? 2u : 1u;
|
||||
private DateTime _openedAt = DateTime.MinValue;
|
||||
|
||||
public ITask With(ElementId elementId)
|
||||
{
|
||||
_elementId = elementId;
|
||||
_questType = _elementId is LeveId ? 2u : 1u;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
AgentQuestJournal.Instance()->OpenForQuest(_elementId.Value, _questType);
|
||||
AgentQuestJournal.Instance()->OpenForQuest(elementId.Value, _questType);
|
||||
_openedAt = DateTime.Now;
|
||||
return true;
|
||||
}
|
||||
@ -83,32 +68,24 @@ internal static class InitiateLeve
|
||||
{
|
||||
AgentQuestJournal* agentQuestJournal = AgentQuestJournal.Instance();
|
||||
if (agentQuestJournal->IsAgentActive() &&
|
||||
agentQuestJournal->SelectedQuestId == _elementId.Value &&
|
||||
agentQuestJournal->SelectedQuestId == elementId.Value &&
|
||||
agentQuestJournal->SelectedQuestType == _questType)
|
||||
return ETaskResult.TaskComplete;
|
||||
|
||||
if (DateTime.Now > _openedAt.AddSeconds(3))
|
||||
{
|
||||
AgentQuestJournal.Instance()->OpenForQuest(_elementId.Value, _questType);
|
||||
AgentQuestJournal.Instance()->OpenForQuest(elementId.Value, _questType);
|
||||
_openedAt = DateTime.Now;
|
||||
}
|
||||
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
public override string ToString() => $"OpenJournal({_elementId})";
|
||||
public override string ToString() => $"OpenJournal({elementId})";
|
||||
}
|
||||
|
||||
internal sealed unsafe class Initiate(IGameGui gameGui) : ITask
|
||||
internal sealed unsafe class Initiate(ElementId elementId, IGameGui gameGui) : ITask
|
||||
{
|
||||
private ElementId _elementId = null!;
|
||||
|
||||
public ITask With(ElementId elementId)
|
||||
{
|
||||
_elementId = elementId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start() => true;
|
||||
|
||||
public ETaskResult Update()
|
||||
@ -118,7 +95,7 @@ internal static class InitiateLeve
|
||||
var pickQuest = stackalloc AtkValue[]
|
||||
{
|
||||
new() { Type = ValueType.Int, Int = 4 },
|
||||
new() { Type = ValueType.UInt, Int = _elementId.Value }
|
||||
new() { Type = ValueType.UInt, Int = elementId.Value }
|
||||
};
|
||||
addonJournalDetail->FireCallback(2, pickQuest);
|
||||
return ETaskResult.TaskComplete;
|
||||
@ -127,7 +104,7 @@ internal static class InitiateLeve
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
public override string ToString() => $"InitiateLeve({_elementId})";
|
||||
public override string ToString() => $"InitiateLeve({elementId})";
|
||||
}
|
||||
|
||||
internal sealed unsafe class SelectDifficulty(IGameGui gameGui) : ITask
|
||||
|
@ -20,7 +20,16 @@ namespace Questionable.Controller.Steps.Shared;
|
||||
|
||||
internal static class AethernetShortcut
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider, MovementController movementController)
|
||||
internal sealed class Factory(
|
||||
MovementController movementController,
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
GameFunctions gameFunctions,
|
||||
IClientState clientState,
|
||||
AetheryteData aetheryteData,
|
||||
TerritoryData territoryData,
|
||||
LifestreamIpc lifestreamIpc,
|
||||
ICondition condition,
|
||||
ILoggerFactory loggerFactory)
|
||||
: ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
@ -30,12 +39,22 @@ internal static class AethernetShortcut
|
||||
|
||||
yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
|
||||
"Wait(navmesh ready)");
|
||||
yield return serviceProvider.GetRequiredService<UseAethernetShortcut>()
|
||||
.With(step.AethernetShortcut.From, step.AethernetShortcut.To, step.SkipConditions?.AethernetShortcutIf);
|
||||
yield return Use(step.AethernetShortcut.From, step.AethernetShortcut.To,
|
||||
step.SkipConditions?.AethernetShortcutIf);
|
||||
}
|
||||
|
||||
public ITask Use(EAetheryteLocation from, EAetheryteLocation to, SkipAetheryteCondition? skipConditions = null)
|
||||
{
|
||||
return new UseAethernetShortcut(from, to, skipConditions ?? new(),
|
||||
loggerFactory.CreateLogger<UseAethernetShortcut>(), aetheryteFunctions, gameFunctions, clientState,
|
||||
aetheryteData, territoryData, lifestreamIpc, movementController, condition);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class UseAethernetShortcut(
|
||||
EAetheryteLocation from,
|
||||
EAetheryteLocation to,
|
||||
SkipAetheryteCondition skipConditions,
|
||||
ILogger<UseAethernetShortcut> logger,
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
GameFunctions gameFunctions,
|
||||
@ -51,68 +70,58 @@ internal static class AethernetShortcut
|
||||
private bool _triedMounting;
|
||||
private DateTime _continueAt = DateTime.MinValue;
|
||||
|
||||
public EAetheryteLocation From { get; set; }
|
||||
public EAetheryteLocation To { get; set; }
|
||||
public SkipAetheryteCondition SkipConditions { get; set; } = null!;
|
||||
|
||||
public ITask With(EAetheryteLocation from, EAetheryteLocation to,
|
||||
SkipAetheryteCondition? skipConditions = null)
|
||||
{
|
||||
From = from;
|
||||
To = to;
|
||||
SkipConditions = skipConditions ?? new();
|
||||
return this;
|
||||
}
|
||||
public EAetheryteLocation From => from;
|
||||
public EAetheryteLocation To => to;
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!SkipConditions.Never)
|
||||
if (!skipConditions.Never)
|
||||
{
|
||||
if (SkipConditions.InSameTerritory && clientState.TerritoryType == aetheryteData.TerritoryIds[To])
|
||||
if (skipConditions.InSameTerritory && clientState.TerritoryType == aetheryteData.TerritoryIds[to])
|
||||
{
|
||||
logger.LogInformation("Skipping aethernet shortcut because the target is in the same territory");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SkipConditions.InTerritory.Contains(clientState.TerritoryType))
|
||||
if (skipConditions.InTerritory.Contains(clientState.TerritoryType))
|
||||
{
|
||||
logger.LogInformation(
|
||||
"Skipping aethernet shortcut because the target is in the specified territory");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SkipConditions.AetheryteLocked != null &&
|
||||
!aetheryteFunctions.IsAetheryteUnlocked(SkipConditions.AetheryteLocked.Value))
|
||||
if (skipConditions.AetheryteLocked != null &&
|
||||
!aetheryteFunctions.IsAetheryteUnlocked(skipConditions.AetheryteLocked.Value))
|
||||
{
|
||||
logger.LogInformation("Skipping aethernet shortcut because the target aetheryte is locked");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SkipConditions.AetheryteUnlocked != null &&
|
||||
aetheryteFunctions.IsAetheryteUnlocked(SkipConditions.AetheryteUnlocked.Value))
|
||||
if (skipConditions.AetheryteUnlocked != null &&
|
||||
aetheryteFunctions.IsAetheryteUnlocked(skipConditions.AetheryteUnlocked.Value))
|
||||
{
|
||||
logger.LogInformation("Skipping aethernet shortcut because the target aetheryte is unlocked");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aetheryteFunctions.IsAetheryteUnlocked(From) &&
|
||||
aetheryteFunctions.IsAetheryteUnlocked(To))
|
||||
if (aetheryteFunctions.IsAetheryteUnlocked(from) &&
|
||||
aetheryteFunctions.IsAetheryteUnlocked(to))
|
||||
{
|
||||
ushort territoryType = clientState.TerritoryType;
|
||||
Vector3 playerPosition = clientState.LocalPlayer!.Position;
|
||||
|
||||
// closer to the source
|
||||
if (aetheryteData.CalculateDistance(playerPosition, territoryType, From) <
|
||||
aetheryteData.CalculateDistance(playerPosition, territoryType, To))
|
||||
if (aetheryteData.CalculateDistance(playerPosition, territoryType, from) <
|
||||
aetheryteData.CalculateDistance(playerPosition, territoryType, to))
|
||||
{
|
||||
if (aetheryteData.CalculateDistance(playerPosition, territoryType, From) <
|
||||
(From.IsFirmamentAetheryte() ? 11f : 4f))
|
||||
if (aetheryteData.CalculateDistance(playerPosition, territoryType, from) <
|
||||
(from.IsFirmamentAetheryte() ? 11f : 4f))
|
||||
{
|
||||
DoTeleport();
|
||||
return true;
|
||||
}
|
||||
else if (From == EAetheryteLocation.SolutionNine)
|
||||
else if (from == EAetheryteLocation.SolutionNine)
|
||||
{
|
||||
logger.LogInformation("Moving to S9 aetheryte");
|
||||
List<Vector3> nearbyPoints =
|
||||
@ -125,14 +134,14 @@ internal static class AethernetShortcut
|
||||
|
||||
Vector3 closestPoint = nearbyPoints.MinBy(x => (playerPosition - x).Length());
|
||||
_moving = true;
|
||||
movementController.NavigateTo(EMovementType.Quest, (uint)From, closestPoint, false, true,
|
||||
movementController.NavigateTo(EMovementType.Quest, (uint)from, closestPoint, false, true,
|
||||
0.25f);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (territoryData.CanUseMount(territoryType) &&
|
||||
aetheryteData.CalculateDistance(playerPosition, territoryType, From) > 30 &&
|
||||
aetheryteData.CalculateDistance(playerPosition, territoryType, from) > 30 &&
|
||||
!gameFunctions.HasStatusPreventingMount())
|
||||
{
|
||||
_triedMounting = gameFunctions.Mount();
|
||||
@ -151,7 +160,7 @@ internal static class AethernetShortcut
|
||||
else
|
||||
logger.LogWarning(
|
||||
"Aethernet shortcut not unlocked (from: {FromAetheryte}, to: {ToAetheryte}), walking manually",
|
||||
From, To);
|
||||
from, to);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -160,26 +169,26 @@ internal static class AethernetShortcut
|
||||
{
|
||||
logger.LogInformation("Moving to aethernet shortcut");
|
||||
_moving = true;
|
||||
movementController.NavigateTo(EMovementType.Quest, (uint)From, aetheryteData.Locations[From],
|
||||
movementController.NavigateTo(EMovementType.Quest, (uint)from, aetheryteData.Locations[from],
|
||||
false, true,
|
||||
From.IsFirmamentAetheryte()
|
||||
from.IsFirmamentAetheryte()
|
||||
? 4.4f
|
||||
: AetheryteConverter.IsLargeAetheryte(From)
|
||||
: AetheryteConverter.IsLargeAetheryte(from)
|
||||
? 10.9f
|
||||
: 6.9f);
|
||||
}
|
||||
|
||||
private void DoTeleport()
|
||||
{
|
||||
if (From.IsFirmamentAetheryte())
|
||||
if (from.IsFirmamentAetheryte())
|
||||
{
|
||||
logger.LogInformation("Using manual teleport interaction");
|
||||
_teleported = gameFunctions.InteractWith((uint)From, ObjectKind.EventObj);
|
||||
_teleported = gameFunctions.InteractWith((uint)from, ObjectKind.EventObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("Using lifestream to teleport to {Destination}", To);
|
||||
lifestreamIpc.Teleport(To);
|
||||
logger.LogInformation("Using lifestream to teleport to {Destination}", to);
|
||||
lifestreamIpc.Teleport(to);
|
||||
_teleported = true;
|
||||
}
|
||||
}
|
||||
@ -219,22 +228,22 @@ internal static class AethernetShortcut
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
if (aetheryteData.IsAirshipLanding(To))
|
||||
if (aetheryteData.IsAirshipLanding(to))
|
||||
{
|
||||
if (aetheryteData.CalculateAirshipLandingDistance(clientState.LocalPlayer?.Position ?? Vector3.Zero,
|
||||
clientState.TerritoryType, To) > 5)
|
||||
clientState.TerritoryType, to) > 5)
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
else if (aetheryteData.IsCityAetheryte(To))
|
||||
else if (aetheryteData.IsCityAetheryte(to))
|
||||
{
|
||||
if (aetheryteData.CalculateDistance(clientState.LocalPlayer?.Position ?? Vector3.Zero,
|
||||
clientState.TerritoryType, To) > 20)
|
||||
clientState.TerritoryType, to) > 20)
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
else
|
||||
{
|
||||
// some overworld location (e.g. 'Tesselation (Lakeland)' would end up here
|
||||
if (clientState.TerritoryType != aetheryteData.TerritoryIds[To])
|
||||
if (clientState.TerritoryType != aetheryteData.TerritoryIds[to])
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
@ -242,6 +251,6 @@ internal static class AethernetShortcut
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => $"UseAethernet({From} -> {To})";
|
||||
public override string ToString() => $"UseAethernet({from} -> {to})";
|
||||
}
|
||||
}
|
||||
|
@ -18,23 +18,38 @@ namespace Questionable.Controller.Steps.Shared;
|
||||
internal static class AetheryteShortcut
|
||||
{
|
||||
internal sealed class Factory(
|
||||
IServiceProvider serviceProvider,
|
||||
AetheryteData aetheryteData) : ITaskFactory
|
||||
AetheryteData aetheryteData,
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
QuestFunctions questFunctions,
|
||||
IClientState clientState,
|
||||
IChatGui chatGui,
|
||||
ILoggerFactory loggerFactory) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (step.AetheryteShortcut == null)
|
||||
yield break;
|
||||
|
||||
yield return serviceProvider.GetRequiredService<UseAetheryteShortcut>()
|
||||
.With(step, quest.Id, step.AetheryteShortcut.Value,
|
||||
yield return Use(step, quest.Id, step.AetheryteShortcut.Value,
|
||||
aetheryteData.TerritoryIds[step.AetheryteShortcut.Value]);
|
||||
yield return serviceProvider.GetRequiredService<WaitAtEnd.WaitDelay>()
|
||||
.With(TimeSpan.FromSeconds(0.5));
|
||||
yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(0.5));
|
||||
}
|
||||
|
||||
public ITask Use(QuestStep? step, ElementId? elementId, EAetheryteLocation targetAetheryte,
|
||||
ushort expectedTerritoryId)
|
||||
{
|
||||
return new UseAetheryteShortcut(step, elementId, targetAetheryte, expectedTerritoryId,
|
||||
loggerFactory.CreateLogger<UseAetheryteShortcut>(), aetheryteFunctions, questFunctions, clientState,
|
||||
chatGui, aetheryteData);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class UseAetheryteShortcut(
|
||||
/// <param name="expectedTerritoryId">If using an aethernet shortcut after, the aetheryte's territory-id and the step's territory-id can differ, we always use the aetheryte's territory-id.</param>
|
||||
private sealed class UseAetheryteShortcut(
|
||||
QuestStep? step,
|
||||
ElementId? elementId,
|
||||
EAetheryteLocation targetAetheryte,
|
||||
ushort expectedTerritoryId,
|
||||
ILogger<UseAetheryteShortcut> logger,
|
||||
AetheryteFunctions aetheryteFunctions,
|
||||
QuestFunctions questFunctions,
|
||||
@ -45,26 +60,6 @@ internal static class AetheryteShortcut
|
||||
private bool _teleported;
|
||||
private DateTime _continueAt;
|
||||
|
||||
public QuestStep? Step { get; set; }
|
||||
public ElementId? ElementId { get; set; }
|
||||
public EAetheryteLocation TargetAetheryte { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If using an aethernet shortcut after, the aetheryte's territory-id and the step's territory-id can differ,
|
||||
/// we always use the aetheryte's territory-id.
|
||||
/// </summary>
|
||||
public ushort ExpectedTerritoryId { get; set; }
|
||||
|
||||
public ITask With(QuestStep? step, ElementId? elementId, EAetheryteLocation targetAetheryte,
|
||||
ushort expectedTerritoryId)
|
||||
{
|
||||
Step = step;
|
||||
ElementId = elementId;
|
||||
TargetAetheryte = targetAetheryte;
|
||||
ExpectedTerritoryId = expectedTerritoryId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start() => !ShouldSkipTeleport();
|
||||
|
||||
public ETaskResult Update()
|
||||
@ -78,7 +73,7 @@ internal static class AetheryteShortcut
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
if (clientState.TerritoryType == ExpectedTerritoryId)
|
||||
if (clientState.TerritoryType == expectedTerritoryId)
|
||||
return ETaskResult.TaskComplete;
|
||||
|
||||
return ETaskResult.StillRunning;
|
||||
@ -87,9 +82,9 @@ internal static class AetheryteShortcut
|
||||
private bool ShouldSkipTeleport()
|
||||
{
|
||||
ushort territoryType = clientState.TerritoryType;
|
||||
if (Step != null)
|
||||
if (step != null)
|
||||
{
|
||||
var skipConditions = Step.SkipConditions?.AetheryteShortcutIf ?? new();
|
||||
var skipConditions = step.SkipConditions?.AetheryteShortcutIf ?? new();
|
||||
if (skipConditions is { Never: false })
|
||||
{
|
||||
if (skipConditions.InTerritory.Contains(territoryType))
|
||||
@ -112,12 +107,12 @@ internal static class AetheryteShortcut
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ElementId != null)
|
||||
if (elementId != null)
|
||||
{
|
||||
QuestProgressInfo? questWork = questFunctions.GetQuestProgressInfo(ElementId);
|
||||
QuestProgressInfo? questWork = questFunctions.GetQuestProgressInfo(elementId);
|
||||
if (skipConditions.RequiredQuestVariablesNotMet &&
|
||||
questWork != null &&
|
||||
!QuestWorkUtils.MatchesRequiredQuestWorkConfig(Step.RequiredQuestVariables, questWork,
|
||||
!QuestWorkUtils.MatchesRequiredQuestWorkConfig(step.RequiredQuestVariables, questWork,
|
||||
logger))
|
||||
{
|
||||
logger.LogInformation("Skipping aetheryte teleport, as required variables do not match");
|
||||
@ -126,10 +121,11 @@ internal static class AetheryteShortcut
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (skipConditions.NearPosition is { } nearPosition && clientState.TerritoryType == Step.TerritoryId)
|
||||
if (skipConditions.NearPosition is { } nearPosition &&
|
||||
clientState.TerritoryType == step.TerritoryId)
|
||||
{
|
||||
if (Vector3.Distance(nearPosition.Position, clientState.LocalPlayer!.Position) <= nearPosition.MaximumDistance)
|
||||
if (Vector3.Distance(nearPosition.Position, clientState.LocalPlayer!.Position) <=
|
||||
nearPosition.MaximumDistance)
|
||||
{
|
||||
logger.LogInformation("Skipping aetheryte shortcut, as we're near the position");
|
||||
return true;
|
||||
@ -137,7 +133,7 @@ internal static class AetheryteShortcut
|
||||
}
|
||||
}
|
||||
|
||||
if (ExpectedTerritoryId == territoryType)
|
||||
if (expectedTerritoryId == territoryType)
|
||||
{
|
||||
if (!skipConditions.Never)
|
||||
{
|
||||
@ -148,17 +144,17 @@ internal static class AetheryteShortcut
|
||||
}
|
||||
|
||||
Vector3 pos = clientState.LocalPlayer!.Position;
|
||||
if (Step.Position != null &&
|
||||
(pos - Step.Position.Value).Length() < Step.CalculateActualStopDistance())
|
||||
if (step.Position != null &&
|
||||
(pos - step.Position.Value).Length() < step.CalculateActualStopDistance())
|
||||
{
|
||||
logger.LogInformation("Skipping aetheryte teleport, we're near the target");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aetheryteData.CalculateDistance(pos, territoryType, TargetAetheryte) < 20 ||
|
||||
(Step.AethernetShortcut != null &&
|
||||
(aetheryteData.CalculateDistance(pos, territoryType, Step.AethernetShortcut.From) < 20 ||
|
||||
aetheryteData.CalculateDistance(pos, territoryType, Step.AethernetShortcut.To) < 20)))
|
||||
if (aetheryteData.CalculateDistance(pos, territoryType, targetAetheryte) < 20 ||
|
||||
(step.AethernetShortcut != null &&
|
||||
(aetheryteData.CalculateDistance(pos, territoryType, step.AethernetShortcut.From) < 20 ||
|
||||
aetheryteData.CalculateDistance(pos, territoryType, step.AethernetShortcut.To) < 20)))
|
||||
{
|
||||
logger.LogInformation("Skipping aetheryte teleport");
|
||||
return true;
|
||||
@ -172,7 +168,7 @@ internal static class AetheryteShortcut
|
||||
|
||||
private bool DoTeleport()
|
||||
{
|
||||
if (!aetheryteFunctions.CanTeleport(TargetAetheryte))
|
||||
if (!aetheryteFunctions.CanTeleport(targetAetheryte))
|
||||
{
|
||||
if (!aetheryteFunctions.IsTeleportUnlocked())
|
||||
throw new TaskException("Teleport is not unlocked, attune to any aetheryte first.");
|
||||
@ -184,12 +180,12 @@ internal static class AetheryteShortcut
|
||||
|
||||
_continueAt = DateTime.Now.AddSeconds(8);
|
||||
|
||||
if (!aetheryteFunctions.IsAetheryteUnlocked(TargetAetheryte))
|
||||
if (!aetheryteFunctions.IsAetheryteUnlocked(targetAetheryte))
|
||||
{
|
||||
chatGui.PrintError($"[Questionable] Aetheryte {TargetAetheryte} is not unlocked.");
|
||||
chatGui.PrintError($"[Questionable] Aetheryte {targetAetheryte} is not unlocked.");
|
||||
throw new TaskException("Aetheryte is not unlocked");
|
||||
}
|
||||
else if (aetheryteFunctions.TeleportAetheryte(TargetAetheryte))
|
||||
else if (aetheryteFunctions.TeleportAetheryte(targetAetheryte))
|
||||
{
|
||||
logger.LogInformation("Travelling via aetheryte...");
|
||||
return true;
|
||||
@ -201,6 +197,6 @@ internal static class AetheryteShortcut
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => $"UseAetheryte({TargetAetheryte})";
|
||||
public override string ToString() => $"UseAetheryte({targetAetheryte})";
|
||||
}
|
||||
}
|
||||
|
@ -7,18 +7,22 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using LLib.GameData;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.External;
|
||||
using Questionable.Model.Questing;
|
||||
using Mount = Questionable.Controller.Steps.Common.Mount;
|
||||
using Quest = Questionable.Model.Quest;
|
||||
|
||||
namespace Questionable.Controller.Steps.Shared;
|
||||
|
||||
internal static class Craft
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory
|
||||
internal sealed class Factory(
|
||||
IDataManager dataManager,
|
||||
IClientState clientState,
|
||||
ArtisanIpc artisanIpc,
|
||||
Mount.Factory mountFactory,
|
||||
ILoggerFactory loggerFactory) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -29,40 +33,34 @@ internal static class Craft
|
||||
ArgumentNullException.ThrowIfNull(step.ItemCount);
|
||||
return
|
||||
[
|
||||
serviceProvider.GetRequiredService<UnmountTask>(),
|
||||
serviceProvider.GetRequiredService<DoCraft>()
|
||||
.With(step.ItemId.Value, step.ItemCount.Value)
|
||||
mountFactory.Unmount(),
|
||||
Craft(step.ItemId.Value, step.ItemCount.Value)
|
||||
];
|
||||
}
|
||||
|
||||
public ITask Craft(uint itemId, int itemCount) =>
|
||||
new DoCraft(itemId, itemCount, dataManager, clientState, artisanIpc, loggerFactory.CreateLogger<DoCraft>());
|
||||
}
|
||||
|
||||
internal sealed class DoCraft(
|
||||
private sealed class DoCraft(
|
||||
uint itemId,
|
||||
int itemCount,
|
||||
IDataManager dataManager,
|
||||
IClientState clientState,
|
||||
ArtisanIpc artisanIpc,
|
||||
ILogger<DoCraft> logger) : ITask
|
||||
{
|
||||
private uint _itemId;
|
||||
private int _itemCount;
|
||||
|
||||
public ITask With(uint itemId, int itemCount)
|
||||
{
|
||||
_itemId = itemId;
|
||||
_itemCount = itemCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (HasRequestedItems())
|
||||
{
|
||||
logger.LogInformation("Already own {ItemCount}x {ItemId}", _itemCount, _itemId);
|
||||
logger.LogInformation("Already own {ItemCount}x {ItemId}", itemCount, itemId);
|
||||
return false;
|
||||
}
|
||||
|
||||
RecipeLookup? recipeLookup = dataManager.GetExcelSheet<RecipeLookup>()!.GetRow(_itemId);
|
||||
RecipeLookup? recipeLookup = dataManager.GetExcelSheet<RecipeLookup>()!.GetRow(itemId);
|
||||
if (recipeLookup == null)
|
||||
throw new TaskException($"Item {_itemId} is not craftable");
|
||||
throw new TaskException($"Item {itemId} is not craftable");
|
||||
|
||||
uint recipeId = (EClassJob)clientState.LocalPlayer!.ClassJob.Id switch
|
||||
{
|
||||
@ -94,12 +92,12 @@ internal static class Craft
|
||||
}
|
||||
|
||||
if (recipeId == 0)
|
||||
throw new TaskException($"Unable to determine recipe for item {_itemId}");
|
||||
throw new TaskException($"Unable to determine recipe for item {itemId}");
|
||||
|
||||
int remainingItemCount = _itemCount - GetOwnedItemCount();
|
||||
int remainingItemCount = itemCount - GetOwnedItemCount();
|
||||
logger.LogInformation(
|
||||
"Starting craft for item {ItemId} with recipe {RecipeId} for {RemainingItemCount} items",
|
||||
_itemId, recipeId, remainingItemCount);
|
||||
itemId, recipeId, remainingItemCount);
|
||||
if (!artisanIpc.CraftItem((ushort)recipeId, remainingItemCount))
|
||||
throw new TaskException($"Failed to start Artisan craft for recipe {recipeId}");
|
||||
|
||||
@ -130,15 +128,15 @@ internal static class Craft
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
private bool HasRequestedItems() => GetOwnedItemCount() >= _itemCount;
|
||||
private bool HasRequestedItems() => GetOwnedItemCount() >= itemCount;
|
||||
|
||||
private unsafe int GetOwnedItemCount()
|
||||
{
|
||||
InventoryManager* inventoryManager = InventoryManager.Instance();
|
||||
return inventoryManager->GetInventoryItemCount(_itemId, isHq: false, checkEquipped: false)
|
||||
+ inventoryManager->GetInventoryItemCount(_itemId, isHq: true, checkEquipped: false);
|
||||
return inventoryManager->GetInventoryItemCount(itemId, isHq: false, checkEquipped: false)
|
||||
+ inventoryManager->GetInventoryItemCount(itemId, isHq: true, checkEquipped: false);
|
||||
}
|
||||
|
||||
public override string ToString() => $"Craft {_itemCount}x {_itemId} (with Artisan)";
|
||||
public override string ToString() => $"Craft {itemCount}x {itemId} (with Artisan)";
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.Data;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Gathering;
|
||||
using Questionable.Model.Questing;
|
||||
@ -22,6 +21,7 @@ internal static class GatheringRequiredItems
|
||||
internal sealed class Factory(
|
||||
IServiceProvider serviceProvider,
|
||||
MovementController movementController,
|
||||
GatheringController gatheringController,
|
||||
GatheringPointRegistry gatheringPointRegistry,
|
||||
IClientState clientState,
|
||||
GatheringData gatheringData,
|
||||
@ -50,8 +50,7 @@ internal static class GatheringRequiredItems
|
||||
|
||||
if (classJob != currentClassJob)
|
||||
{
|
||||
yield return serviceProvider.GetRequiredService<SwitchClassJob>()
|
||||
.With(classJob);
|
||||
yield return new SwitchClassJob(classJob, clientState);
|
||||
}
|
||||
|
||||
if (HasRequiredItems(requiredGatheredItems))
|
||||
@ -69,7 +68,7 @@ internal static class GatheringRequiredItems
|
||||
foreach (var task in serviceProvider.GetRequiredService<TaskCreator>()
|
||||
.CreateTasks(quest, gatheringSequence, gatheringStep))
|
||||
if (task is WaitAtEnd.NextStep)
|
||||
yield return serviceProvider.GetRequiredService<SkipMarker>();
|
||||
yield return CreateSkipMarkerTask();
|
||||
else
|
||||
yield return task;
|
||||
}
|
||||
@ -82,8 +81,7 @@ internal static class GatheringRequiredItems
|
||||
yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
|
||||
"Wait(navmesh ready)");
|
||||
|
||||
yield return serviceProvider.GetRequiredService<StartGathering>()
|
||||
.With(gatheringPointId, requiredGatheredItems);
|
||||
yield return CreateStartGatheringTask(gatheringPointId, requiredGatheredItems);
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,25 +105,28 @@ internal static class GatheringRequiredItems
|
||||
minCollectability: (short)requiredGatheredItems.Collectability) >=
|
||||
requiredGatheredItems.ItemCount;
|
||||
}
|
||||
|
||||
private StartGathering CreateStartGatheringTask(GatheringPointId gatheringPointId, GatheredItem gatheredItem)
|
||||
{
|
||||
return new StartGathering(gatheringPointId, gatheredItem, gatheringController);
|
||||
}
|
||||
|
||||
internal sealed class StartGathering(GatheringController gatheringController) : ITask
|
||||
private static SkipMarker CreateSkipMarkerTask()
|
||||
{
|
||||
private GatheringPointId _gatheringPointId = null!;
|
||||
private GatheredItem _gatheredItem = null!;
|
||||
|
||||
public ITask With(GatheringPointId gatheringPointId, GatheredItem gatheredItem)
|
||||
{
|
||||
_gatheringPointId = gatheringPointId;
|
||||
_gatheredItem = gatheredItem;
|
||||
return this;
|
||||
return new SkipMarker();
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class StartGathering(
|
||||
GatheringPointId gatheringPointId,
|
||||
GatheredItem gatheredItem,
|
||||
GatheringController gatheringController) : ITask
|
||||
{
|
||||
public bool Start()
|
||||
{
|
||||
return gatheringController.Start(new GatheringController.GatheringRequest(_gatheringPointId,
|
||||
_gatheredItem.ItemId, _gatheredItem.AlternativeItemId, _gatheredItem.ItemCount,
|
||||
_gatheredItem.Collectability));
|
||||
return gatheringController.Start(new GatheringController.GatheringRequest(gatheringPointId,
|
||||
gatheredItem.ItemId, gatheredItem.AlternativeItemId, gatheredItem.ItemCount,
|
||||
gatheredItem.Collectability));
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
@ -138,11 +139,11 @@ internal static class GatheringRequiredItems
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (_gatheredItem.Collectability == 0)
|
||||
return $"Gather({_gatheredItem.ItemCount}x {_gatheredItem.ItemId})";
|
||||
if (gatheredItem.Collectability == 0)
|
||||
return $"Gather({gatheredItem.ItemCount}x {gatheredItem.ItemId})";
|
||||
else
|
||||
return
|
||||
$"Gather({_gatheredItem.ItemCount}x {_gatheredItem.ItemId} {SeIconChar.Collectible.ToIconString()} {_gatheredItem.Collectability})";
|
||||
$"Gather({gatheredItem.ItemCount}x {gatheredItem.ItemId} {SeIconChar.Collectible.ToIconString()} {gatheredItem.Collectability})";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,330 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using LLib;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.Data;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
using Action = System.Action;
|
||||
using Quest = Questionable.Model.Quest;
|
||||
|
||||
namespace Questionable.Controller.Steps.Shared;
|
||||
|
||||
internal static class Move
|
||||
{
|
||||
internal sealed class Factory(IServiceProvider serviceProvider, AetheryteData aetheryteData) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (step.Position != null)
|
||||
{
|
||||
var builder = serviceProvider.GetRequiredService<MoveBuilder>();
|
||||
builder.Step = step;
|
||||
builder.Destination = step.Position.Value;
|
||||
return builder.Build();
|
||||
}
|
||||
else if (step is { DataId: not null, StopDistance: not null })
|
||||
{
|
||||
var task = serviceProvider.GetRequiredService<ExpectToBeNearDataId>();
|
||||
task.DataId = step.DataId.Value;
|
||||
task.StopDistance = step.StopDistance.Value;
|
||||
return [task];
|
||||
}
|
||||
else if (step is { InteractionType: EInteractionType.AttuneAetheryte, Aetheryte: not null })
|
||||
{
|
||||
var builder = serviceProvider.GetRequiredService<MoveBuilder>();
|
||||
builder.Step = step;
|
||||
builder.Destination = aetheryteData.Locations[step.Aetheryte.Value];
|
||||
return builder.Build();
|
||||
}
|
||||
else if (step is { InteractionType: EInteractionType.AttuneAethernetShard, AethernetShard: not null })
|
||||
{
|
||||
var builder = serviceProvider.GetRequiredService<MoveBuilder>();
|
||||
builder.Step = step;
|
||||
builder.Destination = aetheryteData.Locations[step.AethernetShard.Value];
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class MoveBuilder(
|
||||
IServiceProvider serviceProvider,
|
||||
ILogger<MoveBuilder> logger,
|
||||
GameFunctions gameFunctions,
|
||||
IClientState clientState,
|
||||
MovementController movementController,
|
||||
TerritoryData territoryData,
|
||||
AetheryteData aetheryteData)
|
||||
{
|
||||
public ElementId QuestId { get; set; } = null!;
|
||||
public QuestStep Step { get; set; } = null!;
|
||||
public Vector3 Destination { get; set; }
|
||||
|
||||
public IEnumerable<ITask> Build()
|
||||
{
|
||||
if (Step.InteractionType == EInteractionType.Jump && Step.JumpDestination != null &&
|
||||
(clientState.LocalPlayer!.Position - Step.JumpDestination.Position).Length() <=
|
||||
(Step.JumpDestination.StopDistance ?? 1f))
|
||||
{
|
||||
logger.LogInformation("We're at the jump destination, skipping movement");
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new WaitConditionTask(() => clientState.TerritoryType == Step.TerritoryId,
|
||||
$"Wait(territory: {territoryData.GetNameAndId(Step.TerritoryId)})");
|
||||
|
||||
if (!Step.DisableNavmesh)
|
||||
yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
|
||||
"Wait(navmesh ready)");
|
||||
|
||||
float stopDistance = Step.CalculateActualStopDistance();
|
||||
Vector3? position = clientState.LocalPlayer?.Position;
|
||||
float actualDistance = position == null ? float.MaxValue : Vector3.Distance(position.Value, Destination);
|
||||
|
||||
// if we teleport to a different zone, assume we always need to move; this is primarily relevant for cases
|
||||
// where you're e.g. in Lakeland, and the step navigates via Crystarium → Tesselation back into the same
|
||||
// zone.
|
||||
//
|
||||
// Side effects of this check being broken include:
|
||||
// - mounting when near the target npc (if you spawn close enough for the next step)
|
||||
// - trying to fly when near the target npc (if close enough where no movement is required)
|
||||
if (Step.AetheryteShortcut != null &&
|
||||
aetheryteData.TerritoryIds[Step.AetheryteShortcut.Value] != Step.TerritoryId)
|
||||
{
|
||||
logger.LogDebug("Aetheryte: Changing distance to max, previous distance: {Distance}", actualDistance);
|
||||
actualDistance = float.MaxValue;
|
||||
}
|
||||
|
||||
if (QuestId is SatisfactionSupplyNpcId)
|
||||
{
|
||||
logger.LogDebug("SatisfactionSupply: Changing distance to max, previous distance: {Distance}",
|
||||
actualDistance);
|
||||
actualDistance = float.MaxValue;
|
||||
}
|
||||
|
||||
if (Step.Mount == true)
|
||||
yield return serviceProvider.GetRequiredService<MountTask>()
|
||||
.With(Step.TerritoryId, MountTask.EMountIf.Always);
|
||||
else if (Step.Mount == false)
|
||||
yield return serviceProvider.GetRequiredService<UnmountTask>();
|
||||
|
||||
if (!Step.DisableNavmesh)
|
||||
{
|
||||
if (Step.Mount == null)
|
||||
{
|
||||
MountTask.EMountIf mountIf =
|
||||
actualDistance > stopDistance && Step.Fly == true &&
|
||||
gameFunctions.IsFlyingUnlocked(Step.TerritoryId)
|
||||
? MountTask.EMountIf.Always
|
||||
: MountTask.EMountIf.AwayFromPosition;
|
||||
yield return serviceProvider.GetRequiredService<MountTask>()
|
||||
.With(Step.TerritoryId, mountIf, Destination);
|
||||
}
|
||||
|
||||
if (actualDistance > stopDistance)
|
||||
{
|
||||
yield return serviceProvider.GetRequiredService<MoveInternal>()
|
||||
.With(Step, Destination);
|
||||
}
|
||||
else
|
||||
logger.LogInformation("Skipping move task, distance: {ActualDistance} < {StopDistance}",
|
||||
actualDistance, stopDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
// navmesh won't move close enough
|
||||
if (actualDistance > stopDistance)
|
||||
{
|
||||
yield return serviceProvider.GetRequiredService<MoveInternal>()
|
||||
.With(Step, Destination);
|
||||
}
|
||||
else
|
||||
logger.LogInformation("Skipping move task, distance: {ActualDistance} < {StopDistance}",
|
||||
actualDistance, stopDistance);
|
||||
}
|
||||
|
||||
if (Step.Fly == true && Step.Land == true)
|
||||
yield return serviceProvider.GetRequiredService<Land>();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class MoveInternal(
|
||||
MovementController movementController,
|
||||
GameFunctions gameFunctions,
|
||||
ILogger<MoveInternal> logger,
|
||||
ICondition condition,
|
||||
IDataManager dataManager) : ITask, IToastAware
|
||||
{
|
||||
private string _cannotExecuteAtThisTime = dataManager.GetString<LogMessage>(579, x => x.Text)!;
|
||||
|
||||
public Action StartAction { get; set; } = null!;
|
||||
public Vector3 Destination { get; set; }
|
||||
|
||||
public ITask With(QuestStep step, Vector3 destination)
|
||||
{
|
||||
return With(
|
||||
territoryId: step.TerritoryId,
|
||||
destination: destination,
|
||||
stopDistance: step.CalculateActualStopDistance(),
|
||||
dataId: step.DataId,
|
||||
disableNavMesh: step.DisableNavmesh,
|
||||
sprint: step.Sprint != false,
|
||||
fly: step.Fly == true,
|
||||
land: step.Land == true,
|
||||
ignoreDistanceToObject: step.IgnoreDistanceToObject == true);
|
||||
}
|
||||
|
||||
public ITask With(ushort territoryId, Vector3 destination, float? stopDistance = null, uint? dataId = null,
|
||||
bool disableNavMesh = false, bool sprint = true, bool fly = false, bool land = false,
|
||||
bool ignoreDistanceToObject = false)
|
||||
{
|
||||
Destination = destination;
|
||||
|
||||
if (!gameFunctions.IsFlyingUnlocked(territoryId))
|
||||
{
|
||||
fly = false;
|
||||
land = false;
|
||||
}
|
||||
|
||||
if (!disableNavMesh)
|
||||
{
|
||||
StartAction = () =>
|
||||
movementController.NavigateTo(EMovementType.Quest, dataId, Destination,
|
||||
fly: fly,
|
||||
sprint: sprint,
|
||||
stopDistance: stopDistance,
|
||||
ignoreDistanceToObject: ignoreDistanceToObject,
|
||||
land: land);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartAction = () =>
|
||||
movementController.NavigateTo(EMovementType.Quest, dataId, [Destination],
|
||||
fly: fly,
|
||||
sprint: sprint,
|
||||
stopDistance: stopDistance,
|
||||
ignoreDistanceToObject: ignoreDistanceToObject,
|
||||
land: land);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
logger.LogInformation("Moving to {Destination}", Destination.ToString("G", CultureInfo.InvariantCulture));
|
||||
StartAction();
|
||||
return true;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (movementController.IsPathfinding || movementController.IsPathRunning)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
DateTime movementStartedAt = movementController.MovementStartedAt;
|
||||
if (movementStartedAt == DateTime.MaxValue || movementStartedAt.AddSeconds(2) >= DateTime.Now)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => $"MoveTo({Destination.ToString("G", CultureInfo.InvariantCulture)})";
|
||||
|
||||
public bool OnErrorToast(SeString message)
|
||||
{
|
||||
if (GameFunctions.GameStringEquals(_cannotExecuteAtThisTime, message.TextValue) &&
|
||||
condition[ConditionFlag.Diving])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ExpectToBeNearDataId(GameFunctions gameFunctions, IClientState clientState) : ITask
|
||||
{
|
||||
public uint DataId { get; set; }
|
||||
public float StopDistance { get; set; }
|
||||
|
||||
public bool Start() => true;
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId);
|
||||
if (gameObject == null ||
|
||||
(gameObject.Position - clientState.LocalPlayer!.Position).Length() > StopDistance)
|
||||
{
|
||||
throw new TaskException("Object not found or too far away, no position so we can't move");
|
||||
}
|
||||
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Land(IClientState clientState, ICondition condition, ILogger<Land> logger) : ITask
|
||||
{
|
||||
private bool _landing;
|
||||
private DateTime _continueAt;
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!condition[ConditionFlag.InFlight])
|
||||
{
|
||||
logger.LogInformation("Not flying, not attempting to land");
|
||||
return false;
|
||||
}
|
||||
|
||||
_landing = AttemptLanding();
|
||||
_continueAt = DateTime.Now.AddSeconds(0.25);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (DateTime.Now < _continueAt)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
if (condition[ConditionFlag.InFlight])
|
||||
{
|
||||
if (!_landing)
|
||||
{
|
||||
_landing = AttemptLanding();
|
||||
_continueAt = DateTime.Now.AddSeconds(0.25);
|
||||
}
|
||||
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
private unsafe bool AttemptLanding()
|
||||
{
|
||||
var character = (Character*)(clientState.LocalPlayer?.Address ?? 0);
|
||||
if (character != null)
|
||||
{
|
||||
if (ActionManager.Instance()->GetActionStatus(ActionType.GeneralAction, 23) == 0)
|
||||
{
|
||||
logger.LogInformation("Attempting to land");
|
||||
return ActionManager.Instance()->UseAction(ActionType.GeneralAction, 23);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
340
Questionable/Controller/Steps/Shared/MoveTo.cs
Normal file
340
Questionable/Controller/Steps/Shared/MoveTo.cs
Normal file
@ -0,0 +1,340 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using LLib;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.Data;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
using Action = System.Action;
|
||||
using Mount = Questionable.Controller.Steps.Common.Mount;
|
||||
using Quest = Questionable.Model.Quest;
|
||||
|
||||
namespace Questionable.Controller.Steps.Shared;
|
||||
|
||||
internal static class MoveTo
|
||||
{
|
||||
internal sealed class Factory(
|
||||
MovementController movementController,
|
||||
GameFunctions gameFunctions,
|
||||
ICondition condition,
|
||||
IDataManager dataManager,
|
||||
IClientState clientState,
|
||||
AetheryteData aetheryteData,
|
||||
TerritoryData territoryData,
|
||||
ILoggerFactory loggerFactory,
|
||||
Mount.Factory mountFactory,
|
||||
ILogger<Factory> logger) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
if (step.Position != null)
|
||||
{
|
||||
return CreateMountTasks(quest.Id, step, step.Position.Value);
|
||||
}
|
||||
else if (step is { DataId: not null, StopDistance: not null })
|
||||
{
|
||||
return [ExpectToBeNearDataId(step.DataId.Value, step.StopDistance.Value)];
|
||||
}
|
||||
else if (step is { InteractionType: EInteractionType.AttuneAetheryte, Aetheryte: not null })
|
||||
{
|
||||
return CreateMountTasks(quest.Id, step, aetheryteData.Locations[step.Aetheryte.Value]);
|
||||
}
|
||||
else if (step is { InteractionType: EInteractionType.AttuneAethernetShard, AethernetShard: not null })
|
||||
{
|
||||
return CreateMountTasks(quest.Id, step, aetheryteData.Locations[step.AethernetShard.Value]);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public ITask Move(QuestStep step, Vector3 destination)
|
||||
{
|
||||
return Move(new MoveParams(step, destination));
|
||||
}
|
||||
|
||||
public ITask Move(MoveParams moveParams)
|
||||
{
|
||||
return new MoveInternal(moveParams, movementController, gameFunctions,
|
||||
loggerFactory.CreateLogger<MoveInternal>(), condition, dataManager);
|
||||
}
|
||||
|
||||
public ITask Land()
|
||||
{
|
||||
return new LandTask(clientState, condition, loggerFactory.CreateLogger<LandTask>());
|
||||
}
|
||||
|
||||
public ITask ExpectToBeNearDataId(uint dataId, float stopDistance)
|
||||
{
|
||||
return new WaitForNearDataId(dataId, stopDistance, gameFunctions, clientState);
|
||||
}
|
||||
|
||||
public IEnumerable<ITask> CreateMountTasks(ElementId questId, QuestStep step, Vector3 destination)
|
||||
{
|
||||
if (step.InteractionType == EInteractionType.Jump && step.JumpDestination != null &&
|
||||
(clientState.LocalPlayer!.Position - step.JumpDestination.Position).Length() <=
|
||||
(step.JumpDestination.StopDistance ?? 1f))
|
||||
{
|
||||
logger.LogInformation("We're at the jump destination, skipping movement");
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new WaitConditionTask(() => clientState.TerritoryType == step.TerritoryId,
|
||||
$"Wait(territory: {territoryData.GetNameAndId(step.TerritoryId)})");
|
||||
|
||||
if (!step.DisableNavmesh)
|
||||
yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
|
||||
"Wait(navmesh ready)");
|
||||
|
||||
float stopDistance = step.CalculateActualStopDistance();
|
||||
Vector3? position = clientState.LocalPlayer?.Position;
|
||||
float actualDistance = position == null ? float.MaxValue : Vector3.Distance(position.Value, destination);
|
||||
|
||||
// if we teleport to a different zone, assume we always need to move; this is primarily relevant for cases
|
||||
// where you're e.g. in Lakeland, and the step navigates via Crystarium → Tesselation back into the same
|
||||
// zone.
|
||||
//
|
||||
// Side effects of this check being broken include:
|
||||
// - mounting when near the target npc (if you spawn close enough for the next step)
|
||||
// - trying to fly when near the target npc (if close enough where no movement is required)
|
||||
if (step.AetheryteShortcut != null &&
|
||||
aetheryteData.TerritoryIds[step.AetheryteShortcut.Value] != step.TerritoryId)
|
||||
{
|
||||
logger.LogDebug("Aetheryte: Changing distance to max, previous distance: {Distance}", actualDistance);
|
||||
actualDistance = float.MaxValue;
|
||||
}
|
||||
|
||||
if (step.Mount == true)
|
||||
yield return mountFactory.Mount(step.TerritoryId, Mount.EMountIf.Always);
|
||||
else if (step.Mount == false)
|
||||
yield return mountFactory.Unmount();
|
||||
|
||||
if (!step.DisableNavmesh)
|
||||
{
|
||||
if (step.Mount == null)
|
||||
{
|
||||
Mount.EMountIf mountIf =
|
||||
actualDistance > stopDistance && step.Fly == true &&
|
||||
gameFunctions.IsFlyingUnlocked(step.TerritoryId)
|
||||
? Mount.EMountIf.Always
|
||||
: Mount.EMountIf.AwayFromPosition;
|
||||
yield return mountFactory.Mount(step.TerritoryId, mountIf, destination);
|
||||
}
|
||||
|
||||
if (actualDistance > stopDistance)
|
||||
{
|
||||
yield return Move(step, destination);
|
||||
}
|
||||
else
|
||||
logger.LogInformation("Skipping move task, distance: {ActualDistance} < {StopDistance}",
|
||||
actualDistance, stopDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
// navmesh won't move close enough
|
||||
if (actualDistance > stopDistance)
|
||||
{
|
||||
yield return Move(step, destination);
|
||||
}
|
||||
else
|
||||
logger.LogInformation("Skipping move task, distance: {ActualDistance} < {StopDistance}",
|
||||
actualDistance, stopDistance);
|
||||
}
|
||||
|
||||
if (step.Fly == true && step.Land == true)
|
||||
yield return Land();
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class MoveInternal : ITask, IToastAware
|
||||
{
|
||||
private readonly string _cannotExecuteAtThisTime;
|
||||
private readonly MovementController _movementController;
|
||||
private readonly ILogger<MoveInternal> _logger;
|
||||
private readonly ICondition _condition;
|
||||
|
||||
private readonly Action _startAction;
|
||||
private readonly Vector3 _destination;
|
||||
|
||||
public MoveInternal(MoveParams moveParams,
|
||||
MovementController movementController,
|
||||
GameFunctions gameFunctions,
|
||||
ILogger<MoveInternal> logger,
|
||||
ICondition condition,
|
||||
IDataManager dataManager)
|
||||
{
|
||||
_movementController = movementController;
|
||||
_logger = logger;
|
||||
_condition = condition;
|
||||
_cannotExecuteAtThisTime = dataManager.GetString<LogMessage>(579, x => x.Text)!;
|
||||
|
||||
_destination = moveParams.Destination;
|
||||
|
||||
if (!gameFunctions.IsFlyingUnlocked(moveParams.TerritoryId))
|
||||
{
|
||||
moveParams = moveParams with { Fly = false, Land = false };
|
||||
}
|
||||
|
||||
if (!moveParams.DisableNavMesh)
|
||||
{
|
||||
_startAction = () =>
|
||||
_movementController.NavigateTo(EMovementType.Quest, moveParams.DataId, _destination,
|
||||
fly: moveParams.Fly,
|
||||
sprint: moveParams.Sprint,
|
||||
stopDistance: moveParams.StopDistance,
|
||||
ignoreDistanceToObject: moveParams.IgnoreDistanceToObject,
|
||||
land: moveParams.Land);
|
||||
}
|
||||
else
|
||||
{
|
||||
_startAction = () =>
|
||||
_movementController.NavigateTo(EMovementType.Quest, moveParams.DataId, [_destination],
|
||||
fly: moveParams.Fly,
|
||||
sprint: moveParams.Sprint,
|
||||
stopDistance: moveParams.StopDistance,
|
||||
ignoreDistanceToObject: moveParams.IgnoreDistanceToObject,
|
||||
land: moveParams.Land);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
_logger.LogInformation("Moving to {Destination}", _destination.ToString("G", CultureInfo.InvariantCulture));
|
||||
_startAction();
|
||||
return true;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (_movementController.IsPathfinding || _movementController.IsPathRunning)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
DateTime movementStartedAt = _movementController.MovementStartedAt;
|
||||
if (movementStartedAt == DateTime.MaxValue || movementStartedAt.AddSeconds(2) >= DateTime.Now)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
public override string ToString() => $"MoveTo({_destination.ToString("G", CultureInfo.InvariantCulture)})";
|
||||
|
||||
public bool OnErrorToast(SeString message)
|
||||
{
|
||||
if (GameFunctions.GameStringEquals(_cannotExecuteAtThisTime, message.TextValue) &&
|
||||
_condition[ConditionFlag.Diving])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed record MoveParams(
|
||||
ushort TerritoryId,
|
||||
Vector3 Destination,
|
||||
float? StopDistance = null,
|
||||
uint? DataId = null,
|
||||
bool DisableNavMesh = false,
|
||||
bool Sprint = true,
|
||||
bool Fly = false,
|
||||
bool Land = false,
|
||||
bool IgnoreDistanceToObject = false)
|
||||
{
|
||||
public MoveParams(QuestStep step, Vector3 destination)
|
||||
: this(step.TerritoryId,
|
||||
destination,
|
||||
step.CalculateActualStopDistance(),
|
||||
step.DataId,
|
||||
step.DisableNavmesh,
|
||||
step.Sprint != false,
|
||||
step.Fly == true,
|
||||
step.Land == true,
|
||||
step.IgnoreDistanceToObject == true)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class WaitForNearDataId(
|
||||
uint dataId,
|
||||
float stopDistance,
|
||||
GameFunctions gameFunctions,
|
||||
IClientState clientState) : ITask
|
||||
{
|
||||
public bool Start() => true;
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId);
|
||||
if (gameObject == null ||
|
||||
(gameObject.Position - clientState.LocalPlayer!.Position).Length() > stopDistance)
|
||||
{
|
||||
throw new TaskException("Object not found or too far away, no position so we can't move");
|
||||
}
|
||||
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class LandTask(IClientState clientState, ICondition condition, ILogger<LandTask> logger) : ITask
|
||||
{
|
||||
private bool _landing;
|
||||
private DateTime _continueAt;
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
if (!condition[ConditionFlag.InFlight])
|
||||
{
|
||||
logger.LogInformation("Not flying, not attempting to land");
|
||||
return false;
|
||||
}
|
||||
|
||||
_landing = AttemptLanding();
|
||||
_continueAt = DateTime.Now.AddSeconds(0.25);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ETaskResult Update()
|
||||
{
|
||||
if (DateTime.Now < _continueAt)
|
||||
return ETaskResult.StillRunning;
|
||||
|
||||
if (condition[ConditionFlag.InFlight])
|
||||
{
|
||||
if (!_landing)
|
||||
{
|
||||
_landing = AttemptLanding();
|
||||
_continueAt = DateTime.Now.AddSeconds(0.25);
|
||||
}
|
||||
|
||||
return ETaskResult.StillRunning;
|
||||
}
|
||||
|
||||
return ETaskResult.TaskComplete;
|
||||
}
|
||||
|
||||
private unsafe bool AttemptLanding()
|
||||
{
|
||||
var character = (Character*)(clientState.LocalPlayer?.Address ?? 0);
|
||||
if (character != null)
|
||||
{
|
||||
if (ActionManager.Instance()->GetActionStatus(ActionType.GeneralAction, 23) == 0)
|
||||
{
|
||||
logger.LogInformation("Attempting to land");
|
||||
return ActionManager.Instance()->UseAction(ActionType.GeneralAction, 23);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user