Limsa navmesh adjustments; add more role quests

This commit is contained in:
Liza 2024-07-12 10:31:34 +02:00
parent 8c49c0b273
commit ef34c5b4f1
Signed by: liza
GPG Key ID: 7199F8D727D55F67
23 changed files with 1293 additions and 37 deletions

View File

@ -13,7 +13,166 @@
"Z": 198.68762 "Z": 198.68762
}, },
"TerritoryId": 1185, "TerritoryId": 1185,
"InteractionType": "AcceptQuest" "InteractionType": "AcceptQuest",
"AetheryteShortcut": "Tuliyollal",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
]
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1019038,
"Position": {
"X": -55.222473,
"Y": -2.9000003,
"Z": -65.65961
},
"TerritoryId": 628,
"InteractionType": "Interact",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] Shiokaze Hostelry"
],
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 1019003,
"Position": {
"X": -41.24518,
"Y": -3.0000017,
"Z": -63.09613
},
"TerritoryId": 628,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 1019069,
"Position": {
"X": -62.119568,
"Y": 8,
"Z": -56.62628
},
"TerritoryId": 628,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1051620,
"Position": {
"X": 111.40613,
"Y": 11.997255,
"Z": -52.048523
},
"TerritoryId": 628,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1048296,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 4,
"Steps": [
{
"DataId": 2013689,
"Position": {
"X": 29.251465,
"Y": 5.935669,
"Z": -129.62543
},
"TerritoryId": 628,
"InteractionType": "Interact",
"AethernetShortcut": [
"[Kugane] Sekiseigumi Barracks",
"[Kugane] Rakuza District"
]
}
]
},
{
"Sequence": 5,
"Steps": [
{
"DataId": 2013690,
"Position": {
"X": 14.114502,
"Y": 3.982544,
"Z": 43.411865
},
"TerritoryId": 628,
"InteractionType": "Interact",
"AethernetShortcut": [
"[Kugane] Rakuza District",
"[Kugane] Kogane Dori Markets"
]
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048296,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "CompleteQuest",
"AethernetShortcut": [
"[Kugane] Kogane Dori Markets",
"[Kugane] Sekiseigumi Barracks"
],
"NextQuestId": 4831
} }
] ]
} }

View File

@ -0,0 +1,153 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1048296,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "Kugane",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
],
"DialogueChoices": [
{
"Type": "List",
"Prompt": "TEXT_KINGBA311_04831_Q2_000_000",
"Answer": "TEXT_KINGBA311_04831_A2_000_002"
}
]
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1019154,
"Position": {
"X": 829.1294,
"Y": 5.9230084,
"Z": 859.739
},
"TerritoryId": 613,
"InteractionType": "Interact",
"AethernetShortcut": [
"[Kugane] Sekiseigumi Barracks",
"[Kugane] The Ruby Price"
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1019169,
"Position": {
"X": 476.82898,
"Y": 30.113333,
"Z": 763.546
},
"TerritoryId": 613,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 1019167,
"Position": {
"X": 447.56226,
"Y": 34.29651,
"Z": 732.66187
},
"TerritoryId": 613,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1048299,
"Position": {
"X": 463.46216,
"Y": 29.787891,
"Z": 736.8428
},
"TerritoryId": 613,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 4,
"Steps": [
{
"Position": {
"X": 426.16245,
"Y": 0.7213422,
"Z": 195.08597
},
"TerritoryId": 613,
"InteractionType": "WalkTo",
"Fly": true
},
{
"DataId": 1048301,
"Position": {
"X": 427.78674,
"Y": 0.5689501,
"Z": 195.39172
},
"TerritoryId": 613,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048296,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] Sekiseigumi Barracks"
],
"NextQuestId": 4832
}
]
}
]
}

View File

@ -0,0 +1,142 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1048296,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "Kugane",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
]
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1019260,
"Position": {
"X": 417.5935,
"Y": 68.02854,
"Z": -110.24652
},
"TerritoryId": 614,
"InteractionType": "Interact",
"AetheryteShortcut": "Yanxia - Namai",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 1019257,
"Position": {
"X": 468.55872,
"Y": 68.02771,
"Z": -93.21747
},
"TerritoryId": 614,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 1019262,
"Position": {
"X": 445.76172,
"Y": 58.67623,
"Z": -155.62683
},
"TerritoryId": 614,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1048302,
"Position": {
"X": 399.95422,
"Y": 76.04927,
"Z": -114.885254
},
"StopDistance": 0.5,
"TerritoryId": 614,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1048304,
"Position": {
"X": 421.3473,
"Y": 1.7278045,
"Z": -278.70605
},
"TerritoryId": 614,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048296,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] Sekiseigumi Barracks"
],
"NextQuestId": 4833
}
]
}
]
}

