Move all battle state from IPokemon to an ephemeral IBattlePokemon wrapper
This commit is contained in:
@@ -92,7 +92,7 @@ public interface IBattle : IScriptSource, IDeepCloneable, IDisposable
|
||||
/// <summary>
|
||||
/// Get a Pokemon on the battlefield, on a specific side and an index on that side.
|
||||
/// </summary>
|
||||
IPokemon? GetPokemon(byte side, byte position);
|
||||
IBattlePokemon? GetPokemon(byte side, byte position);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a slot on the battlefield can still be filled. If no party is responsible
|
||||
@@ -116,7 +116,7 @@ public interface IBattle : IScriptSource, IDeepCloneable, IDisposable
|
||||
/// Checks whether a Pokemon has a forced turn choice. If it does, this returns true and the choice
|
||||
/// is set in the out parameter. If it does not, this returns false and the out parameter is null.
|
||||
/// </summary>
|
||||
bool HasForcedTurn(IPokemon pokemon, [NotNullWhen(true)] out ITurnChoice? choice);
|
||||
bool HasForcedTurn(IBattlePokemon pokemon, [NotNullWhen(true)] out ITurnChoice? choice);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a choice is actually possible.
|
||||
@@ -202,6 +202,8 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
Sides = sides;
|
||||
Random = randomSeed.HasValue ? new BattleRandomImpl(randomSeed.Value) : new BattleRandomImpl();
|
||||
EventHook = new EventHook();
|
||||
foreach (var party in parties)
|
||||
party.Initialize(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -248,12 +250,22 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
public BattleChoiceQueue? ChoiceQueue { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPokemon? GetPokemon(byte side, byte position) => Sides[side].Pokemon[position];
|
||||
public IBattlePokemon? GetPokemon(byte side, byte position) => Sides[side].Pokemon[position];
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanSlotBeFilled(byte side, byte position) => Parties.Any(x =>
|
||||
x.IsResponsibleForIndex(new ResponsibleIndex(side, position)) && x.HasUsablePokemonNotInField());
|
||||
|
||||
private readonly List<IPokemon> _capturedPokemon = [];
|
||||
|
||||
/// <summary>
|
||||
/// Attaches battle-wide result data, such as the captured Pokémon, to a result.
|
||||
/// </summary>
|
||||
private BattleResult FinalizeResult(BattleResult result) => result with
|
||||
{
|
||||
CapturedPokemon = _capturedPokemon.ToList(),
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ValidateBattleState()
|
||||
{
|
||||
@@ -265,7 +277,7 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
{
|
||||
if (side.HasFledBattle)
|
||||
{
|
||||
Result = BattleResult.Inconclusive;
|
||||
Result = FinalizeResult(BattleResult.Inconclusive);
|
||||
HasEnded = true;
|
||||
return;
|
||||
}
|
||||
@@ -283,13 +295,13 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
// If every side is defeated, the battle is a draw
|
||||
if (!survivingSideExists)
|
||||
{
|
||||
Result = BattleResult.Inconclusive;
|
||||
Result = FinalizeResult(BattleResult.Inconclusive);
|
||||
HasEnded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// If only one side is left, that side has won
|
||||
Result = BattleResult.Conclusive(survivingSide!.Index);
|
||||
Result = FinalizeResult(BattleResult.Conclusive(survivingSide!.Index));
|
||||
HasEnded = true;
|
||||
}
|
||||
|
||||
@@ -297,22 +309,15 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
public void ForceEndBattle()
|
||||
{
|
||||
HasEnded = true;
|
||||
Result = BattleResult.Inconclusive;
|
||||
Result = FinalizeResult(BattleResult.Inconclusive);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasForcedTurn(IPokemon pokemon, [NotNullWhen(true)] out ITurnChoice? choice)
|
||||
public bool HasForcedTurn(IBattlePokemon pokemon, [NotNullWhen(true)] out ITurnChoice? choice)
|
||||
{
|
||||
var battleData = pokemon.BattleData;
|
||||
if (battleData == null)
|
||||
{
|
||||
choice = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ITurnChoice? forcedChoice = null;
|
||||
pokemon.RunScriptHook<IScriptForceTurnSelection>(script =>
|
||||
script.ForceTurnSelection(this, battleData.SideIndex, battleData.Position, ref forcedChoice));
|
||||
script.ForceTurnSelection(this, pokemon.SideIndex, pokemon.Position, ref forcedChoice));
|
||||
choice = forcedChoice;
|
||||
return choice != null;
|
||||
}
|
||||
@@ -346,7 +351,7 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
if (!switchChoice.SwitchTo.IsUsable)
|
||||
return false;
|
||||
// Can't switch to a Pokémon already on the field
|
||||
if (switchChoice.SwitchTo.BattleData is { IsOnBattlefield: true })
|
||||
if (switchChoice.SwitchTo.IsOnBattlefield)
|
||||
return false;
|
||||
if (switchChoice.SwitchTo == switchChoice.User)
|
||||
return false;
|
||||
@@ -389,10 +394,10 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
{
|
||||
if (!CanUse(choice))
|
||||
return false;
|
||||
if (choice.User.BattleData?.IsOnBattlefield != true)
|
||||
if (!choice.User.IsOnBattlefield)
|
||||
return false;
|
||||
var side = Sides[choice.User.BattleData!.SideIndex];
|
||||
side.SetChoice(choice.User.BattleData!.Position, choice);
|
||||
var side = Sides[choice.User.SideIndex];
|
||||
side.SetChoice(choice.User.Position, choice);
|
||||
CheckChoicesSetAndRun();
|
||||
return true;
|
||||
}
|
||||
@@ -555,8 +560,8 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
if (attemptCapture.IsCaught)
|
||||
{
|
||||
target.MarkAsCaught();
|
||||
var side = Sides[target.BattleData!.SideIndex];
|
||||
side.ForceClearPokemonFromField(target.BattleData.Position);
|
||||
_capturedPokemon.Add(target.UnderlyingPokemon);
|
||||
target.BattleSide.ForceClearPokemonFromField(target.Position);
|
||||
}
|
||||
EventHook.Invoke(new CaptureAttemptEvent(target, attemptCapture, item));
|
||||
|
||||
@@ -592,9 +597,9 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
{
|
||||
foreach (var party in Parties)
|
||||
{
|
||||
foreach (var pokemon in party.Party.WhereNotNull())
|
||||
foreach (var pokemon in party.BattlePokemon.WhereNotNull())
|
||||
{
|
||||
pokemon.ClearBattleData();
|
||||
pokemon.OnBattleEnd();
|
||||
}
|
||||
}
|
||||
_weatherScript.Clear();
|
||||
|
||||
Reference in New Issue
Block a user