Rework task factories; finish up Artisan crafting

This commit is contained in:
Liza 2024-08-17 20:07:27 +02:00
parent cf56a01a08
commit 59d83cb338
Signed by: liza
GPG Key ID: 7199F8D727D55F67
30 changed files with 143 additions and 77 deletions

View File

@ -57,7 +57,8 @@
"Z": -273.68756 "Z": -273.68756
}, },
"TerritoryId": 959, "TerritoryId": 959,
"InteractionType": "WalkTo" "InteractionType": "WalkTo",
"Fly": true
}, },
{ {
"DataId": 1044403, "DataId": 1044403,

View File

@ -9,9 +9,9 @@ namespace Questionable.Controller.Steps.Common;
internal static class NextQuest internal static class NextQuest
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.CompleteQuest) if (step.InteractionType != EInteractionType.CompleteQuest)
return null; return null;

View File

@ -13,9 +13,9 @@ namespace Questionable.Controller.Steps.Gathering;
internal static class TurnInDelivery internal static class TurnInDelivery
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (quest.Id is not SatisfactionSupplyNpcId || sequence.Sequence != 1) if (quest.Id is not SatisfactionSupplyNpcId || sequence.Sequence != 1)
return null; return null;

View File

@ -6,12 +6,5 @@ namespace Questionable.Controller.Steps;
internal interface ITaskFactory internal interface ITaskFactory
{ {
ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step); IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step);
IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{
var task = CreateTask(quest, sequence, step);
if (task != null)
yield return task;
}
} }

View File

@ -33,9 +33,6 @@ internal static class Action
return [unmount, task]; return [unmount, task];
} }
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new InvalidOperationException();
} }
internal sealed class UseOnObject(GameFunctions gameFunctions, ILogger<UseOnObject> logger) : ITask internal sealed class UseOnObject(GameFunctions gameFunctions, ILogger<UseOnObject> logger) : ITask

View File

@ -11,9 +11,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class AetherCurrent internal static class AetherCurrent
{ {
internal sealed class Factory(IServiceProvider serviceProvider, AetherCurrentData aetherCurrentData, IChatGui chatGui) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider, AetherCurrentData aetherCurrentData, IChatGui chatGui) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.AttuneAetherCurrent) if (step.InteractionType != EInteractionType.AttuneAetherCurrent)
return null; return null;

View File

@ -11,9 +11,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class AethernetShard internal static class AethernetShard
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.AttuneAethernetShard) if (step.InteractionType != EInteractionType.AttuneAethernetShard)
return null; return null;

View File

@ -10,9 +10,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class Aetheryte internal static class Aetheryte
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.AttuneAetheryte) if (step.InteractionType != EInteractionType.AttuneAetheryte)
return null; return null;

View File

@ -18,9 +18,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class Dive internal static class Dive
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.Dive) if (step.InteractionType != EInteractionType.Dive)
return null; return null;

View File

@ -10,9 +10,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class Duty internal static class Duty
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.Duty) if (step.InteractionType != EInteractionType.Duty)
return null; return null;

View File

@ -36,9 +36,6 @@ internal static class Emote
return [unmount, task]; return [unmount, task];
} }
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new InvalidOperationException();
} }
internal sealed class UseOnObject(ChatFunctions chatFunctions) : AbstractDelayedTask internal sealed class UseOnObject(ChatFunctions chatFunctions) : AbstractDelayedTask

View File

@ -16,9 +16,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class EquipItem internal static class EquipItem
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.EquipItem) if (step.InteractionType != EInteractionType.EquipItem)
return null; return null;

View File

@ -10,9 +10,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class EquipRecommended internal static class EquipRecommended
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.EquipRecommended) if (step.InteractionType != EInteractionType.EquipRecommended)
return null; return null;
@ -21,9 +21,9 @@ internal static class EquipRecommended
} }
} }
internal sealed class BeforeDutyOrInstance(IServiceProvider serviceProvider) : ITaskFactory internal sealed class BeforeDutyOrInstance(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.Duty && if (step.InteractionType != EInteractionType.Duty &&
step.InteractionType != EInteractionType.SinglePlayerDuty && step.InteractionType != EInteractionType.SinglePlayerDuty &&

View File

@ -42,9 +42,6 @@ internal static class Interact
.With(step.DataId.Value, quest, step.InteractionType, .With(step.DataId.Value, quest, step.InteractionType,
step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId); step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId);
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new InvalidOperationException();
} }
internal sealed class DoInteract(GameFunctions gameFunctions, ICondition condition, ILogger<DoInteract> logger) internal sealed class DoInteract(GameFunctions gameFunctions, ICondition condition, ILogger<DoInteract> logger)

