PkmnLib.NET/PkmnLib.Dynamic/Models/BattleFlow/TargetResolver.cs

96 lines
3.5 KiB
C#
Raw Normal View History

2024-08-10 09:18:10 +00:00
using PkmnLib.Static.Moves;
namespace PkmnLib.Dynamic.Models.BattleFlow;
/// <summary>
/// Helper class for resolving the targets of a move.
/// </summary>
public static class TargetResolver
{
/// <summary>
/// Get the targets of a move based on the target type, and the selected side and position to target.
/// </summary>
public static IReadOnlyList<IPokemon?> ResolveTargets(IBattle battle, byte side, byte position, MoveTarget target)
{
return target switch
{
MoveTarget.Adjacent or MoveTarget.AdjacentAlly or MoveTarget.AdjacentAllySelf or MoveTarget.AdjacentOpponent
or MoveTarget.Any or MoveTarget.RandomOpponent
or MoveTarget.SelfUse => [battle.GetPokemon(side, position)],
MoveTarget.All => GetAllTargets(battle),
MoveTarget.AllAdjacentOpponent => GetAllAdjacentAndOpponent(battle, side, position),
MoveTarget.AllAdjacent => GetAllAdjacent(battle, side, position),
MoveTarget.AllAlly => battle.Sides[side].Pokemon.ToList(),
MoveTarget.AllOpponent => battle.Sides[GetOppositeSide(side)].Pokemon.ToList(),
_ => throw new ArgumentOutOfRangeException(nameof(target), target, null)
};
}
private static IReadOnlyList<IPokemon?> GetAllTargets(IBattle battle) =>
battle.Sides.SelectMany(x => x.Pokemon).ToList();
private static byte GetOppositeSide(byte side) => side == 0 ? (byte)1 : (byte)0;
/// <summary>
/// Gets all Pokémon that are adjacent to of directly opposite of a Pokémon. This means the target,
/// the Pokémon left of it, the Pokémon right of it, and the Pokémon opposite of it.
/// </summary>
private static IReadOnlyList<IPokemon?> GetAllAdjacentAndOpponent(IBattle battle, byte side, byte position)
{
var left = position - 1;
var right = position + 1;
if (left < 0 && right >= battle.PositionsPerSide)
{
return [battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position)];
}
if (left < 0)
{
return
[
battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position),
battle.GetPokemon(side, (byte)right)
];
}
if (right >= battle.PositionsPerSide)
{
return
[
battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position),
battle.GetPokemon(side, (byte)left)
];
}
return
[
battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position),
battle.GetPokemon(side, (byte)left), battle.GetPokemon(side, (byte)right)
];
}
private static IReadOnlyList<IPokemon?> GetAllAdjacent(IBattle battle, byte side, byte position)
{
var left = position - 1;
var right = position + 1;
if (left < 0 && right >= battle.PositionsPerSide)
{
return [battle.GetPokemon(side, position)];
}
if (left < 0)
{
return [battle.GetPokemon(side, position), battle.GetPokemon(side, (byte)right)];
}
if (right >= battle.PositionsPerSide)
{
return [battle.GetPokemon(side, position), battle.GetPokemon(side, (byte)left)];
}
return
[
battle.GetPokemon(side, position), battle.GetPokemon(side, (byte)left), battle.GetPokemon(side, (byte)right)
];
}
}