Compare commits

..

2 Commits

Author SHA1 Message Date
Plogon Enjoyer
f7e77dd9a9 test new quest schema
(cherry picked from commit 1bd92659c3)
(cherry picked from commit a5c51b73dc)
2024-08-31 18:38:26 +08:00
Plogon Enjoyer
d208c6663d Added MNK actions "Twin Snakes", "Demolish", "Dragon Kick", and "Form
Shift"
2024-08-31 18:37:28 +08:00
73 changed files with 120 additions and 676 deletions

View File

@ -62,9 +62,6 @@ internal static class QuestStepExtensions
Assignment(nameof(QuestStep.IgnoreDistanceToObject), Assignment(nameof(QuestStep.IgnoreDistanceToObject),
step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject) step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.RestartNavigationIfCancelled),
step.RestartNavigationIfCancelled, emptyStep.RestartNavigationIfCancelled)
.AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment) Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.Aetheryte), step.Aetheryte, emptyStep.Aetheryte) Assignment(nameof(QuestStep.Aetheryte), step.Aetheryte, emptyStep.Aetheryte)

View File

@ -53,7 +53,6 @@
"Y": -0.63573146, "Y": -0.63573146,
"Z": -166.33862 "Z": -166.33862
}, },
"StopDistance": 5,
"TerritoryId": 141, "TerritoryId": 141,
"InteractionType": "Interact" "InteractionType": "Interact"
} }

View File

@ -35,7 +35,6 @@
}, },
"TerritoryId": 155, "TerritoryId": 155,
"InteractionType": "CompleteQuest", "InteractionType": "CompleteQuest",
"Mount": true,
"DialogueChoices": [ "DialogueChoices": [
{ {
"Type": "YesNo", "Type": "YesNo",

View File

@ -337,6 +337,16 @@
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"Fly": true "Fly": true
}, },
{
"Position": {
"X": 233.0817,
"Y": 8,
"Z": -21.83023
},
"TerritoryId": 146,
"InteractionType": "WalkTo",
"Fly": true
},
{ {
"DataId": 2000077, "DataId": 2000077,
"Position": { "Position": {
@ -350,16 +360,18 @@
"KillEnemyDataIds": [ "KillEnemyDataIds": [
9489 9489
], ],
"$": "0 0 0 0 0 0 -> 16 17 0 0 0 128", "$": "0 0 0 0 0 0 -> 16 17 0 0 0 128"
"CompletionQuestVariablesFlags": [ },
null, {
null, "Position": {
null, "X": 614.4023,
null, "Y": 301.81046,
null, "Z": -101.94888
128 },
], "TerritoryId": 155,
"Fly": true "InteractionType": "WalkTo",
"Fly": true,
"AetheryteShortcut": "Coerthas Central Highlands - Camp Dragonhead"
}, },
{ {
"DataId": 2000078, "DataId": 2000078,
@ -374,17 +386,7 @@
"KillEnemyDataIds": [ "KillEnemyDataIds": [
9490 9490
], ],
"Fly": true, "$": "16 17 0 0 0 128 -> 0 17 0 0 0 0"
"AetheryteShortcut": "Coerthas Central Highlands - Camp Dragonhead",
"$": "16 17 0 0 0 128 -> 0 17 0 0 0 0",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
} }
] ]
}, },

View File

@ -191,15 +191,6 @@
"AethernetShard": "[Gold Saucer] Cactpot Board", "AethernetShard": "[Gold Saucer] Cactpot Board",
"DelaySecondsAtStart": 3 "DelaySecondsAtStart": 3
}, },
{
"Position": {
"X": 111.36922,
"Y": 13.000123,
"Z": -24.209782
},
"TerritoryId": 144,
"InteractionType": "WalkTo"
},
{ {
"DataId": 1011079, "DataId": 1011079,
"Position": { "Position": {
@ -216,15 +207,6 @@
{ {
"Sequence": 6, "Sequence": 6,
"Steps": [ "Steps": [
{
"Position": {
"X": 111.36922,
"Y": 13.000123,
"Z": -24.209782
},
"TerritoryId": 144,
"InteractionType": "WalkTo"
},
{ {
"TerritoryId": 144, "TerritoryId": 144,
"InteractionType": "None", "InteractionType": "None",

View File

@ -196,17 +196,6 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"Position": {
"X": -465.66104,
"Y": 43.041187,
"Z": 380.90747
},
"TerritoryId": 400,
"InteractionType": "WalkTo",
"Mount": true,
"DisableNavmesh": true
},
{ {
"DataId": 1013420, "DataId": 1013420,
"Position": { "Position": {
@ -215,7 +204,8 @@
"Z": 347.0968 "Z": 347.0968
}, },
"TerritoryId": 400, "TerritoryId": 400,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest",
"DisableNavmesh": true
} }
] ]
} }

View File

@ -111,7 +111,6 @@
}, },
"TerritoryId": 398, "TerritoryId": 398,
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"Mount": true,
"SkipConditions": { "SkipConditions": {
"StepIf": { "StepIf": {
"CompletionQuestVariablesFlags": [ "CompletionQuestVariablesFlags": [

View File

@ -20,15 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"Position": {
"X": 67.682434,
"Y": -49.685223,
"Z": -148.21802
},
"TerritoryId": 398,
"InteractionType": "WalkTo"
},
{ {
"DataId": 4001, "DataId": 4001,
"Position": { "Position": {

View File

@ -118,7 +118,6 @@
}, },
"TerritoryId": 398, "TerritoryId": 398,
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"Mount": true,
"SkipConditions": { "SkipConditions": {
"StepIf": { "StepIf": {
"CompletionQuestVariablesFlags": [ "CompletionQuestVariablesFlags": [

View File

@ -152,8 +152,7 @@
"Z": 22.9953 "Z": 22.9953
}, },
"TerritoryId": 398, "TerritoryId": 398,
"InteractionType": "CompleteQuest", "InteractionType": "CompleteQuest"
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine"
} }
] ]
} }

View File

@ -98,7 +98,6 @@
"Y": 205.6815, "Y": 205.6815,
"Z": 31.631958 "Z": 31.631958
}, },
"StopDistance": 5,
"TerritoryId": 478, "TerritoryId": 478,
"InteractionType": "CompleteQuest", "InteractionType": "CompleteQuest",
"AetheryteShortcut": "Idyllshire" "AetheryteShortcut": "Idyllshire"

View File

@ -30,17 +30,6 @@
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"TargetTerritoryId": 399 "TargetTerritoryId": 399
}, },
{
"DataId": 2006210,
"Position": {
"X": -487.48004,
"Y": 144.64026,
"Z": -285.359
},
"TerritoryId": 399,
"InteractionType": "AttuneAetherCurrent",
"AetherCurrentId": 2818088
},
{ {
"DataId": 1013651, "DataId": 1013651,
"Position": { "Position": {

View File

@ -20,15 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"Position": {
"X": -44.83911,
"Y": -1.6023016,
"Z": -655.73804
},
"TerritoryId": 401,
"InteractionType": "WalkTo"
},
{ {
"DataId": 2005824, "DataId": 2005824,
"Position": { "Position": {

View File

@ -135,20 +135,6 @@
{ {
"Sequence": 3, "Sequence": 3,
"Steps": [ "Steps": [
{
"Position": {
"X": 423.53406,
"Y": -26.253891,
"Z": -550.60297
},
"TerritoryId": 398,
"InteractionType": "WalkTo",
"SkipConditions": {
"StepIf": {
"Flying": "Unlocked"
}
}
},
{ {
"DataId": 2005573, "DataId": 2005573,
"Position": { "Position": {
@ -191,8 +177,7 @@
"StepIf": { "StepIf": {
"Flying": "Unlocked" "Flying": "Unlocked"
} }
}, }
"DisableNavmesh": true
} }
] ]
}, },

View File

@ -12,7 +12,6 @@
"Y": 0.014982708, "Y": 0.014982708,
"Z": -0.07635498 "Z": -0.07635498
}, },
"StopDistance": 7,
"TerritoryId": 395, "TerritoryId": 395,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }

View File

@ -114,7 +114,8 @@
"Z": 761.01306 "Z": 761.01306
}, },
"TerritoryId": 401, "TerritoryId": 401,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest",
"AetheryteShortcut": "The Sea of Clouds - Camp Cloudtop"
} }
] ]
} }

