Compare commits

..

1 Commits

Author SHA1 Message Date
Plogon Enjoyer
59f3ae6c21 Added new daily quest - Tale of Roe 2024-11-25 20:49:42 +08:00
11 changed files with 200 additions and 383 deletions

View File

@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<Version>4.5</Version>
<Version>4.4</Version>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,180 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "plogon_enjoyer",
"QuestSequence": [
{
"Sequence": 0,
"Steps": [
{
"DataId": 1024217,
"Position": {
"X": 394.39978,
"Y": -119.58932,
"Z": -232.28815
},
"TerritoryId": 613,
"InteractionType": "AcceptQuest"
}
]
},
{
"Sequence": 1,
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] The Ruby Price"
]
},
{
"DataId": 2009100,
"Position": {
"X": 394.7661,
"Y": 16.983276,
"Z": 845.9448
},
"TerritoryId": 613,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2002419,
"KillEnemyDataIds": [8242],
"RequiredQuestVariables": [
null,
null,
null,
null,
[48, 80, 112, 128],
null
],
"Fly": true
},
{
"DataId": 2009101,
"Position": {
"X": 460.99023,
"Y": 0.56451416,
"Z": 889.494
},
"TerritoryId": 613,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2002419,
"KillEnemyDataIds": [8242],
"RequiredQuestVariables": [
null,
null,
null,
null,
[16, 32, 128],
null
],
"Fly": true
},
{
"DataId": 2009142,
"Position": {
"X": 480.4607,
"Y": 3.829956,
"Z": 841.3672
},
"TerritoryId": 613,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2002419,
"KillEnemyDataIds": [8242],
"RequiredQuestVariables": [
null,
null,
null,
null,
[16, 64, 80, 96],
null
],
"Fly": true
},
{
"DataId": 2009140,
"Position": {
"X": 543.1753,
"Y": -0.015319824,
"Z": 685.7251
},
"TerritoryId": 613,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2002419,
"KillEnemyDataIds": [8243, 8243],
"RequiredQuestVariables": [null, null, null, null, [96, 112], null],
"Fly": true
},
{
"DataId": 2009141,
"Position": {
"X": 352.1018,
"Y": -0.015319824,
"Z": 860.31885
},
"TerritoryId": 613,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2002419,
"KillEnemyDataIds": [8243, 8243],
"RequiredQuestVariables": [
null,
null,
null,
null,
[32, 48, 64],
null
],
"Fly": true
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1024317,
"Position": {
"X": 823.3004,
"Y": 5.9230013,
"Z": 866.6361
},
"TerritoryId": 613,
"InteractionType": "Interact",
"Fly": true
}
]
},
{
"Sequence": 255,
"Steps": [
{
"Position": {
"X": 392.59683,
"Y": -119.589325,
"Z": -234.30063
},
"TerritoryId": 613,
"InteractionType": "WalkTo",
"AetheryteShortcut": "Ruby Sea - Tamamizu",
"Fly": true
},
{
"DataId": 1024217,
"Position": {
"X": 394.39978,
"Y": -119.58932,
"Z": -232.28815
},
"TerritoryId": 613,
"InteractionType": "CompleteQuest"
}
]
}
]
}

View File

@ -0,0 +1,10 @@
0 0 0 0 xxx 0 | 2009100 2009101 2009140 2009141 2009142
16 x x
32 x x
48 x x
64 x x
80 x x
96 x x
112 x x
128 x x

View File

