Lots more work on implementing battling
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using PkmnLib.Dynamic.Events;
|
||||
using PkmnLib.Dynamic.Models.Choices;
|
||||
using PkmnLib.Dynamic.ScriptHandling;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Dynamic.Models;
|
||||
|
||||
@@ -59,7 +61,7 @@ public interface IBattleSide : IScriptSource
|
||||
/// responsible for them. Returns false if all slots are filled with usable pokemon, or slots are
|
||||
/// empty, but can't be filled by any party anymore.
|
||||
/// </summary>
|
||||
void AllPositionsFilled();
|
||||
bool AllPositionsFilled();
|
||||
|
||||
/// <summary>
|
||||
/// Sets a choice for a Pokémon on this side.
|
||||
@@ -70,11 +72,12 @@ public interface IBattleSide : IScriptSource
|
||||
/// Resets all choices on this side.
|
||||
/// </summary>
|
||||
void ResetChoices();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Forcibly removes a Pokémon from the field.
|
||||
/// </summary>
|
||||
void ForceClearPokemonFromField();
|
||||
/// <param name="index"></param>
|
||||
void ForceClearPokemonFromField(byte index);
|
||||
|
||||
/// <summary>
|
||||
/// Switches out a spot on the field for a different Pokémon. If null is passed, the spot is
|
||||
@@ -117,4 +120,168 @@ public interface IBattleSide : IScriptSource
|
||||
/// Gets a random Pokémon on the given side.
|
||||
/// </summary>
|
||||
byte GetRandomPosition();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBattleSide"/>
|
||||
public class BattleSideImpl : ScriptSource, IBattleSide
|
||||
{
|
||||
/// <inheritdoc cref="BattleSideImpl"/>
|
||||
public BattleSideImpl(byte index, byte numberOfPositions, IBattle battle)
|
||||
{
|
||||
Index = index;
|
||||
NumberOfPositions = numberOfPositions;
|
||||
_pokemon = new IPokemon?[numberOfPositions];
|
||||
_setChoices = new ITurnChoice?[numberOfPositions];
|
||||
_fillablePositions = new bool[numberOfPositions];
|
||||
Battle = battle;
|
||||
VolatileScripts = new ScriptSet();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte Index { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte NumberOfPositions { get; }
|
||||
|
||||
private readonly IPokemon?[] _pokemon;
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<IPokemon?> Pokemon => _pokemon;
|
||||
|
||||
private readonly ITurnChoice?[] _setChoices;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<ITurnChoice?> SetChoices => _setChoices;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool AllChoicesSet => _setChoices.All(choice => choice is not null);
|
||||
|
||||
private readonly bool[] _fillablePositions;
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<bool> FillablePositions => _fillablePositions;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IBattle Battle { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasFledBattle { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IScriptSet VolatileScripts { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool AllPositionsFilled()
|
||||
{
|
||||
for (byte i = 0; i < NumberOfPositions; i++)
|
||||
{
|
||||
var pokemon = Pokemon[i];
|
||||
var isPokemonViable = pokemon is not null && pokemon.IsUsable;
|
||||
// If the Pokémon is not valid, but the slot can be filled, return false.
|
||||
if (!isPokemonViable && Battle.CanSlotBeFilled(Index, i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetChoice(byte position, ITurnChoice choice)
|
||||
{
|
||||
_setChoices[position] = choice;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ResetChoices()
|
||||
{
|
||||
for (byte i = 0; i < NumberOfPositions; i++)
|
||||
{
|
||||
_setChoices[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <param name="index"></param>
|
||||
/// <inheritdoc />
|
||||
public void ForceClearPokemonFromField(byte index)
|
||||
{
|
||||
_pokemon[index] = null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPokemon? SwapPokemon(byte position, IPokemon? pokemon)
|
||||
{
|
||||
var oldPokemon = _pokemon[position];
|
||||
if (oldPokemon is not null)
|
||||
{
|
||||
oldPokemon.RunScriptHook(script => script.OnRemove());
|
||||
oldPokemon.SetOnBattlefield(false);
|
||||
}
|
||||
_pokemon[position] = pokemon;
|
||||
if (pokemon is not null)
|
||||
{
|
||||
pokemon.SetBattleData(Battle, Index);
|
||||
pokemon.SetOnBattlefield(true);
|
||||
pokemon.SetBattleSidePosition(position);
|
||||
foreach (var side in Battle.Sides)
|
||||
{
|
||||
if (side == this)
|
||||
continue;
|
||||
foreach (var opponent in side.Pokemon.WhereNotNull())
|
||||
{
|
||||
opponent.MarkOpponentAsSeen(pokemon);
|
||||
pokemon.MarkOpponentAsSeen(opponent);
|
||||
}
|
||||
}
|
||||
Battle.EventHook.Invoke(new SwitchEvent(Index, position, pokemon));
|
||||
pokemon.RunScriptHook(script => script.OnSwitchIn(pokemon));
|
||||
}
|
||||
else
|
||||
{
|
||||
Battle.EventHook.Invoke(new SwitchEvent(Index, position, null));
|
||||
}
|
||||
|
||||
return oldPokemon;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SwapPokemon(byte position1, byte position2)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPokemonOnSide(IPokemon pokemon) => _pokemon.Contains(pokemon);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void MarkPositionAsUnfillable(byte position) => _fillablePositions[position] = false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPositionFillable(byte position) => _fillablePositions[position];
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsDefeated()
|
||||
{
|
||||
return _fillablePositions.All(fillable => !fillable);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void MarkAsFled() => HasFledBattle = true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte GetRandomPosition() => (byte)Battle.Random.GetInt(0, NumberOfPositions);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int ScriptCount => 1 + Battle.ScriptCount;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void GetOwnScripts(List<IEnumerable<ScriptContainer>> scripts)
|
||||
{
|
||||
scripts.Add(VolatileScripts);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void CollectScripts(List<IEnumerable<ScriptContainer>> scripts)
|
||||
{
|
||||
scripts.Add(VolatileScripts);
|
||||
Battle.CollectScripts(scripts);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user