PkmnLibSharp/PkmnLibSharp/Battling/Battle/Battle.cs

246 lines
8.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using PkmnLibSharp.Battling.ChoiceTurn;
using PkmnLibSharp.Battling.Events;
using PkmnLibSharp.Battling.History;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class Battle : PointerWrapper
{
public Battle(BattleLibrary library, BattleParty[] parties, bool canFlee, byte numberOfSides, byte pokemonPerSide,
ulong randomSeed)
{
var ptr = IntPtr.Zero;
var arr = parties.Select(x => x.Ptr).ToArray();
Pkmnlib.Generated.Battle.Construct(ref ptr, library.Ptr, arr.ArrayPtr(), (ulong) arr.Length,
canFlee.ToNative(), numberOfSides, pokemonPerSide, randomSeed).Assert();
Initialize(ptr);
}
public BattleLibrary Library
{
get
{
if (_library != null) return _library;
var ptr = Creaturelib.Generated.Battle.GetLibrary(Ptr);
if (TryResolvePointer(ptr, out _library))
{
return _library!;
}
_library = new BattleLibrary(ptr);
return _library;
}
}
public BattleRandom Random
{
get
{
if (_random != null) return _random;
var ptr = Creaturelib.Generated.Battle.GetRandom(Ptr);
if (TryResolvePointer(ptr, out _random))
{
return _random!;
}
_random = new BattleRandom(ptr);
return _random;
}
}
public bool CanFlee => Creaturelib.Generated.Battle.CanFlee(Ptr) == 1;
public bool HasEnded => Creaturelib.Generated.Battle.HasEnded(Ptr) == 1;
public bool HasConclusiveResult => Creaturelib.Generated.Battle.HasConclusiveResult(Ptr) == 1;
public byte WinningSide => Creaturelib.Generated.Battle.GetWinningSide(Ptr);
public ulong SidesCount => Creaturelib.Generated.Battle.GetSidesCount(Ptr);
public ulong PartiesCount => Creaturelib.Generated.Battle.GetPartiesCount(Ptr);
public ulong MonsPerSide => Creaturelib.Generated.Battle.GetCreaturesPerSide(Ptr);
public long LastTurnTimeMicroseconds => Creaturelib.Generated.Battle.GetLastTurnTimeMicroseconds(Ptr);
public ReadOnlyNativePtrArray<BattleSide> Sides
{
get
{
if (_sides != null) return _sides;
var ptr = Creaturelib.Generated.Battle.GetSides(Ptr);
_sides = new ReadOnlyNativePtrArray<BattleSide>(ptr, (int) SidesCount, Constructor.GenericType.BattleSide);
return _sides;
}
}
public uint CurrentTurn => Creaturelib.Generated.Battle.GetCurrentTurn(Ptr);
public ReadOnlyNativePtrArray<BattleParty> Parties
{
get
{
if (_parties != null) return _parties;
var ptr = Creaturelib.Generated.Battle.GetParties(Ptr);
_parties = new ReadOnlyNativePtrArray<BattleParty>(ptr, (int) PartiesCount, Constructor.GenericType.BattleParty);
return _parties;
}
}
public string? WeatherName => Pkmnlib.Generated.Battle.GetWeatherName(Ptr).PtrString();
public HistoryHandler History
{
get
{
if (_history != null) return _history;
var ptr = Creaturelib.Generated.Battle.GetHistory(Ptr);
if (TryResolvePointer(ptr, out _history))
return _history!;
_history = new HistoryHandler(ptr);
return _history;
}
}
public bool CanUse(BaseTurnChoice turnChoice)
{
byte b = 0;
Creaturelib.Generated.Battle.CanUse(ref b, Ptr, turnChoice.Ptr).Assert();
return b == 1;
}
private readonly List<BaseTurnChoice> _choiceCache = new List<BaseTurnChoice>();
public bool TrySetChoice(BaseTurnChoice turnChoice)
{
byte b = 0;
var initialTurn = CurrentTurn;
_choiceCache.Add(turnChoice);
var t1 = System.Diagnostics.Stopwatch.StartNew();
Creaturelib.Generated.Battle.TrySetChoice(ref b, Ptr, turnChoice.Ptr).Assert();
t1.Stop();
if (b == 1 && CurrentTurn != initialTurn)
{
LogHandler.Log(LogHandler.LogLevel.Information,
$"Ran turn in {t1.ElapsedMilliseconds} ms, battle reported {LastTurnTimeMicroseconds} microseconds");
_choiceCache.Clear();
}
return b == 1;
}
public void EndBattle()
{
Creaturelib.Generated.Battle.EndBattle(Ptr).Assert();
}
public void CheckChoicesSetAndRun()
{
Creaturelib.Generated.Battle.CheckChoicesSetAndRun(Ptr);
}
public bool IsPokemonInField(Pokemon pokemon)
{
byte b = 0;
Creaturelib.Generated.Battle.CreatureInField(ref b, Ptr, pokemon.Ptr).Assert();
return b == 1;
}
public Pokemon GetPokemonInField(byte side, byte index)
{
var ptr = IntPtr.Zero;
Creaturelib.Generated.Battle.GetCreature(ref ptr, Ptr, side, index).Assert();
return TryResolvePointer(ptr, out Pokemon? pokemon) ? pokemon! : Constructor.Active.ConstructPokemon(ptr)!;
}
public void ForceRecall(byte side, byte index)
{
Creaturelib.Generated.Battle.ForceRecall(Ptr, side, index).Assert();
}
public void SwitchPokemon(byte side, byte index, Pokemon newPokemon)
{
Creaturelib.Generated.Battle.SwitchCreature(Ptr, side, index, newPokemon.Ptr).Assert();
}
public bool CanSlotBeFilled(byte side, byte index)
{
byte b = 0;
Creaturelib.Generated.Battle.CanSlotBeFilled(ref b, Ptr, side, index).Assert();
return b == 1;
}
public void ValidateBattleState()
{
Creaturelib.Generated.Battle.ValidateBattleState(Ptr).Assert();
}
public Script GetVolatileScript(string key)
{
var ptr = Creaturelib.Generated.Battle.GetVolatileScript(Ptr, key.ToPtr());
if (TryResolvePointer(ptr, out Script? script))
{
return script!;
}
// TODO: Handle with different script providers.
return new AngelscriptScript(ptr);
}
public void AddVolatileScript(string key)
{
Creaturelib.Generated.Battle.AddVolatileScriptByName(Ptr, key.ToPtr()).Assert();
}
public void AddVolatileScript(Script script)
{
Creaturelib.Generated.Battle.AddVolatileScript(Ptr, script.Ptr).Assert();
}
public void RemoveVolatileScript(string key)
{
Creaturelib.Generated.Battle.RemoveVolatileScript(Ptr, key.ToPtr()).Assert();
}
public void RemoveVolatileScript(Script script)
{
Creaturelib.Generated.Battle.RemoveVolatileScriptWithScript(Ptr, script.Ptr).Assert();
}
public bool HasVolatileScript(string key)
{
return Creaturelib.Generated.Battle.HasVolatileScript(Ptr, key.ToPtr()) == 1;
}
private List<BattleEventListener> _listeners = new List<BattleEventListener>();
public void RegisterEventListener(BattleEventListener listener)
{
_listeners.Add(listener);
Creaturelib.Generated.Battle.RegisterEventListener(Ptr, listener.FunctionPtr).Assert();
}
public void SetWeather(string weatherName)
{
Pkmnlib.Generated.Battle.SetWeather(Ptr, weatherName.ToPtr());
}
public void ClearWeather()
{
Pkmnlib.Generated.Battle.ClearWeather(Ptr);
}
private BattleLibrary? _library;
private BattleRandom? _random;
private ReadOnlyNativePtrArray<BattleSide>? _sides;
private ReadOnlyNativePtrArray<BattleParty>? _parties;
private HistoryHandler? _history;
protected override void DeletePtr()
{
Pkmnlib.Generated.Battle.Destruct(Ptr);
}
public override void Dispose()
{
if (!IsDeleted)
{
Creaturelib.Generated.Battle.ClearBattle(Ptr);
}
base.Dispose();
}
}
}