@ -1,6 +1,7 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"Disabled": true,
"QuestSequence": [
{
"Sequence": 0,
@ -27,122 +28,6 @@
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 2014504,
"Position": {
"X": -232.22711,
"Y": 120.25635,
"Z": 26.199707
},
"TerritoryId": 1188,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2003727,
"KillEnemyDataIds": [
18176
],
"AetheryteShortcut": "Kozama'uka - Earthenshire",
"Fly": true,
"RequiredQuestVariables": [
null,
null,
null,
[
{
"High": 1
}
],
null,
null
]
},
{
"DataId": 2014503,
"Position": {
"X": -134.29468,
"Y": 120.62256,
"Z": 41.000854
},
"TerritoryId": 1188,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2003727,
"KillEnemyDataIds": [
18176
],
"Fly": true,
"RequiredQuestVariables": [
null,
null,
null,
[
{
"High": 2
}
],
null,
null
]
},
{
"DataId": 2014505,
"Position": {
"X": -292.28656,
"Y": 119.46289,
"Z": 17.959839
},
"TerritoryId": 1188,
"InteractionType": "Combat",
"EnemySpawnType": "AfterItemUse",
"ItemId": 2003727,
"KillEnemyDataIds": [
18176
],
"Fly": true,
"RequiredQuestVariables": [
null,
null,
null,
[
{
"High": 3
}
],
null,
null
]
}
]
},
{
"Sequence": 2,
"Steps": [
{
"Position": {
"X": 746.76465,
"Y": 15.431515,
"Z": -201.92921
},
"TerritoryId": 1188,
"InteractionType": "WalkTo",
"AetheryteShortcut": "Kozama'uka - Dock Poga"
},
{
"DataId": 1051741,
"Position": {
"X": 744.19763,
"Y": 15.431515,
"Z": -199.17603
},
"StopDistance": 7,
"TerritoryId": 1188,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 255,
"Steps": [
@ -154,20 +39,7 @@
},
"TerritoryId": 1188,
"InteractionType": "WalkTo",
"AetheryteShortcut": "Kozama'uka - Dock Poga",
"SkipConditions": {
"AetheryteShortcutIf": {
"NearPosition": {
"Position": {
"X": 770.7179,
"Y": 12.84657,
"Z": -263.99634
},
"TerritoryId": 1188,
"MaximumDistance": 300
}
}
}
"AetheryteShortcut": "Kozama'uka - Dock Poga"
},
{
"DataId": 1051711,

View File

@ -1,6 +1,7 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"Disabled": true,
"QuestSequence": [
{
"Sequence": 0,
@ -27,35 +28,6 @@
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1052337,
"Position": {
"X": 479.14844,
"Y": 113.54922,
"Z": 175.37183
},
"TerritoryId": 1188,
"InteractionType": "Interact",
"AetheryteShortcut": "Kozama'uka - Many Fires",
"Fly": true,
"DialogueChoices": [
{
"Type": "List",
"Prompt": "TEXT_BANPEL123_05221_Q1_000_000",
"Answer": "TEXT_BANPEL123_05221_A1_000_003"
},
{
"Type": "List",
"Prompt": "TEXT_BANPEL123_05221_Q2_000_000",
"Answer": "TEXT_BANPEL123_05221_A2_000_002"
}
]
}
]
},
{
"Sequence": 255,
"Steps": [

View File

@ -1,6 +1,7 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"Disabled": true,
"QuestSequence": [
{
"Sequence": 0,
@ -27,66 +28,6 @@
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1052339,
"Position": {
"X": 910.3379,
"Y": 10.1397,
"Z": -381.36877
},
"TerritoryId": 1188,
"InteractionType": "Interact",
"Fly": true,
"AetheryteShortcut": "Kozama'uka - Dock Poga",
"SkipConditions": {
"AetheryteShortcutIf": {
"NearPosition": {
"Position": {
"X": 770.7179,
"Y": 12.84657,
"Z": -263.99634
},
"TerritoryId": 1188,
"MaximumDistance": 300
}
}
}
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 2014506,
"Position": {
"X": 910.3379,
"Y": 10.421875,
"Z": -379.01886
},
"TerritoryId": 1188,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 3,
"Steps": [
{
"DataId": 1052340,
"Position": {
"X": 789.9137,
"Y": 14.354868,
"Z": -215.77783
},
"TerritoryId": 1188,
"InteractionType": "Interact"
}
]
},
{
"Sequence": 255,
"Steps": [
@ -98,20 +39,7 @@
},
"TerritoryId": 1188,
"InteractionType": "WalkTo",
"AetheryteShortcut": "Kozama'uka - Dock Poga",
"SkipConditions": {
"AetheryteShortcutIf": {
"NearPosition": {
"Position": {
"X": 770.7179,
"Y": 12.84657,
"Z": -263.99634
},
"TerritoryId": 1188,
"MaximumDistance": 300
}
}
}
"AetheryteShortcut": "Kozama'uka - Dock Poga"
},
{
"DataId": 1051711,

View File

@ -1,6 +1,7 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
"Author": "liza",
"Disabled": true,
"QuestSequence": [
{
"Sequence": 0,
@ -27,53 +28,6 @@
}
]
},
{
"Sequence": 1,
"Steps": [
{
"DataId": 1051798,
"Position": {
"X": 897.734,
"Y": 6.8223433,
"Z": -285.1759
},
"TerritoryId": 1188,
"InteractionType": "Interact",
"Fly": true,
"AetheryteShortcut": "Kozama'uka - Dock Poga",
"SkipConditions": {
"AetheryteShortcutIf": {
"NearPosition": {
"Position": {
"X": 770.7179,
"Y": 12.84657,
"Z": -263.99634
},
"TerritoryId": 1188,
"MaximumDistance": 300
}
}
}
}
]
},
{
"Sequence": 2,
"Steps": [
{
"DataId": 1052345,
"Position": {
"X": 908.50684,
"Y": 5.7142797,
"Z": -337.85004
},
"TerritoryId": 1188,
"InteractionType": "Action",
"Action": "Bosom Brook",
"Fly": true
}
]
},
{
"Sequence": 255,
"Steps": [

View File

@ -4,10 +4,8 @@ using Dalamud.Game.Gui.ContextMenu;
using Dalamud.Game.Text;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using LLib.GameData;
using LLib.GameUI;
using Microsoft.Extensions.Logging;
using Questionable.Data;
using Questionable.Functions;
@ -61,16 +59,9 @@ internal sealed class ContextMenuController : IDisposable
private void MenuOpened(IMenuOpenedArgs args)
{
// no clue why this isn't the actual name, but here we are
if (args.AddonName != null)
return;
uint itemId = GetHoveredSatisfactionSupplyItemId();
uint itemId = (uint)_gameGui.HoveredItem;
if (itemId == 0)
{
_logger.LogTrace("Ignoring context menu, no item hovered");
return;
}
if (itemId > 1_000_000)
itemId -= 1_000_000;
@ -83,25 +74,6 @@ internal sealed class ContextMenuController : IDisposable
AddContextMenuEntry(args, itemId, npcId, EExtendedClassJob.Miner, "Mine");
AddContextMenuEntry(args, itemId, npcId, EExtendedClassJob.Botanist, "Harvest");
}
else
_logger.LogDebug("No custom delivery NPC found for item {ItemId}.", itemId);
}
private unsafe uint GetHoveredSatisfactionSupplyItemId()
{
AgentSatisfactionSupply* agent = AgentSatisfactionSupply.Instance();
if (agent == null || !agent->IsAgentActive())
return 0;
if (_gameGui.TryGetAddonByName("SatisfactionSupply", out AddonSatisfactionSupply* addon) &&
LAddon.IsAddonReady(&addon->AtkUnitBase) &&
addon->HoveredElementIndex is >= 0 and <= 2)
{
return agent->Items[addon->HoveredElementIndex].Id;
}
return 0;
}
private void AddContextMenuEntry(IMenuOpenedArgs args, uint itemId, uint npcId, EExtendedClassJob extendedClassJob,
@ -114,7 +86,7 @@ internal sealed class ContextMenuController : IDisposable
if (!_gatheringData.TryGetGatheringPointId(itemId, classJob, out _))
{
_logger.LogInformation("No gathering point found for {ClassJob}.", classJob);
_logger.LogInformation("No gathering point found for current job.");
return;
}

View File

@ -1,71 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Shared;
using Questionable.Data;
using Questionable.Functions;
using Questionable.Model;
using Questionable.Model.Common;
using Questionable.Model.Questing;
namespace Questionable.Controller.Steps;
internal static class QuestCleanUp
{
private static readonly Dictionary<ushort, MountConfiguration> AlliedSocietyMountConfiguration = new()
{
{ 369, new(1051798, EAetheryteLocation.KozamaukaDockPoga) }
};
internal sealed class CheckAlliedSocietyMount(GameFunctions gameFunctions, AetheryteData aetheryteData, ILogger<CheckAlliedSocietyMount> logger) : SimpleTaskFactory
{
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{
if (sequence.Sequence == 0)
return null;
// if you are on a allied society mount
if (gameFunctions.GetMountId() is { } mountId &&
AlliedSocietyMountConfiguration.TryGetValue(mountId, out var mountConfiguration))
{
logger.LogInformation("We are on a known allied society mount with id = {MountId}", mountId);
// it doesn't particularly matter if we teleport to the same aetheryte twice in the same quest step, as
// the second (normal) teleport instance should detect that we're within range and not do anything
var targetAetheryte = step.AetheryteShortcut ?? mountConfiguration.ClosestAetheryte;
var teleportTask = new AetheryteShortcut.Task(null, quest.Id, targetAetheryte, aetheryteData.TerritoryIds[targetAetheryte]);
// turn-in step can never be done while mounted on an allied society mount
if (sequence.Sequence == 255)
{
logger.LogInformation("Mount can't be used to finish quest, teleporting to {Aetheryte}", mountConfiguration.ClosestAetheryte);
return teleportTask;
}
// if the quest uses no mount actions, that's not a mount quest
if (!quest.AllSteps().Any(x => x.Step.Action is { } action && action.RequiresMount()))
{
logger.LogInformation("Quest doesn't use any mount actions, teleporting to {Aetheryte}", mountConfiguration.ClosestAetheryte);
return teleportTask;
}
// have any of the previous sequences interacted with the issuer?
var previousSequences =
quest.AllSequences()
.Where(x => x.Sequence > 0 // quest accept doesn't ever put us into a mount
&& x.Sequence < sequence.Sequence)
.ToList();
if (previousSequences.SelectMany(x => x.Steps).All(x => x.DataId != mountConfiguration.IssuerDataId))
{
// this quest hasn't given us a mount yet
logger.LogInformation("Haven't talked to mount NPC for this allied society quest; {Aetheryte}", mountConfiguration.ClosestAetheryte);
return teleportTask;
}
}
return null;
}
}
private sealed record MountConfiguration(uint IssuerDataId, EAetheryteLocation ClosestAetheryte);
}

View File

@ -243,6 +243,7 @@ internal sealed unsafe class QuestFunctions
{
return questId.Value switch
{
5215 => EAlliedSociety.None,
>= 5199 and <= 5226 => EAlliedSociety.Pelupelu,
_ => EAlliedSociety.None,
};

View File

@ -133,7 +133,6 @@ public sealed class QuestionablePlugin : IDalamudPlugin
private static void AddTaskFactories(ServiceCollection serviceCollection)
{
// individual tasks
serviceCollection.AddTaskFactory<QuestCleanUp.CheckAlliedSocietyMount>();
serviceCollection
.AddTaskExecutor<MoveToLandingLocation.Task, MoveToLandingLocation.MoveToLandingLocationExecutor>();
serviceCollection.AddTaskExecutor<DoGather.Task, DoGather.GatherExecutor>();