//
// CombatState.cs
//
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Diagnostics.CodeAnalysis;
using NosSmooth.Core.Client;
using NosSmooth.Extensions.Combat.Operations;
namespace NosSmooth.Extensions.Combat;
///
internal class CombatState : ICombatState
{
private readonly Dictionary> _operations;
private readonly Dictionary _currentOperations;
///
/// Initializes a new instance of the class.
///
/// The NosTale client.
/// The game.
/// The combat manager.
public CombatState(ManagedNostaleClient client, Game.Game game, CombatManager combatManager)
{
Client = client;
Game = game;
CombatManager = combatManager;
_operations = new Dictionary>();
_currentOperations = new Dictionary();
}
///
/// Gets whether the combat state should be quit.
///
public bool ShouldQuit { get; private set; }
///
public CombatManager CombatManager { get; }
///
public Game.Game Game { get; }
///
public ManagedNostaleClient Client { get; }
///
/// Gets whether the manager may currently quit.
///
///
/// Used for finishing the current operations.
///
public bool CanQuit => _currentOperations.Values.All(x => !x.IsExecuting() || x.IsFinished());
///
public bool IsWaitingOnOperation => _currentOperations.Any(x => !x.Value.IsExecuting());
///
/// Move to next operation, if available.
///
/// The queue type to move to next operation in.
/// Next operation, if any.
public ICombatOperation? NextOperation(OperationQueueType queueType)
{
if (_operations.ContainsKey(queueType))
{
var nextOperation = _operations[queueType].FirstOrDefault();
if (nextOperation is not null)
{
_operations[queueType].RemoveFirst();
_currentOperations[queueType] = nextOperation;
return nextOperation;
}
}
return null;
}
///
public IReadOnlyList GetWaitingForOperations()
{
return _currentOperations.Values.Where(x => !x.IsExecuting()).ToList();
}
///
public ICombatOperation? RemoveCurrentOperation(OperationQueueType queueType, bool emptyQueue = false)
{
if (emptyQueue && _operations.TryGetValue(queueType, out var queue))
{
queue.Clear();
}
if (_currentOperations.TryGetValue(queueType, out var operation))
{
operation.Dispose();
_currentOperations.Remove(queueType);
return operation;
}
return null;
}
///
public ICombatOperation? GetCurrentOperation(OperationQueueType queueType)
=> _currentOperations.GetValueOrDefault(queueType);
///
public bool IsExecutingOperation(OperationQueueType queueType, [NotNullWhen(true)] out ICombatOperation? operation)
{
operation = GetCurrentOperation(queueType);
return operation is not null && operation.IsExecuting();
}
///
public void QuitCombat()
{
ShouldQuit = true;
}
///
public void SetCurrentOperation
(ICombatOperation operation, bool emptyQueue = false, bool prependCurrentOperationToQueue = false)
{
var type = operation.QueueType;
if (!_operations.ContainsKey(type))
{
_operations[type] = new LinkedList();
}
if (emptyQueue)
{
_operations[type].Clear();
}
if (prependCurrentOperationToQueue)
{
_operations[type].AddFirst(operation);
return;
}
if (_currentOperations.ContainsKey(type))
{
_currentOperations[type].Dispose();
}
_currentOperations[type] = operation;
}
///
public void EnqueueOperation(ICombatOperation operation)
{
var type = operation.QueueType;
if (!_operations.ContainsKey(type))
{
_operations[type] = new LinkedList();
}
_operations[type].AddLast(operation);
}
///
public void RemoveOperations(Func filter)
{
throw new NotImplementedException();
}
}