Lots more work on implementing battling
This commit is contained in:
@@ -217,7 +217,7 @@ public interface IPokemon : IScriptSource
|
||||
/// <param name="stat">The stat to be changed</param>
|
||||
/// <param name="change">The amount to change the stat by</param>
|
||||
/// <param name="selfInflicted">Whether the change was self-inflicted. This can be relevant in scripts.</param>
|
||||
void ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted);
|
||||
bool ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the currently active ability.
|
||||
@@ -283,6 +283,27 @@ public interface IPokemon : IScriptSource
|
||||
/// </summary>
|
||||
void ChangeLevelBy(int change);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current battle the Pokémon is in.
|
||||
/// </summary>
|
||||
void SetBattleData(IBattle battle, byte sideIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether the Pokémon is on the battlefield.
|
||||
/// </summary>
|
||||
void SetOnBattlefield(bool onBattleField);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position the Pokémon has within its side.
|
||||
/// </summary>
|
||||
/// <param name="position"></param>
|
||||
void SetBattleSidePosition(byte position);
|
||||
|
||||
/// <summary>
|
||||
/// Marks a Pokemon as seen in the battle.
|
||||
/// </summary>
|
||||
void MarkOpponentAsSeen(IPokemon pokemon);
|
||||
|
||||
// TODO: (de)serialize
|
||||
}
|
||||
|
||||
@@ -295,25 +316,35 @@ public interface IPokemonBattleData
|
||||
/// <summary>
|
||||
/// The battle the Pokemon is in.
|
||||
/// </summary>
|
||||
IBattle Battle { get; }
|
||||
IBattle Battle { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The index of the side of the Pokemon
|
||||
/// </summary>
|
||||
byte SideIndex { get; }
|
||||
byte SideIndex { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The index of the position of the Pokemon on the field
|
||||
/// </summary>
|
||||
byte Position { get; }
|
||||
byte Position { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of opponents the Pokemon has seen this battle.
|
||||
/// </summary>
|
||||
IReadOnlyList<IPokemon> SeenOpponents { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the Pokemon is on the battlefield.
|
||||
/// </summary>
|
||||
bool IsOnBattlefield { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds an opponent to the list of seen opponents.
|
||||
/// </summary>
|
||||
void MarkOpponentAsSeen(IPokemon opponent);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <inheritdoc cref="IPokemon"/>
|
||||
public class PokemonImpl : ScriptSource, IPokemon
|
||||
{
|
||||
/// <inheritdoc cref="PokemonImpl"/>
|
||||
@@ -358,7 +389,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
public IForm? DisplayForm { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public LevelInt Level { get; }
|
||||
public LevelInt Level { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public uint Experience { get; }
|
||||
@@ -468,13 +499,42 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
/// <inheritdoc />
|
||||
public bool ConsumeHeldItem()
|
||||
{
|
||||
if (HeldItem is null)
|
||||
return false;
|
||||
if (!Library.ScriptResolver.TryResolveItemScript(HeldItem, out _))
|
||||
return false;
|
||||
// TODO: actually consume the item
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted)
|
||||
public bool ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var prevented = false;
|
||||
this.RunScriptHook(script => script.PreventStatBoostChange(this, stat, change, selfInflicted, ref prevented));
|
||||
if (prevented)
|
||||
return false;
|
||||
this.RunScriptHook(script => script.ChangeStatBoostChange(this, stat, selfInflicted, ref change));
|
||||
if (change == 0)
|
||||
return false;
|
||||
var changed = false;
|
||||
var oldBoost = StatBoost.GetStatistic(stat);
|
||||
changed = change switch
|
||||
{
|
||||
> 0 => StatBoost.IncreaseStatistic(stat, change),
|
||||
< 0 => StatBoost.DecreaseStatistic(stat, change),
|
||||
_ => changed
|
||||
};
|
||||
if (!changed)
|
||||
return false;
|
||||
if (BattleData != null)
|
||||
{
|
||||
var newBoost = StatBoost.GetStatistic(stat);
|
||||
BattleData.Battle.EventHook.Invoke(new StatBoostEvent(this, stat, oldBoost, newBoost));
|
||||
}
|
||||
|
||||
RecalculateBoostedStats();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -499,10 +559,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RecalculateBoostedStats()
|
||||
{
|
||||
Library.StatCalculator.CalculateBoostedStats(this, BoostedStats);
|
||||
}
|
||||
public void RecalculateBoostedStats() => Library.StatCalculator.CalculateBoostedStats(this, BoostedStats);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ChangeSpecies(ISpecies species, IForm form)
|
||||
@@ -612,6 +669,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= Moves.Count)
|
||||
throw new InvalidOperationException("No empty move slot found.");
|
||||
if (!Library.StaticLibrary.Moves.TryGet(moveName, out var move))
|
||||
@@ -621,17 +679,57 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearStatus()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public void ClearStatus() => StatusScript.Clear();
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ChangeLevelBy(int change)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var newLevel = Level + change;
|
||||
Level = (LevelInt)Math.Clamp(newLevel, 1, Library.StaticLibrary.Settings.MaxLevel);
|
||||
RecalculateFlatStats();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetBattleData(IBattle battle, byte sideIndex)
|
||||
{
|
||||
if (BattleData is not null)
|
||||
{
|
||||
BattleData.Battle = battle;
|
||||
BattleData.SideIndex = sideIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
BattleData = new PokemonBattleDataImpl(battle, sideIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetOnBattlefield(bool onBattleField)
|
||||
{
|
||||
if (BattleData is not null)
|
||||
{
|
||||
BattleData.IsOnBattlefield = onBattleField;
|
||||
if (!onBattleField)
|
||||
{
|
||||
Volatile.Clear();
|
||||
WeightInKm = Form.Weight;
|
||||
HeightInMeters = Form.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetBattleSidePosition(byte position)
|
||||
{
|
||||
if (BattleData is not null)
|
||||
{
|
||||
BattleData.Position = position;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void MarkOpponentAsSeen(IPokemon pokemon) => BattleData?.MarkOpponentAsSeen(pokemon);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int ScriptCount
|
||||
{
|
||||
@@ -667,4 +765,37 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
side.CollectScripts(scripts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public class PokemonBattleDataImpl : IPokemonBattleData
|
||||
{
|
||||
/// <inheritdoc cref="PokemonBattleDataImpl"/>
|
||||
public PokemonBattleDataImpl(IBattle battle, byte sideIndex)
|
||||
{
|
||||
Battle = battle;
|
||||
SideIndex = sideIndex;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IBattle Battle { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte SideIndex { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte Position { get; set; }
|
||||
|
||||
private readonly List<IPokemon> _seenOpponents = [];
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<IPokemon> SeenOpponents => _seenOpponents;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsOnBattlefield { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void MarkOpponentAsSeen(IPokemon opponent)
|
||||
{
|
||||
_seenOpponents.Add(opponent);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user