View File

@ -11,9 +11,9 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class Jump internal static class Jump
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.Jump) if (step.InteractionType != EInteractionType.Jump)
return null; return null;

View File

@ -28,9 +28,6 @@ internal static class Say
var task = serviceProvider.GetRequiredService<UseChat>().With(excelString); var task = serviceProvider.GetRequiredService<UseChat>().With(excelString);
return [unmount, task]; return [unmount, task];
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new InvalidOperationException();
} }
internal sealed class UseChat(ChatFunctions chatFunctions) : AbstractDelayedTask internal sealed class UseChat(ChatFunctions chatFunctions) : AbstractDelayedTask

View File

@ -100,9 +100,6 @@ internal static class UseItem
} }
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new InvalidOperationException();
private IEnumerable<ITask> CreateVesperBayFallbackTask() private IEnumerable<ITask> CreateVesperBayFallbackTask()
{ {
logger.LogWarning("No vesper bay aetheryte tickets in inventory, navigating via ferry in Limsa instead"); logger.LogWarning("No vesper bay aetheryte tickets in inventory, navigating via ferry in Limsa instead");

View File

@ -30,9 +30,6 @@ internal static class InitiateLeve
yield return serviceProvider.GetRequiredService<SelectDifficulty>(); yield return serviceProvider.GetRequiredService<SelectDifficulty>();
yield return new WaitConditionTask(() => condition[ConditionFlag.BoundByDuty], "Wait(BoundByDuty)"); yield return new WaitConditionTask(() => condition[ConditionFlag.BoundByDuty], "Wait(BoundByDuty)");
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new NotImplementedException();
} }
internal sealed unsafe class SkipInitiateIfActive : ITask internal sealed unsafe class SkipInitiateIfActive : ITask

View File

@ -20,9 +20,9 @@ namespace Questionable.Controller.Steps.Shared;
internal static class AethernetShortcut internal static class AethernetShortcut
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.AethernetShortcut == null) if (step.AethernetShortcut == null)
return null; return null;

View File