View File

@ -83,15 +83,6 @@
128 128
] ]
}, },
{
"Position": {
"X": -368.08698,
"Y": -185.05266,
"Z": 792.836
},
"TerritoryId": 401,
"InteractionType": "WalkTo"
},
{ {
"DataId": 1012360, "DataId": 1012360,
"Position": { "Position": {

View File

@ -20,23 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1011952,
"Position": {
"X": -277.63788,
"Y": -184.59735,
"Z": 741.60376
},
"TerritoryId": 401,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "The Sea of Clouds - Camp Cloudtop",
"PickUpQuestId": 1748,
"SkipConditions": {
"AetheryteShortcutIf": {
"InSameTerritory": true
}
}
},
{ {
"DataId": 1001029, "DataId": 1001029,
"Position": { "Position": {

View File

@ -47,7 +47,6 @@
"Y": 16.009666, "Y": 16.009666,
"Z": -9.567444 "Z": -9.567444
}, },
"StopDistance": 7,
"TerritoryId": 419, "TerritoryId": 419,
"InteractionType": "Interact", "InteractionType": "Interact",
"TargetTerritoryId": 433 "TargetTerritoryId": 433
@ -64,7 +63,6 @@
"Y": 0.022254243, "Y": 0.022254243,
"Z": -4.409851 "Z": -4.409851
}, },
"StopDistance": 5,
"TerritoryId": 433, "TerritoryId": 433,
"InteractionType": "CompleteQuest", "InteractionType": "CompleteQuest",
"DialogueChoices": [ "DialogueChoices": [

View File

@ -12,7 +12,6 @@
"Y": 0.022254243, "Y": 0.022254243,
"Z": -4.409851 "Z": -4.409851
}, },
"StopDistance": 5,
"TerritoryId": 433, "TerritoryId": 433,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }
@ -28,6 +27,7 @@
"Y": 1.1443481, "Y": 1.1443481,
"Z": 13.199036 "Z": 13.199036
}, },
"StopDistance": 7,
"TerritoryId": 433, "TerritoryId": 433,
"InteractionType": "Interact", "InteractionType": "Interact",
"TargetTerritoryId": 419 "TargetTerritoryId": 419

View File