View File

@ -0,0 +1,104 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1048297,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "Kugane",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
]
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 2013691,
"Position": {
"X": 203.8147,
"Y": 12.069824,
"Z": 773.0067
},
"TerritoryId": 613,
"InteractionType": "Interact",
"AethernetShortcut": [
"[Kugane] Sekiseigumi Barracks",
"[Kugane] The Ruby Price"
],
"Fly": true
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 2013692,
"Position": {
"X": 138.59766,
"Y": 9.292725,
"Z": 676.6002
},
"TerritoryId": 613,
"InteractionType": "Combat",
"EnemySpawnType": "AfterInteraction",
"KillEnemyDataIds": [
17617,
17618,
17619
],
"Fly": true
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 2013693,
"Position": {
"X": 167.89502,
"Y": 2.1209717,
"Z": 561.27246
},
"TerritoryId": 613,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048297,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] Sekiseigumi Barracks"
],
"NextQuestId": 4834
}
]
}
]
}

View File

@ -0,0 +1,144 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1048297,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "Kugane",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
]
}
]
},
{
"Sequence": 1,
"Steps": [
{
"Position": {
"X": 42.052795,
"Y": 4.000001,
"Z": 71.14965
},
"TerritoryId": 628,
"InteractionType": "WalkTo",
"AethernetShortcut": [
"[Kugane] Sekiseigumi Barracks",
"[Kugane] Kogane Dori Markets"
]
},
{
"DataId": 1018984,
"Position": {
"X": 42.34375,
"Y": 4.8365364,
"Z": 73.83838
},
"TerritoryId": 628,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1019065,
"Position": {
"X": 80.49133,
"Y": 4,
"Z": 56.443115
},
"TerritoryId": 628,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 2013694,
"Position": {
"X": 517.2654,
"Y": 0.99176025,
"Z": -692.10345
},
"TerritoryId": 613,
"InteractionType": "UseItem",
"ItemId": 2003492,
"AetheryteShortcut": "Ruby Sea - Onokoro",
"Fly": true
}
]
},
{
"Sequence": 4,
"Steps": [
{
"DataId": 2013695,
"Position": {
"X": 519.76794,
"Y": 0.99176025,
"Z": -679.8352
},
"TerritoryId": 613,
"InteractionType": "Combat",
"EnemySpawnType": "AfterInteraction",
"KillEnemyDataIds": [
17620
]
}
]
},
{
"Sequence": 5,
"Steps": [
{
"DataId": 1019065,
"Position": {
"X": 80.49133,
"Y": 4,
"Z": 56.443115
},
"TerritoryId": 628,
"InteractionType": "Interact",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] Kogane Dori Markets"
],
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
]
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048298,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "CompleteQuest",
"NextQuestId": 4835
}
]
}
]
}

View File

@ -0,0 +1,169 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1048298,
"Position": {
"X": 111.40613,
"Y": 11.997235,
"Z": -52.018066
},
"TerritoryId": 628,
"InteractionType": "AcceptQuest",
"AetheryteShortcut": "Kugane",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
]
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1019350,
"Position": {
"X": 563.2562,
"Y": -19.505632,
"Z": 319.11182
},
"TerritoryId": 622,
"InteractionType": "Interact",
"AetheryteShortcut": "Azim Steppe - Reunion",
"SkipIf": [
"AetheryteShortcutIfInSameTerritory"
],
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 1019351,
"Position": {
"X": 548.8822,
"Y": -19.505648,
"Z": 295.1858
},
"TerritoryId": 622,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 1019353,
"Position": {
"X": 544.0298,
"Y": -19.505642,
"Z": 391.68372
},
"TerritoryId": 622,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1048305,
"Position": {
"X": 591.08875,
"Y": -19.505634,
"Z": 296.9253
},
"TerritoryId": 622,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1048305,
"Position": {
"X": 591.08875,
"Y": -19.505634,
"Z": 296.9253
},
"TerritoryId": 622,
"InteractionType": "SinglePlayerDuty"
}
]
},
{
"Sequence": 4,
"Steps": [
{
"Position": {
"X": 0,
"Y": 0,
"Z": 0
},
"TerritoryId": 1,
"InteractionType": "WalkTo",
"Comment": "Filler"
}
]
},
{
"Sequence": 5,
"Steps": [
{
"DataId": 1048307,
"Position": {
"X": -494.56018,
"Y": 71.630486,
"Z": -518.9441
},
"TerritoryId": 622,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048295,
"Position": {
"X": -74.143616,
"Y": -19.32829,
"Z": 198.68762
},
"TerritoryId": 1185,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Tuliyollal",
"AethernetShortcut": [
"[Tuliyollal] Aetheryte Plaza",
"[Tuliyollal] Bayside Bevy Marketplace"
]
}
]
}
]
}