@ -17,9 +17,9 @@ internal static class AetheryteShortcut
{ {
internal sealed class Factory( internal sealed class Factory(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
AetheryteData aetheryteData) : ITaskFactory AetheryteData aetheryteData) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.AetheryteShortcut == null) if (step.AetheryteShortcut == null)
return null; return null;

View File

@ -1,9 +1,15 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using LLib.GameData; using LLib.GameData;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Common;
using Questionable.External; using Questionable.External;
using Questionable.Model.Questing; using Questionable.Model.Questing;
using Quest = Questionable.Model.Quest; using Quest = Questionable.Model.Quest;
@ -14,19 +20,27 @@ internal static class Craft
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.InteractionType != EInteractionType.Craft) if (step.InteractionType != EInteractionType.Craft)
return null; return [];
ArgumentNullException.ThrowIfNull(step.ItemId); ArgumentNullException.ThrowIfNull(step.ItemId);
ArgumentNullException.ThrowIfNull(step.ItemCount); ArgumentNullException.ThrowIfNull(step.ItemCount);
return serviceProvider.GetRequiredService<DoCraft>() return
.With(step.ItemId.Value, step.ItemCount.Value); [
serviceProvider.GetRequiredService<UnmountTask>(),
serviceProvider.GetRequiredService<DoCraft>()
.With(step.ItemId.Value, step.ItemCount.Value)
];
} }
} }
internal sealed class DoCraft(IDataManager dataManager, IClientState clientState, ArtisanIpc artisanIpc) : ITask internal sealed class DoCraft(
IDataManager dataManager,
IClientState clientState,
ArtisanIpc artisanIpc,
ILogger<DoCraft> logger) : ITask
{ {
private uint _itemId; private uint _itemId;
private int _itemCount; private int _itemCount;
@ -40,11 +54,17 @@ internal static class Craft
public bool Start() public bool Start()
{ {
if (HasRequestedItems())
{
logger.LogInformation("Already own {ItemCount}x {ItemId}", _itemCount, _itemId);
return false;
}
RecipeLookup? recipeLookup = dataManager.GetExcelSheet<RecipeLookup>()!.GetRow(_itemId); RecipeLookup? recipeLookup = dataManager.GetExcelSheet<RecipeLookup>()!.GetRow(_itemId);
if (recipeLookup == null) if (recipeLookup == null)
throw new TaskException($"Item {_itemId} is not craftable"); throw new TaskException($"Item {_itemId} is not craftable");
uint recipeId = ((EClassJob)clientState.LocalPlayer!.ClassJob.Id) switch uint recipeId = (EClassJob)clientState.LocalPlayer!.ClassJob.Id switch
{ {
EClassJob.Carpenter => recipeLookup.CRP.Row, EClassJob.Carpenter => recipeLookup.CRP.Row,
EClassJob.Blacksmith => recipeLookup.BSM.Row, EClassJob.Blacksmith => recipeLookup.BSM.Row,
@ -59,7 +79,8 @@ internal static class Craft
if (recipeId == 0) if (recipeId == 0)
{ {
recipeId = new[]{ recipeId = new[]
{
recipeLookup.CRP.Row, recipeLookup.CRP.Row,
recipeLookup.BSM.Row, recipeLookup.BSM.Row,
recipeLookup.ARM.Row, recipeLookup.ARM.Row,
@ -75,15 +96,49 @@ internal static class Craft
if (recipeId == 0) if (recipeId == 0)
throw new TaskException($"Unable to determine recipe for item {_itemId}"); throw new TaskException($"Unable to determine recipe for item {_itemId}");
if (!artisanIpc.CraftItem((ushort)recipeId, _itemCount)) int remainingItemCount = _itemCount - GetOwnedItemCount();
logger.LogInformation(
"Starting craft for item {ItemId} with recipe {RecipeId} for {RemainingItemCount} items",
_itemId, recipeId, remainingItemCount);
if (!artisanIpc.CraftItem((ushort)recipeId, remainingItemCount))
throw new TaskException($"Failed to start Artisan craft for recipe {recipeId}"); throw new TaskException($"Failed to start Artisan craft for recipe {recipeId}");
return true; return true;
} }
public ETaskResult Update() public unsafe ETaskResult Update()
{ {
if (HasRequestedItems() && !artisanIpc.IsCrafting())
{
AgentRecipeNote* agentRecipeNote = AgentRecipeNote.Instance();
if (agentRecipeNote != null && agentRecipeNote->IsAgentActive())
{
uint addonId = agentRecipeNote->GetAddonId();
if (addonId == 0)
return ETaskResult.StillRunning;
AtkUnitBase* addon = AtkStage.Instance()->RaptureAtkUnitManager->GetAddonById((ushort)addonId);
if (addon != null)
{
logger.LogInformation("Closing crafting window");
addon->Close(true);
return ETaskResult.TaskComplete;
}
}
}
return ETaskResult.StillRunning; return ETaskResult.StillRunning;
} }
private bool HasRequestedItems() => GetOwnedItemCount() >= _itemCount;
private unsafe int GetOwnedItemCount()
{
InventoryManager* inventoryManager = InventoryManager.Instance();
return inventoryManager->GetInventoryItemCount(_itemId, isHq: false, checkEquipped: false)
+ inventoryManager->GetInventoryItemCount(_itemId, isHq: true, checkEquipped: false);
}
public override string ToString() => $"Craft {_itemCount}x {_itemId} (with Artisan)";
} }
} }

View File

@ -105,9 +105,6 @@ internal static class GatheringRequiredItems
minCollectability: (short)requiredGatheredItems.Collectability) >= minCollectability: (short)requiredGatheredItems.Collectability) >=
requiredGatheredItems.ItemCount; requiredGatheredItems.ItemCount;
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new NotImplementedException();
} }
internal sealed class StartGathering(GatheringController gatheringController) : ITask internal sealed class StartGathering(GatheringController gatheringController) : ITask

View File