@ -87,17 +87,6 @@
{ {
"Sequence": 4, "Sequence": 4,
"Steps": [ "Steps": [
{
"DataId": 1011240,
"Position": {
"X": 493.15625,
"Y": 200.2377,
"Z": 663.01965
},
"TerritoryId": 397,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1744
},
{ {
"DataId": 2005536, "DataId": 2005536,
"Position": { "Position": {

View File

@ -20,39 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1011910,
"Position": {
"X": -298.26813,
"Y": 126.67049,
"Z": -1.4191895
},
"TerritoryId": 397,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1759
},
{
"DataId": 1011907,
"Position": {
"X": -288.8686,
"Y": 127.06639,
"Z": 13.199036
},
"TerritoryId": 397,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1760
},
{
"DataId": 1011911,
"Position": {
"X": -279.56055,
"Y": 127.08131,
"Z": 13.595764
},
"TerritoryId": 397,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 2111
},
{ {
"Position": { "Position": {
"X": -365.48965, "X": -365.48965,

View File

@ -20,16 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"Position": {
"X": -826.9342,
"Y": 117.95439,
"Z": -642.92413
},
"TerritoryId": 397,
"InteractionType": "WalkTo",
"Fly": true
},
{ {
"Position": { "Position": {
"X": -850.3646, "X": -850.3646,

View File

@ -35,17 +35,6 @@
{ {
"Sequence": 2, "Sequence": 2,
"Steps": [ "Steps": [
{
"DataId": 1011916,
"Position": {
"X": 470.02356,
"Y": -49.89133,
"Z": 20.370789
},
"TerritoryId": 398,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1771
},
{ {
"Position": { "Position": {
"X": 634.0371, "X": 634.0371,

View File

@ -105,17 +105,6 @@
{ {
"Sequence": 3, "Sequence": 3,
"Steps": [ "Steps": [
{
"DataId": 1011929,
"Position": {
"X": 70.81714,
"Y": -49.2083,
"Z": -141.55798
},
"TerritoryId": 398,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1790
},
{ {
"Position": { "Position": {
"X": 70.535545, "X": 70.535545,

View File

@ -90,52 +90,13 @@
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{ {
"DataId": 1011916,
"Position": { "Position": {
"X": 470.02356, "X": 123.44939,
"Y": -49.89133, "Y": -60.88712,
"Z": 20.370789 "Z": -118.79085
}, },
"TerritoryId": 398, "TerritoryId": 398,
"InteractionType": "AcceptQuest", "InteractionType": "WalkTo"
"PickUpQuestId": 1797,
"AetheryteShortcut": "The Dravanian Forelands - Tailfeather",
"SkipConditions": {
"AetheryteShortcutIf": {
"QuestsCompleted": [
1797
]
}
}
},
{
"DataId": 1011937,
"Position": {
"X": -305.56195,
"Y": 39.04307,
"Z": 22.9953
},
"TerritoryId": 398,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1802,
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine",
"SkipConditions": {
"AetheryteShortcutIf": {
"QuestsCompleted": [
1802
]
}
}
},
{
"Position": {
"X": 22.235865,
"Y": -24.754946,
"Z": -119.65716
},
"TerritoryId": 398,
"InteractionType": "WalkTo",
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine"
}, },
{ {
"DataId": 1014544, "DataId": 1014544,
@ -145,8 +106,7 @@
"Z": -142.50409 "Z": -142.50409
}, },
"TerritoryId": 398, "TerritoryId": 398,
"InteractionType": "CompleteQuest", "InteractionType": "CompleteQuest"
"DisableNavmesh": true
} }
] ]
} }

View File

@ -12,7 +12,7 @@
"Y": -50.325172, "Y": -50.325172,
"Z": -146.95972 "Z": -146.95972
}, },
"StopDistance": 7, "StopDistance": 5,
"TerritoryId": 398, "TerritoryId": 398,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }

View File

@ -12,7 +12,7 @@
"Y": -69.42934, "Y": -69.42934,
"Z": 693.5072 "Z": 693.5072
}, },
"StopDistance": 6.5, "StopDistance": 5,
"TerritoryId": 400, "TerritoryId": 400,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }

View File

@ -31,17 +31,6 @@
"DisableNavmesh": true, "DisableNavmesh": true,
"Mount": true "Mount": true
}, },
{
"DataId": 1012284,
"Position": {
"X": 363.24097,
"Y": -73.25598,
"Z": 678.4314
},
"TerritoryId": 400,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1819
},
{ {
"Position": { "Position": {
"X": 286.46622, "X": 286.46622,

View File

@ -155,7 +155,7 @@
"Y": -69.42934, "Y": -69.42934,
"Z": 693.5072 "Z": 693.5072
}, },
"StopDistance": 7, "StopDistance": 5,
"TerritoryId": 400, "TerritoryId": 400,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest"
} }

View File

@ -12,7 +12,7 @@
"Y": -69.42934, "Y": -69.42934,
"Z": 693.5072 "Z": 693.5072
}, },
"StopDistance": 7, "StopDistance": 5,
"TerritoryId": 400, "TerritoryId": 400,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }

View File

@ -58,25 +58,6 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"DataId": 1012285,
"Position": {
"X": 247.11987,
"Y": -42.33362,
"Z": 565.3314
},
"TerritoryId": 400,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1823,
"AetheryteShortcut": "The Churning Mists - Moghome",
"SkipConditions": {
"AetheryteShortcutIf": {
"QuestsCompleted": [
1823
]
}
}
},
{ {
"DataId": 1013202, "DataId": 1013202,
"Position": { "Position": {

View File

@ -85,7 +85,6 @@
"Y": 123.72873, "Y": 123.72873,
"Z": 210.74231 "Z": 210.74231
}, },
"StopDistance": 7,
"TerritoryId": 400, "TerritoryId": 400,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest"
} }

View File

@ -12,7 +12,6 @@
"Y": 123.72873, "Y": 123.72873,
"Z": 210.74231 "Z": 210.74231
}, },
"StopDistance": 7,
"TerritoryId": 400, "TerritoryId": 400,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }

View File

@ -20,17 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1013434,
"Position": {
"X": 517.9064,
"Y": -1.1917055,
"Z": -354.63495
},
"TerritoryId": 400,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1835
},
{ {
"DataId": 1012720, "DataId": 1012720,
"Position": { "Position": {

View File

@ -12,7 +12,6 @@
"Y": 16.979584, "Y": 16.979584,
"Z": -37.521973 "Z": -37.521973
}, },
"StopDistance": 7,
"TerritoryId": 418, "TerritoryId": 418,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }
@ -59,7 +58,6 @@
"Y": 0, "Y": 0,
"Z": -3.1281738 "Z": -3.1281738
}, },
"StopDistance": 7,
"TerritoryId": 212, "TerritoryId": 212,
"InteractionType": "Interact" "InteractionType": "Interact"
} }

View File

@ -21,25 +21,6 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"DataId": 1013420,
"Position": {
"X": -511.46716,
"Y": 50,
"Z": 347.0968
},
"TerritoryId": 400,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "The Churning Mists - Zenith",
"PickUpQuestId": 1828,
"SkipConditions": {
"AetheryteShortcutIf": {
"QuestsCompleted": [
1828
]
}
}
},
{ {
"DataId": 1013172, "DataId": 1013172,
"Position": { "Position": {
@ -49,6 +30,7 @@
}, },
"TerritoryId": 400, "TerritoryId": 400,
"InteractionType": "CompleteQuest", "InteractionType": "CompleteQuest",
"AetheryteShortcut": "The Churning Mists - Zenith",
"Fly": true "Fly": true
} }
] ]

View File

@ -21,18 +21,6 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"DataId": 1014720,
"Position": {
"X": 13.809326,
"Y": 15.96505,
"Z": -13.870483
},
"StopDistance": 7,
"TerritoryId": 419,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1874
},
{ {
"DataId": 1011223, "DataId": 1011223,
"Position": { "Position": {
@ -49,9 +37,8 @@
"Yes": true "Yes": true
} }
], ],
"AetheryteShortcut": "Ishgard",
"AethernetShortcut": [ "AethernetShortcut": [
"[Ishgard] Aetheryte Plaza", "[Ishgard] The Last Vigil",
"[Ishgard] The Forgotten Knight" "[Ishgard] The Forgotten Knight"
] ]
}, },

View File

@ -38,7 +38,7 @@
"Z": 113.54166 "Z": 113.54166
}, },
"TerritoryId": 401, "TerritoryId": 401,
"InteractionType": "Emote", "InteractionType": "SinglePlayerDuty",
"Emote": "lookout", "Emote": "lookout",
"StopDistance": 0.25 "StopDistance": 0.25
} }
@ -54,9 +54,10 @@
"Z": 77.39858 "Z": 77.39858
}, },
"TerritoryId": 401, "TerritoryId": 401,
"InteractionType": "SinglePlayerDuty", "InteractionType": "Emote",
"Emote": "lookout", "Emote": "lookout",
"StopDistance": 0.25 "StopDistance": 0.25,
"Comment": "Solo Duty triggered by emoting?"
} }
] ]
}, },

View File

@ -20,17 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1012069,
"Position": {
"X": -647.0283,
"Y": -51.05719,
"Z": -417.74628
},
"TerritoryId": 401,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1909
},
{ {
"DataId": 1012064, "DataId": 1012064,
"Position": { "Position": {
@ -46,17 +35,6 @@
{ {
"Sequence": 2, "Sequence": 2,
"Steps": [ "Steps": [
{
"DataId": 1012068,
"Position": {
"X": -597.0398,
"Y": -51.05185,
"Z": -387.0451
},
"TerritoryId": 401,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1910
},
{ {
"DataId": 2006231, "DataId": 2006231,
"Position": { "Position": {
@ -90,7 +68,6 @@
"Y": -14.730623, "Y": -14.730623,
"Z": -537.56006 "Z": -537.56006
}, },
"StopDistance": 7,
"TerritoryId": 401, "TerritoryId": 401,
"InteractionType": "Interact", "InteractionType": "Interact",
"DialogueChoices": [ "DialogueChoices": [
@ -123,7 +100,7 @@
"Y": -14.153766, "Y": -14.153766,
"Z": -543.0228 "Z": -543.0228
}, },
"StopDistance": 7, "StopDistance": 5,
"TerritoryId": 401, "TerritoryId": 401,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest"
} }

View File

@ -12,7 +12,7 @@
"Y": -14.153766, "Y": -14.153766,
"Z": -543.0228 "Z": -543.0228
}, },
"StopDistance": 7, "StopDistance": 5,
"TerritoryId": 401, "TerritoryId": 401,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest"
} }

View File

@ -21,15 +21,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"Position": {
"X": 43.620056,
"Y": -7.9655867,
"Z": 103.63884
},
"TerritoryId": 132,
"InteractionType": "WalkTo"
},
{ {
"DataId": 1000691, "DataId": 1000691,
"Position": { "Position": {

View File

@ -45,8 +45,7 @@
}, },
"TerritoryId": 398, "TerritoryId": 398,
"InteractionType": "CompleteQuest", "InteractionType": "CompleteQuest",
"AetheryteShortcut": "The Dravanian Forelands - Tailfeather", "AetheryteShortcut": "The Dravanian Forelands - Tailfeather"
"Fly": true
} }
] ]
} }

View File

