Support for battle event listeners.

This commit is contained in:
Deukhoofd 2020-08-04 17:32:20 +02:00
parent 00c5f51c55
commit b0dea8b6e7
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
19 changed files with 201 additions and 39 deletions

View File

@ -65,6 +65,8 @@ namespace PkmnLibSharp.Battling
return _sides;
}
}
public uint CurrentTurn => Creaturelib.Generated.Battle.GetCurrentTurn(Ptr);
public ReadOnlyNativePtrArray<BattleParty> Parties
{
@ -175,12 +177,7 @@ namespace PkmnLibSharp.Battling
{
Creaturelib.Generated.Battle.RegisterEventListener(Ptr, listener.FunctionPtr).Assert();
}
public void TriggerEventListener(BattleEvent evt)
{
Creaturelib.Generated.Battle.TriggerEventListener(Ptr, evt.Ptr).Assert();
}
public void SetWeather(string weatherName)
{
Pkmnlib.Generated.Battle.SetWeather(Ptr, weatherName.ToPtr());

View File

@ -1,11 +0,0 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling.Events
{
public abstract class BattleEvent : PointerWrapper
{
protected internal BattleEvent(IntPtr ptr) : base(ptr)
{}
}
}

View File

@ -1,12 +1,11 @@
using System;
using System.Runtime.InteropServices;
using Creaturelib;
namespace PkmnLibSharp.Battling.Events
{
public class BattleEventListener
{
public delegate void BattleEventDelegate(BattleEvent evt);
public delegate void BattleEventDelegate(EventData evt);
private delegate void BattleEventPtrDelegate(IntPtr ptr);
private readonly BattleEventDelegate _del;
@ -27,20 +26,23 @@ namespace PkmnLibSharp.Battling.Events
_del.Invoke(wrapped);
}
private static BattleEvent WrapEventPtr(IntPtr ptr)
private static EventData WrapEventPtr(IntPtr ptr)
{
var evtType = Creaturelib.Generated.EventData.GetKind(ptr);
var evtType = (EventDataKind)Creaturelib.Generated.EventData.GetKind(ptr);
switch (evtType)
{
case EventDataKind.Damage:
return new DamageEvent(ptr);
return new DamageEvent(evtType, ptr);
case EventDataKind.Heal:
break;
case EventDataKind.Faint:
break;
case EventDataKind.DisplayText:
break;
default:
break;
}
Creaturelib.Generated.EventData.Destruct(ptr);
throw new NotImplementedException($"Unhandled battle event: '{evtType}'");
}
}

View File

@ -2,15 +2,34 @@ using System;
namespace PkmnLibSharp.Battling.Events
{
public class DamageEvent : BattleEvent
public class DamageEvent : EventData
{
internal DamageEvent(IntPtr ptr) : base(ptr)
internal DamageEvent(EventDataKind kind, IntPtr ptr) : base(kind, ptr)
{
}
public Pokemon Pokemon
{
get
{
if (_pokemon != null) return _pokemon;
var ptr = Creaturelib.Generated.DamageEvent.GetCreature(Ptr);
if (TryResolvePointer(ptr, out _pokemon))
return _pokemon;
_pokemon = new Pokemon(ptr);
return _pokemon;
}
}
public DamageSource Source => (DamageSource) Creaturelib.Generated.DamageEvent.GetDamageSource(Ptr);
public uint OriginalHealth => Creaturelib.Generated.DamageEvent.GetOriginalHealth(Ptr);
public uint NewHealth => Creaturelib.Generated.DamageEvent.GetNewHealth(Ptr);
private Pokemon _pokemon;
protected override void DeletePtr()
{
throw new NotImplementedException();
Creaturelib.Generated.DamageEvent.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling.Events
{
public abstract class EventData : PointerWrapper
{
protected internal EventData(EventDataKind kind, IntPtr ptr) : base(ptr)
{
Kind = kind;
}
public EventDataKind Kind { get; }
}
}

View File

@ -0,0 +1,10 @@
namespace PkmnLibSharp.Battling.Events
{
public enum EventDataKind : byte
{
Damage = 0,
Heal = 1,
Faint = 2,
DisplayText = 3,
}
}

View File

@ -0,0 +1,32 @@
using System;
namespace PkmnLibSharp.Battling.Events
{
public class FaintEvent : EventData
{
internal FaintEvent(EventDataKind kind, IntPtr ptr) : base(kind, ptr)
{
}
Pokemon Pokemon
{
get
{
if (_pokemon != null) return _pokemon;
var ptr = Creaturelib.Generated.DamageEvent.GetCreature(Ptr);
if (TryResolvePointer(ptr, out _pokemon))
return _pokemon;
_pokemon = new Pokemon(ptr);
return _pokemon;
}
}
private Pokemon _pokemon;
protected override void DeletePtr()
{
Creaturelib.Generated.FaintEvent.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,34 @@
using System;
namespace PkmnLibSharp.Battling.Events
{
public class HealEvent : EventData
{
internal HealEvent(EventDataKind kind, IntPtr ptr) : base(kind, ptr)
{
}
public Pokemon Pokemon
{
get
{
if (_pokemon != null) return _pokemon;
var ptr = Creaturelib.Generated.HealEvent.GetCreature(Ptr);
if (TryResolvePointer(ptr, out _pokemon))
return _pokemon;
_pokemon = new Pokemon(ptr);
return _pokemon;
}
}
public uint OriginalHealth => Creaturelib.Generated.HealEvent.GetOriginalHealth(Ptr);
public uint NewHealth => Creaturelib.Generated.HealEvent.GetNewHealth(Ptr);
private Pokemon _pokemon;
protected override void DeletePtr()
{
Creaturelib.Generated.HealEvent.Destruct(Ptr);
}
}
}

View File

@ -52,6 +52,11 @@ namespace Creaturelib.Generated
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_Battle_CheckChoicesSetAndRun")]
internal static extern byte CheckChoicesSetAndRun(IntPtr p);
/// <param name="p">Battle *</param>
/// <returns>unsigned int</returns>
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_Battle_GetCurrentTurn")]
internal static extern uint GetCurrentTurn(IntPtr p);
/// <param name="p">const Battle *</param>
/// <returns>ChoiceQueue *</returns>
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_Battle_GetCurrentTurnQueue")]
@ -182,11 +187,5 @@ namespace Creaturelib.Generated
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_Battle_RegisterEventListener")]
internal static extern byte RegisterEventListener(IntPtr p, IntPtr func);
/// <param name="p">Battle *</param>
/// <param name="data">EventData *</param>
/// <returns>unsigned char</returns>
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_Battle_TriggerEventListener")]
internal static extern byte TriggerEventListener(IntPtr p, IntPtr data);
}
}

View File

@ -26,5 +26,10 @@ namespace Creaturelib.Generated
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_DamageEvent_GetNewHealth")]
internal static extern uint GetNewHealth(IntPtr p);
/// <param name="p">const DamageEvent *</param>
/// <returns>void</returns>
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_DamageEvent_Destruct")]
internal static extern void Destruct(IntPtr p);
}
}

View File

@ -11,5 +11,10 @@ namespace Creaturelib.Generated
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_DisplayTextEvent_GetText")]
internal static extern IntPtr GetText(IntPtr p);
/// <param name="p">const DisplayTextEvent *</param>
/// <returns>void</returns>
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_DisplayTextEvent_Destruct")]
internal static extern void Destruct(IntPtr p);
}
}

View File

@ -11,5 +11,10 @@ namespace Creaturelib.Generated
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_FaintEvent_GetCreature")]
internal static extern IntPtr GetCreature(IntPtr p);
/// <param name="p">const FaintEvent *</param>
/// <returns>void</returns>
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_FaintEvent_Destruct")]
internal static extern void Destruct(IntPtr p);
}
}