@ -59,9 +59,6 @@ internal static class Move
return []; return [];
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new InvalidOperationException();
} }
internal sealed class MoveBuilder( internal sealed class MoveBuilder(

View File

@ -20,9 +20,9 @@ namespace Questionable.Controller.Steps.Shared;
internal static class SkipCondition internal static class SkipCondition
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
var skipConditions = step.SkipConditions?.StepIf; var skipConditions = step.SkipConditions?.StepIf;
if (skipConditions is { Never: true }) if (skipConditions is { Never: true })

View File

@ -8,9 +8,9 @@ namespace Questionable.Controller.Steps.Shared;
internal static class StepDisabled internal static class StepDisabled
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (!step.Disabled) if (!step.Disabled)
return null; return null;

View File

@ -136,9 +136,6 @@ internal static class WaitAtEnd
} }
} }
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
=> throw new InvalidOperationException();
private static NextStep Next(Quest quest, QuestSequence sequence) private static NextStep Next(Quest quest, QuestSequence sequence)
{ {
return new NextStep(quest.Id, sequence.Sequence); return new NextStep(quest.Id, sequence.Sequence);

View File

@ -8,9 +8,9 @@ namespace Questionable.Controller.Steps.Shared;
internal static class WaitAtStart internal static class WaitAtStart
{ {
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory internal sealed class Factory(IServiceProvider serviceProvider) : SimpleTaskFactory
{ {
public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
{ {
if (step.DelaySecondsAtStart == null) if (step.DelaySecondsAtStart == null)
return null; return null;

View File

@ -0,0 +1,17 @@
using System.Collections.Generic;
using Questionable.Model;
using Questionable.Model.Questing;
namespace Questionable.Controller.Steps;
internal abstract class SimpleTaskFactory : ITaskFactory
{
public abstract ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step);
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{
var task = CreateTask(quest, sequence, step);
if (task != null)
yield return task;
}
}

View File

@ -9,11 +9,13 @@ internal sealed class ArtisanIpc
{ {
private readonly ILogger<ArtisanIpc> _logger; private readonly ILogger<ArtisanIpc> _logger;
private readonly ICallGateSubscriber<ushort, int, object> _craftItem; private readonly ICallGateSubscriber<ushort, int, object> _craftItem;
private readonly ICallGateSubscriber<bool> _getEnduranceStatus;
public ArtisanIpc(IDalamudPluginInterface pluginInterface, ILogger<ArtisanIpc> logger) public ArtisanIpc(IDalamudPluginInterface pluginInterface, ILogger<ArtisanIpc> logger)
{ {
_logger = logger; _logger = logger;
_craftItem = pluginInterface.GetIpcSubscriber<ushort, int, object>("Artisan.CraftItem"); _craftItem = pluginInterface.GetIpcSubscriber<ushort, int, object>("Artisan.CraftItem");
_getEnduranceStatus = pluginInterface.GetIpcSubscriber<bool>("Artisan.GetEnduranceStatus");
} }
public bool CraftItem(ushort recipeId, int quantity) public bool CraftItem(ushort recipeId, int quantity)
@ -31,4 +33,20 @@ internal sealed class ArtisanIpc
return false; return false;
} }
} }
/// <summary>
/// This ignores crafting lists, but we can't create/use those.
/// </summary>
public bool IsCrafting()
{
try
{
return _getEnduranceStatus.InvokeFunc();
}
catch (IpcError e)
{
_logger.LogError(e, "Unable to check for Artisan endurance status");
return false;
}
}
} }

View File

@ -401,6 +401,15 @@ internal sealed unsafe class GameFunctions
if (IsLoadingScreenVisible()) if (IsLoadingScreenVisible())
return true; return true;
if (_condition[ConditionFlag.Crafting])
{
if (!AgentRecipeNote.Instance()->IsAgentActive())
return true;
if (!_condition[ConditionFlag.PreparingToCraft])
return true;
}
return _condition[ConditionFlag.Occupied] || _condition[ConditionFlag.Occupied30] || return _condition[ConditionFlag.Occupied] || _condition[ConditionFlag.Occupied30] ||
_condition[ConditionFlag.Occupied33] || _condition[ConditionFlag.Occupied38] || _condition[ConditionFlag.Occupied33] || _condition[ConditionFlag.Occupied38] ||
_condition[ConditionFlag.Occupied39] || _condition[ConditionFlag.OccupiedInEvent] || _condition[ConditionFlag.Occupied39] || _condition[ConditionFlag.OccupiedInEvent] ||