@ -27,7 +27,6 @@
"Y": 205.62819, "Y": 205.62819,
"Z": 26.901611 "Z": 26.901611
}, },
"StopDistance": 7,
"TerritoryId": 478, "TerritoryId": 478,
"InteractionType": "Interact" "InteractionType": "Interact"
} }
@ -48,15 +47,7 @@
"$": "0 0 0 0 0 0 -> 1 0 0 0 0 64", "$": "0 0 0 0 0 0 -> 1 0 0 0 0 64",
"ChatMessage": { "ChatMessage": {
"Key": "TEXT_HEAVNA607_01656_SAYTODO_000" "Key": "TEXT_HEAVNA607_01656_SAYTODO_000"
}, }
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}, },
{ {
"DataId": 1012413, "DataId": 1012413,
@ -69,15 +60,7 @@
"InteractionType": "Say", "InteractionType": "Say",
"ChatMessage": { "ChatMessage": {
"Key": "TEXT_HEAVNA607_01656_SAYTODO_000" "Key": "TEXT_HEAVNA607_01656_SAYTODO_000"
}, }
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
} }
] ]
}, },

View File

@ -20,21 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1012287,
"Position": {
"X": -28.397034,
"Y": 100.969696,
"Z": -186.4195
},
"TerritoryId": 399,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1936,
"AethernetShortcut": [
"[Idyllshire] Aetheryte Plaza",
"[Idyllshire] Epilogue Gate (Eastern Hinterlands)"
]
},
{ {
"DataId": 1012416, "DataId": 1012416,
"Position": { "Position": {

View File

@ -20,17 +20,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1012102,
"Position": {
"X": 72.40405,
"Y": 205.6815,
"Z": 31.631958
},
"TerritoryId": 478,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1945
},
{ {
"DataId": 1012419, "DataId": 1012419,
"Position": { "Position": {

View File

@ -21,17 +21,6 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1012133,
"Position": {
"X": -26.840637,
"Y": 206.49944,
"Z": 28.67163
},
"TerritoryId": 478,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1963
},
{ {
"Position": { "Position": {
"X": 71.86769, "X": 71.86769,
@ -40,15 +29,18 @@
}, },
"TerritoryId": 478, "TerritoryId": 478,
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"TargetTerritoryId": 399, "TargetTerritoryId": 399
"SkipConditions": {
"StepIf": {
"InTerritory": [
399
]
}
}, },
"$": "Skipped if already in the Hinterlands, since 'Taking Stock' already leaves you closer to the entrance to Matoya's cave" {
"DataId": 2006210,
"Position": {
"X": -487.48004,
"Y": 144.64026,
"Z": -285.359
},
"TerritoryId": 399,
"InteractionType": "AttuneAetherCurrent",
"AetherCurrentId": 2818088
}, },
{ {
"DataId": 2006214, "DataId": 2006214,

View File

@ -44,7 +44,7 @@
"Y": 38.43, "Y": 38.43,
"Z": 3.5552979 "Z": 3.5552979
}, },
"StopDistance": 6, "StopDistance": 7,
"TerritoryId": 463, "TerritoryId": 463,
"InteractionType": "Interact" "InteractionType": "Interact"
} }
@ -53,17 +53,6 @@
{ {
"Sequence": 3, "Sequence": 3,
"Steps": [ "Steps": [
{
"DataId": 1012141,
"Position": {
"X": 35.690796,
"Y": 38.43,
"Z": 12.985352
},
"TerritoryId": 463,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 1966
},
{ {
"DataId": 2005337, "DataId": 2005337,
"Position": { "Position": {
@ -125,8 +114,7 @@
}, },
"TerritoryId": 399, "TerritoryId": 399,
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"DisableNavmesh": true, "DisableNavmesh": true
"Mount": true
}, },
{ {
"DataId": 2005336, "DataId": 2005336,

View File

@ -28,7 +28,6 @@
"Y": -14.52896, "Y": -14.52896,
"Z": 41.153564 "Z": 41.153564
}, },
"StopDistance": 7,
"TerritoryId": 419, "TerritoryId": 419,
"InteractionType": "Interact" "InteractionType": "Interact"
} }

View File

@ -61,8 +61,7 @@
"Z": -659.2356 "Z": -659.2356
}, },
"TerritoryId": 402, "TerritoryId": 402,
"InteractionType": "Interact", "InteractionType": "Interact"
"DisableNavmesh": true
} }
] ]
}, },

View File

