Lots more work on implementing battling
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
using PkmnLib.Dynamic.Models.Choices;
|
||||
using PkmnLib.Dynamic.ScriptHandling;
|
||||
|
||||
namespace PkmnLib.Dynamic.Models;
|
||||
|
||||
/// <summary>
|
||||
@@ -10,4 +13,86 @@ namespace PkmnLib.Dynamic.Models;
|
||||
/// </remarks>
|
||||
public class BattleChoiceQueue
|
||||
{
|
||||
private readonly ITurnChoice?[] _choices;
|
||||
private int _currentIndex;
|
||||
|
||||
/// <inheritdoc cref="BattleChoiceQueue"/>
|
||||
public BattleChoiceQueue(ITurnChoice[] choices)
|
||||
{
|
||||
_choices = choices;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dequeues the next turn choice to be executed. This gives back the choice and sets it to null in the queue. It
|
||||
/// also increments the internal index.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ITurnChoice? Dequeue()
|
||||
{
|
||||
if (_currentIndex >= _choices.Length)
|
||||
return null;
|
||||
|
||||
var choice = _choices[_currentIndex];
|
||||
_choices[_currentIndex] = null;
|
||||
_currentIndex++;
|
||||
return choice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This reads what the next choice to execute will be, without modifying state.
|
||||
/// </summary>
|
||||
public ITurnChoice? Peek() => _currentIndex >= _choices.Length ? null : _choices[_currentIndex];
|
||||
|
||||
/// <summary>
|
||||
/// Checks if there are any more choices to execute.
|
||||
/// </summary>
|
||||
public bool HasNext() => _currentIndex < _choices.Length;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This resorts the yet to be executed choices. This can be useful for dealing with situations
|
||||
/// such as Pokémon changing forms just after the very start of a turn, when turn order has
|
||||
/// technically already been decided.
|
||||
/// </summary>
|
||||
public void Resort()
|
||||
{
|
||||
var length = _choices.Length;
|
||||
var currentIndex = _currentIndex;
|
||||
|
||||
for (var i = currentIndex; i < length; i++)
|
||||
{
|
||||
var choice = _choices[i];
|
||||
if (choice == null)
|
||||
continue;
|
||||
// Ensure that the speed is up to date
|
||||
var speed = choice.User.BoostedStats.Speed;
|
||||
choice.User.RunScriptHook(script => script.ChangeSpeed(choice, ref speed));
|
||||
choice.Speed = speed;
|
||||
}
|
||||
|
||||
// We only sort the choices that are left
|
||||
Array.Sort(_choices, currentIndex, length - currentIndex, TurnChoiceComparer.Instance!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This moves the choice of a specific Pokémon up to the next choice to be executed.
|
||||
/// </summary>
|
||||
public bool MovePokemonChoiceNext(IPokemon pokemon)
|
||||
{
|
||||
var index = Array.FindIndex(_choices, _currentIndex, choice => choice?.User == pokemon);
|
||||
if (index == -1)
|
||||
return false;
|
||||
if (index == _currentIndex)
|
||||
return true;
|
||||
var choice = _choices[index];
|
||||
_choices[index] = null;
|
||||
// Push all choices back
|
||||
for (var i = index; i > _currentIndex; i--)
|
||||
_choices[i] = _choices[i - 1];
|
||||
// And insert the choice at the front
|
||||
_choices[_currentIndex] = choice;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal IReadOnlyList<ITurnChoice?> GetChoices() => _choices;
|
||||
}
|
||||
Reference in New Issue
Block a user