View File

@ -21,5 +21,10 @@ namespace Creaturelib.Generated
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_HealEvent_GetNewHealth")]
internal static extern uint GetNewHealth(IntPtr p);
/// <param name="p">const HealEvent *</param>
/// <returns>void</returns>
[DllImport("CreatureLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_HealEvent_Destruct")]
internal static extern void Destruct(IntPtr p);
}
}

View File

@ -6,6 +6,6 @@ namespace Pkmnlib
[SuppressMessage("ReSharper", "InconsistentNaming")]
internal enum PkmnEventDataKind : byte
{
WeatherChange = 4,
WeatherChange = 128,
}
}

BIN
PkmnLibSharp/Native/libCreatureLib.so (Stored with Git LFS)

Binary file not shown.

BIN
PkmnLibSharp/Native/libpkmnLib.so (Stored with Git LFS)

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using PkmnLibSharp.Battling;
using PkmnLibSharp.Battling.ChoiceTurn;
using PkmnLibSharp.Battling.Events;
namespace PkmnLibSharpTests.Battling.BattleTests
{
@ -60,13 +63,55 @@ namespace PkmnLibSharpTests.Battling.BattleTests
battle.SwitchPokemon(0, 0, p1.GetAtIndex(0));
battle.SwitchPokemon(1, 0, p2.GetAtIndex(0));
Assert.AreEqual(0, battle.CurrentTurn);
var moveTurn1 = new MoveTurnChoice(p1.GetAtIndex(0), p1.GetAtIndex(0).Moves[0], 1, 0 );
var moveTurn2 = new MoveTurnChoice(p2.GetAtIndex(0), p2.GetAtIndex(0).Moves[0], 0, 0 );
Assert.That(battle.TrySetChoice(moveTurn1));
Assert.That(battle.TrySetChoice(moveTurn2));
Assert.AreEqual(battle.CurrentTurn, 1);
battle.Dispose();
}
[Test]
public void EventListener()
{
var lib = BattleLibraryHelper.GetLibrary();
var p1 = BuildTestParty(lib);
var p2 = BuildTestParty(lib);
var battle =
new BattleBuilder(lib, true, 2, 1)
.WithPartyOnPositions(p1, new BattlePosition(0, 0))
.WithPartyOnPositions(p2, new BattlePosition(1, 0))
.WithRandomSeed(20)
.Build();
var evts = new List<EventData>();
battle.RegisterEventListener(new BattleEventListener(evt =>
{
evts.Add(evt);
}));
battle.SwitchPokemon(0, 0, p1.GetAtIndex(0));
battle.SwitchPokemon(1, 0, p2.GetAtIndex(0));
Assert.AreEqual(0, battle.CurrentTurn);
var moveTurn1 = new MoveTurnChoice(p1.GetAtIndex(0), p1.GetAtIndex(0).Moves[0], 1, 0 );
var moveTurn2 = new MoveTurnChoice(p2.GetAtIndex(0), p2.GetAtIndex(0).Moves[0], 0, 0 );
Assert.That(battle.TrySetChoice(moveTurn1));
Assert.That(battle.TrySetChoice(moveTurn2));
Assert.AreEqual(1, battle.CurrentTurn);
var damageEvents = evts.Where(x => x.Kind == EventDataKind.Damage).Cast<DamageEvent>().ToArray();
Assert.AreEqual(2, damageEvents.Length);
Assert.AreEqual(damageEvents[0].Pokemon, p2.GetAtIndex(0));
Assert.AreEqual(damageEvents[1].Pokemon, p1.GetAtIndex(0));
battle.Dispose();
}