View File

@ -0,0 +1,113 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1048650,
"Position": {
"X": 367.87964,
"Y": -156.28014,
"Z": -419.11957
},
"TerritoryId": 1187,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 2014104,
"Position": {
"X": 374.77686,
"Y": -154.07043,
"Z": -373.52563
},
"TerritoryId": 1187,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
},
{
"DataId": 2014106,
"Position": {
"X": 327.90112,
"Y": -152.20874,
"Z": -369.31415
},
"TerritoryId": 1187,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
32
]
},
{
"DataId": 2014105,
"Position": {
"X": 330.6172,
"Y": -158.06824,
"Z": -399.8932
},
"TerritoryId": 1187,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 2014107,
"Position": {
"X": 275.7152,
"Y": -166.94897,
"Z": -462.7909
},
"TerritoryId": 1187,
"InteractionType": "Interact",
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
16
]
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048650,
"Position": {
"X": 367.87964,
"Y": -156.28014,
"Z": -419.11957
},
"TerritoryId": 1187,
"InteractionType": "CompleteQuest"
}
]
}
]
}

View File

@ -0,0 +1,82 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1048649,
"Position": {
"X": 357.86987,
"Y": -155.91757,
"Z": -370.1076
},
"TerritoryId": 1187,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1050671,
"Position": {
"X": 191.97375,
"Y": -87.10133,
"Z": -277.39374
},
"TerritoryId": 1187,
"InteractionType": "UseItem",
"ItemId": 2003601,
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
64
]
},
{
"DataId": 1050670,
"Position": {
"X": 132.86023,
"Y": -75.24902,
"Z": -213.2143
},
"TerritoryId": 1187,
"InteractionType": "UseItem",
"ItemId": 2003601,
"Fly": true,
"CompletionQuestVariablesFlags": [
null,
null,
null,
null,
null,
128
]
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1048649,
"Position": {
"X": 357.86987,
"Y": -155.91757,
"Z": -370.1076
},
"TerritoryId": 1187,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Urqopacha - Wachunpelo"
}
]
}
]
}

View File

@ -0,0 +1,116 @@
{
"$schema": "https://carvel.li/questionable/quest-1.0",
"Author": "liza",
"TerritoryBlacklist": [
1204
],
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1051440,
"Position": {
"X": 305.01257,
"Y": 51.199978,
"Z": 198.07727
},
"TerritoryId": 1186,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 2014334,
"Position": {
"X": -6.9123535,
"Y": 53.177612,
"Z": 761.68445
},
"TerritoryId": 1192,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1048243,
"Position": {
"X": 57.87744,
"Y": 53.200012,
"Z": 772.03015
},
"TerritoryId": 1192,
"InteractionType": "Interact",
"TargetTerritoryId": 1192,
"SkipIf": [
"FlyingUnlocked"
]
},
{
"DataId": 1051443,
"Position": {
"X": 614.28235,
"Y": 9.022843,
"Z": 610.13184
},
"TerritoryId": 1192,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 3,
"Steps": [
{
"TerritoryId": 1192,
"InteractionType": "Duty",
"ContentFinderConditionId": 981
}
]
},
{
"Sequence": 4,
"Steps": [
{
"DataId": 1051442,
"Position": {
"X": 613.76355,
"Y": 9.022844,
"Z": 612.1156
},
"StopDistance": 7,
"TerritoryId": 1192,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 255,
"Steps": [
{
"DataId": 1051440,
"Position": {
"X": 305.01257,
"Y": 51.199978,
"Z": 198.07727
},
"TerritoryId": 1186,
"InteractionType": "CompleteQuest",
"AetheryteShortcut": "Solution Nine",
"AethernetShortcut": [
"[Solution Nine] Aetheryte Plaza",
"[Solution Nine] Neon Stein"
]
}
]
}
]
}