@ -35,15 +35,6 @@
{ {
"Sequence": 2, "Sequence": 2,
"Steps": [ "Steps": [
{
"Position": {
"X": 642.1002,
"Y": -32.964188,
"Z": -532.8383
},
"TerritoryId": 402,
"InteractionType": "WalkTo"
},
{ {
"DataId": 2005568, "DataId": 2005568,
"Position": { "Position": {

View File

@ -49,7 +49,8 @@
}, },
"StopDistance": 0.5, "StopDistance": 0.5,
"TerritoryId": 612, "TerritoryId": 612,
"InteractionType": "Combat", "InteractionType": "Instruction",
"Comment": "Manual combat",
"EnemySpawnType": "AutoOnEnterArea", "EnemySpawnType": "AutoOnEnterArea",
"KillEnemyDataIds": [ "KillEnemyDataIds": [
7504 7504
@ -68,7 +69,8 @@
}, },
"StopDistance": 2, "StopDistance": 2,
"TerritoryId": 612, "TerritoryId": 612,
"InteractionType": "Combat", "InteractionType": "Instruction",
"Comment": "Manual combat",
"EnemySpawnType": "AutoOnEnterArea", "EnemySpawnType": "AutoOnEnterArea",
"KillEnemyDataIds": [ "KillEnemyDataIds": [
7505 7505

View File

@ -587,7 +587,6 @@
"AutoOnEnterArea", "AutoOnEnterArea",
"AfterInteraction", "AfterInteraction",
"AfterItemUse", "AfterItemUse",
"AfterAction",
"OverworldEnemies" "OverworldEnemies"
] ]
}, },
@ -858,12 +857,16 @@
"description": "The action to use", "description": "The action to use",
"enum": [ "enum": [
"Heavy Swing", "Heavy Swing",
"Bootshine",
"Twin Snakes",
"Demolish",
"Dragon Kick",
"Heavy Shot", "Heavy Shot",
"Cure", "Cure",
"Cure II", "Cure II",
"Esuna", "Esuna",
"Physick", "Physick",
"Aspected Benefic", "Form Shift",
"Buffet (Sanuwa)", "Buffet (Sanuwa)",
"Buffet (Griffin)", "Buffet (Griffin)",
"Fumigate", "Fumigate",

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using Questionable.Model.Common.Converter; using Questionable.Model.Common.Converter;
namespace Questionable.Model.Questing.Converter; namespace Questionable.Model.Questing.Converter;
@ -8,12 +9,16 @@ public sealed class ActionConverter() : EnumConverter<EAction>(Values)
private static readonly Dictionary<EAction, string> Values = new() private static readonly Dictionary<EAction, string> Values = new()
{ {
{ EAction.HeavySwing, "Heavy Swing" }, { EAction.HeavySwing, "Heavy Swing" },
{ EAction.Bootshine, "Bootshine" },
{ EAction.TwinSnakes, "Twin Snakes" },
{ EAction.Demolish, "Demolish" },
{ EAction.DragonKick, "Dragon Kick" },
{ EAction.HeavyShot, "Heavy Shot" }, { EAction.HeavyShot, "Heavy Shot" },
{ EAction.Cure, "Cure" }, { EAction.Cure, "Cure" },
{ EAction.Cure2, "Cure II" }, { EAction.Cure2, "Cure II" },
{ EAction.Esuna, "Esuna" }, { EAction.Esuna, "Esuna" },
{ EAction.Physick, "Physick" }, { EAction.Physick, "Physick" },
{ EAction.AspectedBenefic, "Aspected Benefic" }, { EAction.FormShift, "Form Shift" },
{ EAction.BuffetSanuwa, "Buffet (Sanuwa)" }, { EAction.BuffetSanuwa, "Buffet (Sanuwa)" },
{ EAction.BuffetGriffin, "Buffet (Griffin)" }, { EAction.BuffetGriffin, "Buffet (Griffin)" },
{ EAction.Fumigate, "Fumigate" }, { EAction.Fumigate, "Fumigate" },

View File

@ -9,7 +9,6 @@ public sealed class EnemySpawnTypeConverter() : EnumConverter<EEnemySpawnType>(V
{ {
{ EEnemySpawnType.AfterInteraction, "AfterInteraction" }, { EEnemySpawnType.AfterInteraction, "AfterInteraction" },
{ EEnemySpawnType.AfterItemUse, "AfterItemUse" }, { EEnemySpawnType.AfterItemUse, "AfterItemUse" },
{ EEnemySpawnType.AfterAction, "AfterAction" },
{ EEnemySpawnType.AutoOnEnterArea, "AutoOnEnterArea" }, { EEnemySpawnType.AutoOnEnterArea, "AutoOnEnterArea" },
{ EEnemySpawnType.OverworldEnemies, "OverworldEnemies" }, { EEnemySpawnType.OverworldEnemies, "OverworldEnemies" },
}; };

View File

@ -7,17 +7,19 @@ namespace Questionable.Model.Questing;
public enum EAction public enum EAction
{ {
HeavySwing = 31, HeavySwing = 31,
Bootshine = 53,
TwinSnakes = 61,
Demolish = 66,
DragonKick = 74,
HeavyShot = 97, HeavyShot = 97,
Cure = 120, Cure = 120,
Cure2 = 135, Cure2 = 135,
Esuna = 7568, Esuna = 7568,
Physick = 190, Physick = 190,
AspectedBenefic = 3595, FormShift = 4262,
BuffetSanuwa = 4931, BuffetSanuwa = 4931,
BuffetGriffin = 4583, BuffetGriffin = 4583,
Fumigate = 5872, Fumigate = 5872,
MagitekPulse = 8624,
MagitekThunder = 8625,
SiphonSnout = 18187, SiphonSnout = 18187,
Cannonfire = 20121, Cannonfire = 20121,
RedGulal = 29382, RedGulal = 29382,

View File

@ -9,7 +9,6 @@ public enum EEnemySpawnType
None = 0, None = 0,
AfterInteraction, AfterInteraction,
AfterItemUse, AfterItemUse,
AfterAction,
AutoOnEnterArea, AutoOnEnterArea,
OverworldEnemies, OverworldEnemies,
} }

View File

@ -191,9 +191,6 @@ internal sealed class CombatController : IDisposable
{ {
if (gameObject is IBattleNpc battleNpc) if (gameObject is IBattleNpc battleNpc)
{ {
if (_currentFight != null && !_currentFight.Module.CanAttack(battleNpc))
return 0;
// TODO this works as somewhat of a delay between killing enemies if certain items/flags are checked // TODO this works as somewhat of a delay between killing enemies if certain items/flags are checked
// but also delays killing the next enemy a little // but also delays killing the next enemy a little
if (_currentFight == null || _currentFight.Data.SpawnType != EEnemySpawnType.OverworldEnemies || if (_currentFight == null || _currentFight.Data.SpawnType != EEnemySpawnType.OverworldEnemies ||

View File

@ -13,6 +13,4 @@ internal interface ICombatModule
void Update(IGameObject nextTarget); void Update(IGameObject nextTarget);
void MoveToTarget(IGameObject nextTarget); void MoveToTarget(IGameObject nextTarget);
bool CanAttack(IBattleNpc target);
} }

View File

@ -1,51 +0,0 @@
using System;
using System.Numerics;
using Dalamud.Game.ClientState.Objects.Types;
using Questionable.Functions;
using Questionable.Model;
using Questionable.Model.Questing;
namespace Questionable.Controller.CombatModules;
/// <summary>
/// Commandeered Magitek Armor; used in 'Magiteknical Failure' quest.
/// </summary>
internal sealed class Mount128Module : ICombatModule
{
public const ushort MountId = 128;
private readonly EAction[] _actions = [EAction.MagitekThunder, EAction.MagitekPulse];
private readonly MovementController _movementController;
private readonly GameFunctions _gameFunctions;
public Mount128Module(MovementController movementController, GameFunctions gameFunctions)
{
_movementController = movementController;
_gameFunctions = gameFunctions;
}
public bool IsLoaded => _gameFunctions.GetMountId() == MountId;
public bool Start() => true;
public bool Stop() => true;
public void Update(IGameObject gameObject)
{
if (_movementController.IsPathfinding || _movementController.IsPathRunning)
return;
foreach (EAction action in _actions)
{
if (_gameFunctions.UseAction(gameObject, action, checkCanUse: false))
return;
}
}
public void MoveToTarget(IGameObject gameObject)
{
}
public bool CanAttack(IBattleNpc target) => target.DataId is 7504 or 7505;
}

View File

@ -85,7 +85,7 @@ internal sealed class RotationSolverRebornModule : ICombatModule, IDisposable
float hitboxOffset = player.HitboxRadius + gameObject.HitboxRadius; float hitboxOffset = player.HitboxRadius + gameObject.HitboxRadius;
float actualDistance = Vector3.Distance(player.Position, gameObject.Position); float actualDistance = Vector3.Distance(player.Position, gameObject.Position);
float maxDistance = player.ClassJob.GameData?.Role is 3 or 4 ? 20f : 2.9f; float maxDistance = player.ClassJob.GameData?.Role is 3 or 4 ? 20f : 3f;
if (actualDistance - hitboxOffset >= maxDistance) if (actualDistance - hitboxOffset >= maxDistance)
{ {
if (actualDistance - hitboxOffset <= 5) if (actualDistance - hitboxOffset <= 5)
@ -119,8 +119,6 @@ internal sealed class RotationSolverRebornModule : ICombatModule, IDisposable
} }
} }
public bool CanAttack(IBattleNpc target) => true;
public void Dispose() => Stop(); public void Dispose() => Stop();
[PublicAPI] [PublicAPI]

View File

@ -3,20 +3,16 @@ using System.Linq;
using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets;
using Questionable.Functions; using Questionable.Functions;
using Questionable.Model;
using Questionable.Model.Questing; using Questionable.Model.Questing;
using Questionable.Windows; using Questionable.Windows;
using Questionable.Windows.QuestComponents; using Questionable.Windows.QuestComponents;
using Quest = Questionable.Model.Quest;
namespace Questionable.Controller; namespace Questionable.Controller;
internal sealed class CommandHandler : IDisposable internal sealed class CommandHandler : IDisposable
{ {
private const string MessageTag = "Questionable";
private const ushort TagColor = 576;
private readonly ICommandManager _commandManager; private readonly ICommandManager _commandManager;
private readonly IChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly QuestController _questController; private readonly QuestController _questController;
@ -28,8 +24,6 @@ internal sealed class CommandHandler : IDisposable
private readonly QuestSelectionWindow _questSelectionWindow; private readonly QuestSelectionWindow _questSelectionWindow;
private readonly ITargetManager _targetManager; private readonly ITargetManager _targetManager;
private readonly QuestFunctions _questFunctions; private readonly QuestFunctions _questFunctions;
private readonly GameFunctions _gameFunctions;
private readonly IDataManager _dataManager;
public CommandHandler( public CommandHandler(
ICommandManager commandManager, ICommandManager commandManager,
@ -42,9 +36,7 @@ internal sealed class CommandHandler : IDisposable
QuestWindow questWindow, QuestWindow questWindow,
QuestSelectionWindow questSelectionWindow, QuestSelectionWindow questSelectionWindow,
ITargetManager targetManager, ITargetManager targetManager,
QuestFunctions questFunctions, QuestFunctions questFunctions)
GameFunctions gameFunctions,
IDataManager dataManager)
{ {
_commandManager = commandManager; _commandManager = commandManager;
_chatGui = chatGui; _chatGui = chatGui;
@ -57,8 +49,6 @@ internal sealed class CommandHandler : IDisposable
_questSelectionWindow = questSelectionWindow; _questSelectionWindow = questSelectionWindow;
_targetManager = targetManager; _targetManager = targetManager;
_questFunctions = questFunctions; _questFunctions = questFunctions;
_gameFunctions = gameFunctions;
_dataManager = dataManager;
_commandManager.AddHandler("/qst", new CommandInfo(ProcessCommand) _commandManager.AddHandler("/qst", new CommandInfo(ProcessCommand)
{ {
@ -118,16 +108,12 @@ internal sealed class CommandHandler : IDisposable
_questSelectionWindow.OpenForCurrentZone(); _questSelectionWindow.OpenForCurrentZone();
break; break;
case "mountid":
PrintMountId();
break;
case "": case "":
_questWindow.Toggle(); _questWindow.Toggle();
break; break;
default: default:
_chatGui.PrintError($"Unknown subcommand {parts[0]}", MessageTag, TagColor); _chatGui.PrintError($"Unknown subcommand {parts[0]}", "Questionable");
break; break;
} }
} }
@ -136,7 +122,7 @@ internal sealed class CommandHandler : IDisposable
{ {
if (!_debugOverlay.DrawConditions()) if (!_debugOverlay.DrawConditions())
{ {
_chatGui.PrintError("You don't have the debug overlay enabled.", MessageTag, TagColor); _chatGui.PrintError("[Questionable] You don't have the debug overlay enabled.");
return; return;
} }
@ -145,15 +131,15 @@ internal sealed class CommandHandler : IDisposable
if (_questRegistry.TryGetQuest(questId, out Quest? quest)) if (_questRegistry.TryGetQuest(questId, out Quest? quest))
{ {
_debugOverlay.HighlightedQuest = quest.Id; _debugOverlay.HighlightedQuest = quest.Id;
_chatGui.Print($"Set highlighted quest to {questId} ({quest.Info.Name}).", MessageTag, TagColor); _chatGui.Print($"[Questionable] Set highlighted quest to {questId} ({quest.Info.Name}).");
} }
else else
_chatGui.PrintError($"Unknown quest {questId}.", MessageTag, TagColor); _chatGui.PrintError($"[Questionable] Unknown quest {questId}.");
} }
else else
{ {
_debugOverlay.HighlightedQuest = null; _debugOverlay.HighlightedQuest = null;
_chatGui.Print("Cleared highlighted quest.", MessageTag, TagColor); _chatGui.Print("[Questionable] Cleared highlighted quest.");
} }
} }
@ -162,21 +148,21 @@ internal sealed class CommandHandler : IDisposable
if (arguments.Length >= 1 && ElementId.TryFromString(arguments[0], out ElementId? questId) && questId != null) if (arguments.Length >= 1 && ElementId.TryFromString(arguments[0], out ElementId? questId) && questId != null)
{ {
if (_questFunctions.IsQuestLocked(questId)) if (_questFunctions.IsQuestLocked(questId))
_chatGui.PrintError($"Quest {questId} is locked.", MessageTag, TagColor); _chatGui.PrintError($"[Questionable] Quest {questId} is locked.");
else if (_questRegistry.TryGetQuest(questId, out Quest? quest)) else if (_questRegistry.TryGetQuest(questId, out Quest? quest))
{ {
_questController.SetNextQuest(quest); _questController.SetNextQuest(quest);
_chatGui.Print($"Set next quest to {questId} ({quest.Info.Name}).", MessageTag, TagColor); _chatGui.Print($"[Questionable] Set next quest to {questId} ({quest.Info.Name}).");
} }
else else
{ {
_chatGui.PrintError($"Unknown quest {questId}.", MessageTag, TagColor); _chatGui.PrintError($"[Questionable] Unknown quest {questId}.");
} }
} }
else else
{ {
_questController.SetNextQuest(null); _questController.SetNextQuest(null);
_chatGui.Print("Cleared next quest.", MessageTag, TagColor); _chatGui.Print("[Questionable] Cleared next quest.");
} }
} }
@ -187,32 +173,18 @@ internal sealed class CommandHandler : IDisposable
if (_questRegistry.TryGetQuest(questId, out Quest? quest)) if (_questRegistry.TryGetQuest(questId, out Quest? quest))
{ {
_questController.SimulateQuest(quest); _questController.SimulateQuest(quest);
_chatGui.Print($"Simulating quest {questId} ({quest.Info.Name}).", MessageTag, TagColor); _chatGui.Print($"[Questionable] Simulating quest {questId} ({quest.Info.Name}).");
} }
else else
_chatGui.PrintError($"Unknown quest {questId}.", MessageTag, TagColor); _chatGui.PrintError($"[Questionable] Unknown quest {questId}.");
} }
else else
{ {
_questController.SimulateQuest(null); _questController.SimulateQuest(null);
_chatGui.Print("Cleared simulated quest.", MessageTag, TagColor); _chatGui.Print("[Questionable] Cleared simulated quest.");
} }
} }
private void PrintMountId()
{
ushort? mountId = _gameFunctions.GetMountId();
if (mountId != null)
{
var row = _dataManager.GetExcelSheet<Mount>()!.GetRow(mountId.Value);
_chatGui.Print(
$"Mount ID: {mountId}, Name: {row?.Singular}, Obtainable: {(row?.Order == -1 ? "No" : "Yes")}",
MessageTag, TagColor);
}
else
_chatGui.Print("You are not mounted.", MessageTag, TagColor);
}
public void Dispose() public void Dispose()
{ {
_commandManager.RemoveHandler("/qst"); _commandManager.RemoveHandler("/qst");

View File

@ -235,16 +235,6 @@ internal sealed class InteractionUiController : IDisposable
_logger.LogInformation("Checking if current quest {Name} is on the list", currentQuest.Quest.Info.Name); _logger.LogInformation("Checking if current quest {Name} is on the list", currentQuest.Quest.Info.Name);
if (CheckQuestSelection(addonSelectIconString, currentQuest.Quest, answers)) if (CheckQuestSelection(addonSelectIconString, currentQuest.Quest, answers))
return; return;
var sequence = currentQuest.Quest.FindSequence(currentQuest.Sequence);
QuestStep? step = sequence?.FindStep(currentQuest.Step);
if (step is { InteractionType: EInteractionType.AcceptQuest, PickUpQuestId: not null } &&
_questRegistry.TryGetQuest(step.PickUpQuestId, out Quest? pickupQuest))
{
_logger.LogInformation("Checking if current picked-up {Name} is on the list", pickupQuest.Info.Name);
if (CheckQuestSelection(addonSelectIconString, pickupQuest, answers))
return;
}
} }
var nextQuest = _questController.NextQuest; var nextQuest = _questController.NextQuest;

View File

@ -20,10 +20,6 @@ internal static class NextQuest
if (step.NextQuestId == quest.Id) if (step.NextQuestId == quest.Id)
return null; return null;
// probably irrelevant, since pick up is handled elsewhere (and, in particular, checks for aetherytes and stuff)
if (questFunctions.GetPriorityQuests().Contains(step.NextQuestId))
return null;
return new SetQuest(step.NextQuestId, quest.Id, questRegistry, questController, questFunctions, loggerFactory.CreateLogger<SetQuest>()); return new SetQuest(step.NextQuestId, quest.Id, questRegistry, questController, questFunctions, loggerFactory.CreateLogger<SetQuest>());
} }
} }

View File

@ -24,18 +24,13 @@ internal static class Action
ArgumentNullException.ThrowIfNull(step.Action); ArgumentNullException.ThrowIfNull(step.Action);
var task = OnObject(step.DataId, step.Action.Value); var task = new UseOnObject(step.DataId, step.Action.Value, gameFunctions,
loggerFactory.CreateLogger<UseOnObject>());
if (step.Action.Value.RequiresMount()) if (step.Action.Value.RequiresMount())
return [task]; return [task];
else else
return [mountFactory.Unmount(), task]; return [mountFactory.Unmount(), task];
} }
public ITask OnObject(uint? dataId, EAction action)
{
return new UseOnObject(dataId, action, gameFunctions,
loggerFactory.CreateLogger<UseOnObject>());
}
} }
private sealed class UseOnObject( private sealed class UseOnObject(

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Questionable.Controller.CombatModules; using Microsoft.Extensions.DependencyInjection;
using Questionable.Controller.Steps.Common; using Questionable.Controller.Steps.Common;
using Questionable.Controller.Steps.Shared; using Questionable.Controller.Steps.Shared;
using Questionable.Controller.Utils; using Questionable.Controller.Utils;
@ -18,9 +18,7 @@ internal static class Combat
Interact.Factory interactFactory, Interact.Factory interactFactory,
Mount.Factory mountFactory, Mount.Factory mountFactory,
UseItem.Factory useItemFactory, UseItem.Factory useItemFactory,
Action.Factory actionFactory, QuestFunctions questFunctions) : ITaskFactory
QuestFunctions questFunctions,
GameFunctions gameFunctions) : ITaskFactory
{ {
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{ {
@ -29,7 +27,6 @@ internal static class Combat
ArgumentNullException.ThrowIfNull(step.EnemySpawnType); ArgumentNullException.ThrowIfNull(step.EnemySpawnType);
if (gameFunctions.GetMountId() != Mount128Module.MountId)
yield return mountFactory.Unmount(); yield return mountFactory.Unmount();
if (step.CombatDelaySecondsAtStart != null) if (step.CombatDelaySecondsAtStart != null)
@ -61,19 +58,6 @@ internal static class Combat
break; break;
} }
case EEnemySpawnType.AfterAction:
{
ArgumentNullException.ThrowIfNull(step.DataId);
ArgumentNullException.ThrowIfNull(step.Action);
if (!step.Action.Value.RequiresMount())
yield return mountFactory.Unmount();
yield return actionFactory.OnObject(step.DataId.Value, step.Action.Value);
yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(1));
yield return CreateTask(quest, sequence, step);
break;
}
case EEnemySpawnType.AutoOnEnterArea: case EEnemySpawnType.AutoOnEnterArea:
if (step.CombatDelaySecondsAtStart == null) if (step.CombatDelaySecondsAtStart == null)
yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(1)); yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(1));

