Allied Society daily 'quest', part 1
This commit is contained in:
parent
ad610d6ddc
commit
6b38e37271
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||||
|
"Author": "liza",
|
||||||
|
"QuestSequence": [
|
||||||
|
{
|
||||||
|
"Sequence": 0,
|
||||||
|
"Steps": [
|
||||||
|
{
|
||||||
|
"DataId": 1016089,
|
||||||
|
"Position": {
|
||||||
|
"X": -799.46594,
|
||||||
|
"Y": -133.2695,
|
||||||
|
"Z": -404.1352
|
||||||
|
},
|
||||||
|
"StopDistance": 3,
|
||||||
|
"TerritoryId": 401,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"AetheryteShortcut": "The Sea of Clouds - Ok' Zundu",
|
||||||
|
"Fly": true,
|
||||||
|
"SkipConditions": {
|
||||||
|
"AetheryteShortcutIf": {
|
||||||
|
"InSameTerritory": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -58,6 +58,17 @@
|
|||||||
{
|
{
|
||||||
"Sequence": 2,
|
"Sequence": 2,
|
||||||
"Steps": [
|
"Steps": [
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": -799.46594,
|
||||||
|
"Y": -133.2695,
|
||||||
|
"Z": -404.1352
|
||||||
|
},
|
||||||
|
"TerritoryId": 401,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"AetheryteShortcut": "The Sea of Clouds - Ok' Zundu",
|
||||||
|
"Fly": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"DataId": 1016089,
|
"DataId": 1016089,
|
||||||
"Position": {
|
"Position": {
|
||||||
@ -67,8 +78,7 @@
|
|||||||
},
|
},
|
||||||
"TerritoryId": 401,
|
"TerritoryId": 401,
|
||||||
"InteractionType": "Interact",
|
"InteractionType": "Interact",
|
||||||
"AetheryteShortcut": "The Sea of Clouds - Ok' Zundu",
|
"Mount": false
|
||||||
"Fly": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
|
||||||
|
"Author": "liza",
|
||||||
|
"QuestSequence": [
|
||||||
|
{
|
||||||
|
"Sequence": 0,
|
||||||
|
"Steps": [
|
||||||
|
{
|
||||||
|
"Position": {
|
||||||
|
"X": 58.39701,
|
||||||
|
"Y": -48.000008,
|
||||||
|
"Z": -172.36507
|
||||||
|
},
|
||||||
|
"TerritoryId": 398,
|
||||||
|
"InteractionType": "WalkTo",
|
||||||
|
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine",
|
||||||
|
"Fly": true,
|
||||||
|
"SkipConditions": {
|
||||||
|
"AetheryteShortcutIf": {
|
||||||
|
"InSameTerritory": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -56,6 +56,19 @@ public abstract class ElementId : IComparable<ElementId>, IEquatable<ElementId>
|
|||||||
return new LeveId(ushort.Parse(value.Substring(1), CultureInfo.InvariantCulture));
|
return new LeveId(ushort.Parse(value.Substring(1), CultureInfo.InvariantCulture));
|
||||||
else if (value.StartsWith("S"))
|
else if (value.StartsWith("S"))
|
||||||
return new SatisfactionSupplyNpcId(ushort.Parse(value.Substring(1), CultureInfo.InvariantCulture));
|
return new SatisfactionSupplyNpcId(ushort.Parse(value.Substring(1), CultureInfo.InvariantCulture));
|
||||||
|
else if (value.StartsWith("A"))
|
||||||
|
{
|
||||||
|
value = value.Substring(1);
|
||||||
|
string[] parts = value.Split('x');
|
||||||
|
if (parts.Length == 2)
|
||||||
|
{
|
||||||
|
return new AlliedSocietyDailyId(
|
||||||
|
byte.Parse(parts[0], CultureInfo.InvariantCulture),
|
||||||
|
byte.Parse(parts[1], CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return new AlliedSocietyDailyId(byte.Parse(value, CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return new QuestId(ushort.Parse(value, CultureInfo.InvariantCulture));
|
return new QuestId(ushort.Parse(value, CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
@ -70,7 +83,8 @@ public abstract class ElementId : IComparable<ElementId>, IEquatable<ElementId>
|
|||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
elementId = null;
|
elementId = null;
|
||||||
return false;
|
//return false;
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,3 +112,14 @@ public sealed class SatisfactionSupplyNpcId(ushort value) : ElementId(value)
|
|||||||
return "S" + Value.ToString(CultureInfo.InvariantCulture);
|
return "S" + Value.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class AlliedSocietyDailyId(byte alliedSociety, byte rank = 0) : ElementId((ushort)(alliedSociety * 10 + rank))
|
||||||
|
{
|
||||||
|
public byte AlliedSociety { get; } = alliedSociety;
|
||||||
|
public byte Rank { get; } = rank;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "A" + AlliedSociety + "x" + Rank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ using Dalamud.Game.ClientState.Objects;
|
|||||||
using Dalamud.Game.Command;
|
using Dalamud.Game.Command;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Lumina.Excel.Sheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Questionable.Functions;
|
using Questionable.Functions;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
using Questionable.Windows;
|
using Questionable.Windows;
|
||||||
|
@ -68,6 +68,29 @@ internal sealed class QuestData
|
|||||||
.Where(x => x.LevelLevemete.RowId != 0)
|
.Where(x => x.LevelLevemete.RowId != 0)
|
||||||
.Select(x => new LeveInfo(x)),
|
.Select(x => new LeveInfo(x)),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
quests.AddRange(
|
||||||
|
dataManager.GetExcelSheet<BeastTribe>()
|
||||||
|
.Where(x => x.RowId > 0 && !x.Name.IsEmpty)
|
||||||
|
.SelectMany(x =>
|
||||||
|
{
|
||||||
|
if (x.RowId < 5)
|
||||||
|
{
|
||||||
|
return ((IEnumerable<byte>)
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
..quests.Where(y => y.AlliedSociety == (EAlliedSociety)x.RowId && y.IsRepeatable)
|
||||||
|
.Cast<QuestInfo>()
|
||||||
|
.Select(y => (byte)y.AlliedSocietyRank).Distinct()
|
||||||
|
])
|
||||||
|
.Select(rank => new AlliedSocietyDailyInfo(x, rank));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return [new AlliedSocietyDailyInfo(x, 0)];
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
_quests = quests.ToDictionary(x => x.QuestId, x => x);
|
_quests = quests.ToDictionary(x => x.QuestId, x => x);
|
||||||
|
|
||||||
// workaround because the game doesn't require completion of the CT questline through normal means
|
// workaround because the game doesn't require completion of the CT questline through normal means
|
||||||
|
@ -14,7 +14,6 @@ using LLib.GameData;
|
|||||||
using LLib.GameUI;
|
using LLib.GameUI;
|
||||||
using Lumina.Excel.Sheets;
|
using Lumina.Excel.Sheets;
|
||||||
using Questionable.Controller;
|
using Questionable.Controller;
|
||||||
using Questionable.Controller.Steps.Interactions;
|
|
||||||
using Questionable.Data;
|
using Questionable.Data;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
@ -487,6 +486,8 @@ internal sealed unsafe class QuestFunctions
|
|||||||
return IsQuestAccepted(leveId);
|
return IsQuestAccepted(leveId);
|
||||||
else if (elementId is SatisfactionSupplyNpcId)
|
else if (elementId is SatisfactionSupplyNpcId)
|
||||||
return false;
|
return false;
|
||||||
|
else if (elementId is AlliedSocietyDailyId)
|
||||||
|
return false;
|
||||||
else
|
else
|
||||||
throw new ArgumentOutOfRangeException(nameof(elementId));
|
throw new ArgumentOutOfRangeException(nameof(elementId));
|
||||||
}
|
}
|
||||||
@ -517,6 +518,8 @@ internal sealed unsafe class QuestFunctions
|
|||||||
return IsQuestComplete(leveId);
|
return IsQuestComplete(leveId);
|
||||||
else if (elementId is SatisfactionSupplyNpcId)
|
else if (elementId is SatisfactionSupplyNpcId)
|
||||||
return false;
|
return false;
|
||||||
|
else if (elementId is AlliedSocietyDailyId)
|
||||||
|
return false;
|
||||||
else
|
else
|
||||||
throw new ArgumentOutOfRangeException(nameof(elementId));
|
throw new ArgumentOutOfRangeException(nameof(elementId));
|
||||||
}
|
}
|
||||||
@ -540,6 +543,8 @@ internal sealed unsafe class QuestFunctions
|
|||||||
return IsQuestLocked(leveId);
|
return IsQuestLocked(leveId);
|
||||||
else if (elementId is SatisfactionSupplyNpcId satisfactionSupplyNpcId)
|
else if (elementId is SatisfactionSupplyNpcId satisfactionSupplyNpcId)
|
||||||
return IsQuestLocked(satisfactionSupplyNpcId);
|
return IsQuestLocked(satisfactionSupplyNpcId);
|
||||||
|
else if (elementId is AlliedSocietyDailyId alliedSocietyDailyId)
|
||||||
|
return IsQuestLocked(alliedSocietyDailyId);
|
||||||
else
|
else
|
||||||
throw new ArgumentOutOfRangeException(nameof(elementId));
|
throw new ArgumentOutOfRangeException(nameof(elementId));
|
||||||
}
|
}
|
||||||
@ -579,6 +584,13 @@ internal sealed unsafe class QuestFunctions
|
|||||||
return !HasCompletedPreviousQuests(questInfo, null);
|
return !HasCompletedPreviousQuests(questInfo, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsQuestLocked(AlliedSocietyDailyId alliedSocietyDailyId)
|
||||||
|
{
|
||||||
|
PlayerState* playerState = PlayerState.Instance();
|
||||||
|
byte currentRank = playerState->GetBeastTribeRank(alliedSocietyDailyId.AlliedSociety);
|
||||||
|
return currentRank == 0 || currentRank < alliedSocietyDailyId.Rank;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsDailyAlliedSocietyQuest(QuestId questId)
|
public bool IsDailyAlliedSocietyQuest(QuestId questId)
|
||||||
{
|
{
|
||||||
var questInfo = (QuestInfo)_questData.GetQuestInfo(questId);
|
var questInfo = (QuestInfo)_questData.GetQuestInfo(questId);
|
||||||
|
60
Questionable/Model/AlliedSocietyDailyInfo.cs
Normal file
60
Questionable/Model/AlliedSocietyDailyInfo.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq;
|
||||||
|
using LLib.GameData;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
using Questionable.Data;
|
||||||
|
using Questionable.Model.Questing;
|
||||||
|
|
||||||
|
namespace Questionable.Model;
|
||||||
|
|
||||||
|
internal sealed class AlliedSocietyDailyInfo : IQuestInfo
|
||||||
|
{
|
||||||
|
public AlliedSocietyDailyInfo(BeastTribe beastTribe, byte rank)
|
||||||
|
{
|
||||||
|
QuestId = new AlliedSocietyDailyId((byte)beastTribe.RowId, rank);
|
||||||
|
Name = beastTribe.Name.ToString();
|
||||||
|
ClassJobs = (EAlliedSociety)beastTribe.RowId switch
|
||||||
|
{
|
||||||
|
EAlliedSociety.Amaljaa or EAlliedSociety.Sylphs or EAlliedSociety.Kobolds or EAlliedSociety.Sahagin or
|
||||||
|
EAlliedSociety.VanuVanu or EAlliedSociety.Vath or
|
||||||
|
EAlliedSociety.Kojin or EAlliedSociety.Ananta or
|
||||||
|
EAlliedSociety.Pixies or
|
||||||
|
EAlliedSociety.Arkasodara or
|
||||||
|
EAlliedSociety.Pelupelu =>
|
||||||
|
[
|
||||||
|
..ClassJobUtils.AsIndividualJobs(EExtendedClassJob.DoW),
|
||||||
|
..ClassJobUtils.AsIndividualJobs(EExtendedClassJob.DoM)
|
||||||
|
],
|
||||||
|
EAlliedSociety.Ixal or EAlliedSociety.Moogles or EAlliedSociety.Dwarves or EAlliedSociety.Loporrits =>
|
||||||
|
ClassJobUtils.AsIndividualJobs(EExtendedClassJob.DoH).ToList(),
|
||||||
|
|
||||||
|
EAlliedSociety.Qitari or EAlliedSociety.Omicrons =>
|
||||||
|
ClassJobUtils.AsIndividualJobs(EExtendedClassJob.DoL).ToList(),
|
||||||
|
|
||||||
|
EAlliedSociety.Namazu =>
|
||||||
|
[
|
||||||
|
..ClassJobUtils.AsIndividualJobs(EExtendedClassJob.DoH),
|
||||||
|
..ClassJobUtils.AsIndividualJobs(EExtendedClassJob.DoL)
|
||||||
|
],
|
||||||
|
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(beastTribe))
|
||||||
|
};
|
||||||
|
Expansion = (EExpansionVersion)beastTribe.Expansion.RowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElementId QuestId { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public uint IssuerDataId => 0;
|
||||||
|
public ImmutableList<PreviousQuestInfo> PreviousQuests { get; } = [];
|
||||||
|
public EQuestJoin PreviousQuestJoin => EQuestJoin.All;
|
||||||
|
public bool IsRepeatable => true;
|
||||||
|
public ushort Level => 1;
|
||||||
|
public EAlliedSociety AlliedSociety => EAlliedSociety.None;
|
||||||
|
public uint? JournalGenre => null;
|
||||||
|
public ushort SortKey => 0;
|
||||||
|
public bool IsMainScenarioQuest => false;
|
||||||
|
public IReadOnlyList<EClassJob> ClassJobs { get; }
|
||||||
|
public EExpansionVersion Expansion { get; }
|
||||||
|
}
|
@ -106,7 +106,7 @@ internal sealed class PriorityWindow : LWindow
|
|||||||
if (!string.IsNullOrEmpty(_searchString))
|
if (!string.IsNullOrEmpty(_searchString))
|
||||||
{
|
{
|
||||||
foundQuests = _questRegistry.AllQuests
|
foundQuests = _questRegistry.AllQuests
|
||||||
.Where(x => x.Id is not SatisfactionSupplyNpcId)
|
.Where(x => x.Id is not SatisfactionSupplyNpcId and not AlliedSocietyDailyId)
|
||||||
.Where(x => x.Info.Name.Contains(_searchString, StringComparison.CurrentCultureIgnoreCase))
|
.Where(x => x.Info.Name.Contains(_searchString, StringComparison.CurrentCultureIgnoreCase))
|
||||||
.Where(x => !_questFunctions.IsQuestUnobtainable(x.Id));
|
.Where(x => !_questFunctions.IsQuestUnobtainable(x.Id));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user