View File

@ -14,6 +14,7 @@ using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Control; using FFXIVClientStructs.FFXIV.Client.Game.Control;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Questionable.Controller.NavigationOverrides;
using Questionable.External; using Questionable.External;
using Questionable.Model; using Questionable.Model;
using Questionable.Model.V1; using Questionable.Model.V1;
@ -23,28 +24,26 @@ namespace Questionable.Controller;
internal sealed class MovementController : IDisposable internal sealed class MovementController : IDisposable
{ {
private static readonly List<BlacklistedArea> BlacklistedAreas =
[
new(1191, new(-223.0412f, 31.937134f, -584.03906f), 5f, 7.75f),
];
private readonly NavmeshIpc _navmeshIpc; private readonly NavmeshIpc _navmeshIpc;
private readonly IClientState _clientState; private readonly IClientState _clientState;
private readonly GameFunctions _gameFunctions; private readonly GameFunctions _gameFunctions;
private readonly ChatFunctions _chatFunctions; private readonly ChatFunctions _chatFunctions;
private readonly ICondition _condition; private readonly ICondition _condition;
private readonly MovementOverrideController _movementOverrideController;
private readonly ILogger<MovementController> _logger; private readonly ILogger<MovementController> _logger;
private CancellationTokenSource? _cancellationTokenSource; private CancellationTokenSource? _cancellationTokenSource;
private Task<List<Vector3>>? _pathfindTask; private Task<List<Vector3>>? _pathfindTask;
public MovementController(NavmeshIpc navmeshIpc, IClientState clientState, GameFunctions gameFunctions, public MovementController(NavmeshIpc navmeshIpc, IClientState clientState, GameFunctions gameFunctions,
ChatFunctions chatFunctions, ICondition condition, ILogger<MovementController> logger) ChatFunctions chatFunctions, ICondition condition, MovementOverrideController movementOverrideController,
ILogger<MovementController> logger)
{ {
_navmeshIpc = navmeshIpc; _navmeshIpc = navmeshIpc;
_clientState = clientState; _clientState = clientState;
_gameFunctions = gameFunctions; _gameFunctions = gameFunctions;
_chatFunctions = chatFunctions; _chatFunctions = chatFunctions;
_condition = condition; _condition = condition;
_movementOverrideController = movementOverrideController;
_logger = logger; _logger = logger;
} }
@ -112,29 +111,7 @@ internal sealed class MovementController : IDisposable
} }
if (!Destination.IsFlying) if (!Destination.IsFlying)
{ _movementOverrideController.AdjustPath(navPoints);
// certain areas shouldn't have navmesh points in them, e.g. the aetheryte in HF Outskirts can't be
// walked on without jumping, but if you teleport to the wrong side you're fucked otherwise.
foreach (var blacklistedArea in BlacklistedAreas)
{
if (_clientState.TerritoryType != blacklistedArea.TerritoryId)
continue;
for (int i = 0; i < navPoints.Count; ++i)
{
var point = navPoints[i];
float distance = (point - blacklistedArea.Center).Length();
if (distance < blacklistedArea.MinDistance || distance > blacklistedArea.MaxDistance)
continue;
_logger.LogInformation("Fudging navmesh point {Point} in blacklisted area",
point.ToString("G", CultureInfo.InvariantCulture));
navPoints[i] = blacklistedArea.Center +
Vector3.Normalize(point - blacklistedArea.Center) *
blacklistedArea.MaxDistance;
}
}
}
_navmeshIpc.MoveTo(navPoints, Destination.IsFlying); _navmeshIpc.MoveTo(navPoints, Destination.IsFlying);
MovementStartedAt = DateTime.Now; MovementStartedAt = DateTime.Now;
@ -175,7 +152,8 @@ internal sealed class MovementController : IDisposable
{ {
if (Destination.DataId if (Destination.DataId
is 2012173 or 2012174 or 2012175 or 2012176 is 2012173 or 2012174 or 2012175 or 2012176
or 2014133 or 2014134 or 2014135) or 2014133 or 2014134 or 2014135
or 2014105)
{ {
Stop(); Stop();
} }
@ -336,12 +314,6 @@ internal sealed class MovementController : IDisposable
bool CanSprint, bool CanSprint,
bool UseNavmesh); bool UseNavmesh);
public sealed record BlacklistedArea(
ushort TerritoryId,
Vector3 Center,
float MinDistance,
float MaxDistance);
public sealed class PathfindingFailedException : Exception public sealed class PathfindingFailedException : Exception
{ {
public PathfindingFailedException() public PathfindingFailedException()

View File

@ -0,0 +1,19 @@
using System.Numerics;
namespace Questionable.Controller.NavigationOverrides;
internal sealed record BlacklistedArea(
ushort TerritoryId,
Vector3 Center,
float MinDistance,
float MaxDistance) : IBlacklistedLocation
{
public Vector3? AdjustPoint(Vector3 point)
{
float distance = (point - Center).Length();
if (distance < MinDistance || distance > MaxDistance)
return null;
return Center + Vector3.Normalize(point - Center) * MaxDistance;
}
}

View File

@ -0,0 +1,19 @@
using System.Numerics;
namespace Questionable.Controller.NavigationOverrides;
public sealed record BlacklistedPoint(
ushort TerritoryId,
Vector3 Original,
Vector3 Replacement,
float CheckDistance = 0.05f) : IBlacklistedLocation
{
public Vector3? AdjustPoint(Vector3 point)
{
float distance = (point - Original).Length();
if (distance > CheckDistance)
return null;
return Replacement;
}
}

View File

@ -0,0 +1,10 @@
using System.Numerics;
namespace Questionable.Controller.NavigationOverrides;
internal interface IBlacklistedLocation
{
ushort TerritoryId { get; }
Vector3? AdjustPoint(Vector3 point);
}

View File

@ -0,0 +1,52 @@
using System.Collections.Generic;
using System.Globalization;
using System.Numerics;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.Logging;
namespace Questionable.Controller.NavigationOverrides;
internal sealed class MovementOverrideController
{
private static readonly List<IBlacklistedLocation> BlacklistedLocations = [
new BlacklistedArea(1191, new(-223.0412f, 31.937134f, -584.03906f), 5f, 7.75f),
new BlacklistedPoint(128, new Vector3(2f, 40.25f, 36.5f), new Vector3(0.25f, 40.25f, 36.5f))
];
private readonly IClientState _clientState;
private readonly ILogger<MovementOverrideController> _logger;
public MovementOverrideController(IClientState clientState, ILogger<MovementOverrideController> logger)
{
_clientState = clientState;
_logger = logger;
}
/// <summary>
/// Certain areas shouldn't have navmesh points in them, e.g. the aetheryte in HF Outskirts can't be
/// walked on without jumping, but if you teleport to the wrong side you're fucked otherwise.
/// </summary>
/// <param name="navPoints">list of points to check</param>
public void AdjustPath(List<Vector3> navPoints)
{
foreach (var blacklistedArea in BlacklistedLocations)
{
if (_clientState.TerritoryType != blacklistedArea.TerritoryId)
continue;
for (int i = 0; i < navPoints.Count; ++i)
{
Vector3? updatedPoint = blacklistedArea.AdjustPoint(navPoints[i]);
if (updatedPoint != null)
{
_logger.LogInformation("Fudging navmesh point from {Original} to {Replacement} in blacklisted area",
navPoints[i].ToString("G", CultureInfo.InvariantCulture),
updatedPoint.Value.ToString("G", CultureInfo.InvariantCulture));
navPoints[i] = updatedPoint.Value;
}
}
}
}
}

View File

@ -9,6 +9,7 @@ using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Questionable.Controller; using Questionable.Controller;
using Questionable.Controller.NavigationOverrides;
using Questionable.Controller.Steps; using Questionable.Controller.Steps;
using Questionable.Controller.Steps.BaseFactory; using Questionable.Controller.Steps.BaseFactory;
using Questionable.Controller.Steps.BaseTasks; using Questionable.Controller.Steps.BaseTasks;
@ -114,6 +115,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
serviceCollection.AddTransient<WaitAtEnd.WaitQuestCompleted>(); serviceCollection.AddTransient<WaitAtEnd.WaitQuestCompleted>();
serviceCollection.AddSingleton<MovementController>(); serviceCollection.AddSingleton<MovementController>();
serviceCollection.AddSingleton<MovementOverrideController>();
serviceCollection.AddSingleton<QuestRegistry>(); serviceCollection.AddSingleton<QuestRegistry>();
serviceCollection.AddSingleton<QuestController>(); serviceCollection.AddSingleton<QuestController>();
serviceCollection.AddSingleton<GameUiController>(); serviceCollection.AddSingleton<GameUiController>();