View File

@ -14,8 +14,7 @@ internal static class Emote
{ {
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType is EInteractionType.AcceptQuest or EInteractionType.CompleteQuest if (step.InteractionType is EInteractionType.AcceptQuest or EInteractionType.CompleteQuest)
or EInteractionType.SinglePlayerDuty)
{ {
if (step.Emote == null) if (step.Emote == null)
return []; return [];

View File

@ -68,7 +68,7 @@ internal static class MoveTo
public ITask Move(MoveParams moveParams) public ITask Move(MoveParams moveParams)
{ {
return new MoveInternal(moveParams, movementController, gameFunctions, return new MoveInternal(moveParams, movementController, gameFunctions,
loggerFactory.CreateLogger<MoveInternal>(), clientState, dataManager); loggerFactory.CreateLogger<MoveInternal>(), condition, clientState, dataManager);
} }
public ITask Land() public ITask Land()
@ -163,22 +163,26 @@ internal static class MoveTo
private readonly string _cannotExecuteAtThisTime; private readonly string _cannotExecuteAtThisTime;
private readonly MovementController _movementController; private readonly MovementController _movementController;
private readonly ILogger<MoveInternal> _logger; private readonly ILogger<MoveInternal> _logger;
private readonly ICondition _condition;
private readonly IClientState _clientState; private readonly IClientState _clientState;
private readonly Action _startAction; private readonly Action _startAction;
private readonly Vector3 _destination; private readonly Vector3 _destination;
private readonly MoveParams _moveParams; private readonly MoveParams _moveParams;
private readonly bool _isUnderwaterInitially;
private bool _canRestart; private bool _canRestart;
public MoveInternal(MoveParams moveParams, public MoveInternal(MoveParams moveParams,
MovementController movementController, MovementController movementController,
GameFunctions gameFunctions, GameFunctions gameFunctions,
ILogger<MoveInternal> logger, ILogger<MoveInternal> logger,
ICondition condition,
IClientState clientState, IClientState clientState,
IDataManager dataManager) IDataManager dataManager)
{ {
_movementController = movementController; _movementController = movementController;
_logger = logger; _logger = logger;
_condition = condition;
_clientState = clientState; _clientState = clientState;
_cannotExecuteAtThisTime = dataManager.GetString<LogMessage>(579, x => x.Text)!; _cannotExecuteAtThisTime = dataManager.GetString<LogMessage>(579, x => x.Text)!;
@ -253,7 +257,8 @@ internal static class MoveTo
public bool OnErrorToast(SeString message) public bool OnErrorToast(SeString message)
{ {
if (GameFunctions.GameStringEquals(_cannotExecuteAtThisTime, message.TextValue)) if (GameFunctions.GameStringEquals(_cannotExecuteAtThisTime, message.TextValue) &&
_condition[ConditionFlag.Diving])
return true; return true;
return false; return false;

View File

@ -1,31 +0,0 @@
using System;
using Dalamud.Plugin;
using Dalamud.Plugin.Ipc;
using Questionable.Controller;
namespace Questionable.External;
internal sealed class QuestionableIpc : IDisposable
{
private const string IpcIsRunning = "Questionable.IsRunning";
private const string IpcGetCurrentQuestId = "Questionable.GetCurrentQuestId";
private readonly ICallGateProvider<bool> _isRunning;
private readonly ICallGateProvider<string?> _getCurrentQuestId;
public QuestionableIpc(QuestController questController, IDalamudPluginInterface pluginInterface)
{
_isRunning = pluginInterface.GetIpcProvider<bool>(IpcIsRunning);
_isRunning.RegisterFunc(() => questController.IsRunning);
_getCurrentQuestId = pluginInterface.GetIpcProvider<string?>(IpcGetCurrentQuestId);
_getCurrentQuestId.RegisterFunc(() => questController.CurrentQuest?.Quest.Id.ToString());
}
public void Dispose()
{
_getCurrentQuestId.UnregisterFunc();
_isRunning.UnregisterFunc();
}
}

View File

@ -81,9 +81,8 @@ internal sealed unsafe class GameFunctions
if (_questFunctions.IsQuestAccepted(new QuestId(3304)) && _condition[ConditionFlag.Mounted]) if (_questFunctions.IsQuestAccepted(new QuestId(3304)) && _condition[ConditionFlag.Mounted])
{ {
// special quest amaro, not the normal one BattleChara* battleChara = (BattleChara*)(_clientState.LocalPlayer?.Address ?? 0);
// TODO Check if this also applies to beast tribe mounts if (battleChara != null && battleChara->Mount.MountId == 198) // special quest amaro, not the normal one
if (GetMountId() == 198)
return true; return true;
} }
@ -93,15 +92,6 @@ internal sealed unsafe class GameFunctions
playerState->IsAetherCurrentZoneComplete(aetherCurrentCompFlgSet); playerState->IsAetherCurrentZoneComplete(aetherCurrentCompFlgSet);
} }
public ushort? GetMountId()
{
BattleChara* battleChara = (BattleChara*)(_clientState.LocalPlayer?.Address ?? 0);
if (battleChara != null && battleChara->Mount.MountId != 0)
return battleChara->Mount.MountId;
else
return null;
}
public bool IsFlyingUnlockedInCurrentZone() => IsFlyingUnlocked(_clientState.TerritoryType); public bool IsFlyingUnlockedInCurrentZone() => IsFlyingUnlocked(_clientState.TerritoryType);
public bool IsAetherCurrentUnlocked(uint aetherCurrentId) public bool IsAetherCurrentUnlocked(uint aetherCurrentId)
@ -220,10 +210,10 @@ internal sealed unsafe class GameFunctions
return false; return false;
} }
public bool UseAction(IGameObject gameObject, EAction action, bool checkCanUse = true) public bool UseAction(IGameObject gameObject, EAction action)
{ {
var actionRow = _dataManager.GetExcelSheet<Action>()!.GetRow((uint)action)!; var actionRow = _dataManager.GetExcelSheet<Action>()!.GetRow((uint)action)!;
if (checkCanUse && !ActionManager.CanUseActionOnTarget((uint)action, (GameObject*)gameObject.Address)) if (!ActionManager.CanUseActionOnTarget((uint)action, (GameObject*)gameObject.Address))
{ {
_logger.LogWarning("Can not use action {Action} on target {Target}", action, gameObject); _logger.LogWarning("Can not use action {Action} on target {Target}", action, gameObject);
return false; return false;

View File

@ -254,8 +254,7 @@ internal sealed unsafe class QuestFunctions
InventoryManager* inventoryManager = InventoryManager.Instance(); InventoryManager* inventoryManager = InventoryManager.Instance();
int gil = inventoryManager->GetItemCountInContainer(1, InventoryType.Currency); int gil = inventoryManager->GetItemCountInContainer(1, InventoryType.Currency);
return GetPriorityQuests() return GetPriorityQuestsThatCanBeAccepted()
.Where(IsReadyToAcceptQuest)
.Where(x => .Where(x =>
{ {
if (!_questRegistry.TryGetQuest(x, out Quest? quest)) if (!_questRegistry.TryGetQuest(x, out Quest? quest))
@ -312,7 +311,7 @@ internal sealed unsafe class QuestFunctions
return 1000 * quest.AllSteps().Count(x => x.Step.AetheryteShortcut != null); return 1000 * quest.AllSteps().Count(x => x.Step.AetheryteShortcut != null);
} }
public List<ElementId> GetPriorityQuests() private List<ElementId> GetPriorityQuestsThatCanBeAccepted()
{ {
List<ElementId> priorityQuests = List<ElementId> priorityQuests =
[ [
@ -350,6 +349,7 @@ internal sealed unsafe class QuestFunctions
return priorityQuests return priorityQuests
.Where(_questRegistry.IsKnownQuest) .Where(_questRegistry.IsKnownQuest)
.Where(IsReadyToAcceptQuest)
.ToList(); .ToList();
} }

View File

@ -120,7 +120,6 @@ public sealed class QuestionablePlugin : IDalamudPlugin
serviceCollection.AddSingleton<LifestreamIpc>(); serviceCollection.AddSingleton<LifestreamIpc>();
serviceCollection.AddSingleton<YesAlreadyIpc>(); serviceCollection.AddSingleton<YesAlreadyIpc>();
serviceCollection.AddSingleton<ArtisanIpc>(); serviceCollection.AddSingleton<ArtisanIpc>();
serviceCollection.AddSingleton<QuestionableIpc>();
} }
private static void AddTaskFactories(ServiceCollection serviceCollection) private static void AddTaskFactories(ServiceCollection serviceCollection)
@ -185,7 +184,6 @@ public sealed class QuestionablePlugin : IDalamudPlugin
serviceCollection.AddSingleton<InteractionUiController>(); serviceCollection.AddSingleton<InteractionUiController>();
serviceCollection.AddSingleton<LeveUiController>(); serviceCollection.AddSingleton<LeveUiController>();
serviceCollection.AddSingleton<ICombatModule, Mount128Module>();
serviceCollection.AddSingleton<ICombatModule, RotationSolverRebornModule>(); serviceCollection.AddSingleton<ICombatModule, RotationSolverRebornModule>();
} }
@ -237,7 +235,6 @@ public sealed class QuestionablePlugin : IDalamudPlugin
serviceProvider.GetRequiredService<CreditsController>(); serviceProvider.GetRequiredService<CreditsController>();
serviceProvider.GetRequiredService<HelpUiController>(); serviceProvider.GetRequiredService<HelpUiController>();
serviceProvider.GetRequiredService<LeveUiController>(); serviceProvider.GetRequiredService<LeveUiController>();
serviceProvider.GetRequiredService<QuestionableIpc>();
serviceProvider.GetRequiredService<DalamudInitializer>(); serviceProvider.GetRequiredService<DalamudInitializer>();
} }

View File

@ -177,7 +177,7 @@ internal sealed partial class ActiveQuestComponent
{ {
using var _ = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudYellow); using var _ = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
ImGui.TextUnformatted( ImGui.TextUnformatted(
$"Next Quest: {Shorten(nextQuest.Quest.Info.Name)} / {nextQuest.Sequence} / {nextQuest.Step}"); $"Next Quest: {Shorten(currentQuest.Quest.Info.Name)} / {currentQuest.Sequence} / {currentQuest.Step}");
} }
} }
} }