This commit is contained in:
@@ -39,6 +39,12 @@ public interface IDynamicLibrary
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
ICaptureLibrary CaptureLibrary { get; }
|
ICaptureLibrary CaptureLibrary { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The experience gain calculator deals with the calculation of experience gained by a
|
||||||
|
/// Pokémon after defeating another Pokémon.
|
||||||
|
/// </summary>
|
||||||
|
IExperienceGainCalculator ExperienceGainCalculator { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A holder of the script types that can be resolved by this library.
|
/// A holder of the script types that can be resolved by this library.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -64,12 +70,13 @@ public class DynamicLibraryImpl : IDynamicLibrary
|
|||||||
|
|
||||||
return new DynamicLibraryImpl(load.StaticLibrary, load.Registry.BattleStatCalculator!,
|
return new DynamicLibraryImpl(load.StaticLibrary, load.Registry.BattleStatCalculator!,
|
||||||
load.Registry.DamageCalculator!, load.Registry.MiscLibrary!, load.Registry.CaptureLibrary!, load.Resolver,
|
load.Registry.DamageCalculator!, load.Registry.MiscLibrary!, load.Registry.CaptureLibrary!, load.Resolver,
|
||||||
load.Registry.ExplicitAIHandlers);
|
load.Registry.ExplicitAIHandlers, load.Registry.ExperienceGainCalculator!);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DynamicLibraryImpl(IStaticLibrary staticLibrary, IBattleStatCalculator statCalculator,
|
private DynamicLibraryImpl(IStaticLibrary staticLibrary, IBattleStatCalculator statCalculator,
|
||||||
IDamageCalculator damageCalculator, IMiscLibrary miscLibrary, ICaptureLibrary captureLibrary,
|
IDamageCalculator damageCalculator, IMiscLibrary miscLibrary, ICaptureLibrary captureLibrary,
|
||||||
ScriptResolver scriptResolver, IReadOnlyExplicitAIHandlers explicitAIHandlers)
|
ScriptResolver scriptResolver, IReadOnlyExplicitAIHandlers explicitAIHandlers,
|
||||||
|
IExperienceGainCalculator experienceGainCalculator)
|
||||||
{
|
{
|
||||||
StaticLibrary = staticLibrary;
|
StaticLibrary = staticLibrary;
|
||||||
StatCalculator = statCalculator;
|
StatCalculator = statCalculator;
|
||||||
@@ -77,6 +84,7 @@ public class DynamicLibraryImpl : IDynamicLibrary
|
|||||||
MiscLibrary = miscLibrary;
|
MiscLibrary = miscLibrary;
|
||||||
ScriptResolver = scriptResolver;
|
ScriptResolver = scriptResolver;
|
||||||
ExplicitAIHandlers = explicitAIHandlers;
|
ExplicitAIHandlers = explicitAIHandlers;
|
||||||
|
ExperienceGainCalculator = experienceGainCalculator;
|
||||||
CaptureLibrary = captureLibrary;
|
CaptureLibrary = captureLibrary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +103,9 @@ public class DynamicLibraryImpl : IDynamicLibrary
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICaptureLibrary CaptureLibrary { get; }
|
public ICaptureLibrary CaptureLibrary { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IExperienceGainCalculator ExperienceGainCalculator { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ScriptResolver ScriptResolver { get; }
|
public ScriptResolver ScriptResolver { get; }
|
||||||
|
|
||||||
|
|||||||
14
PkmnLib.Dynamic/Libraries/ExperienceGainCalculator.cs
Normal file
14
PkmnLib.Dynamic/Libraries/ExperienceGainCalculator.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
|
||||||
|
namespace PkmnLib.Dynamic.Libraries;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates experience gain for Pokémon battles.
|
||||||
|
/// </summary>
|
||||||
|
public interface IExperienceGainCalculator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the experience a Pokémon gains when defeating another Pokémon.
|
||||||
|
/// </summary>
|
||||||
|
uint CalculateExperienceGain(IPokemon defeatedPokemon, IPokemon victoriousPokemon);
|
||||||
|
}
|
||||||
@@ -36,6 +36,8 @@ public static class LibraryLoader
|
|||||||
throw new InvalidOperationException("Misc library not found in plugins.");
|
throw new InvalidOperationException("Misc library not found in plugins.");
|
||||||
if (registry.CaptureLibrary is null)
|
if (registry.CaptureLibrary is null)
|
||||||
throw new InvalidOperationException("Capture library not found in plugins.");
|
throw new InvalidOperationException("Capture library not found in plugins.");
|
||||||
|
if (registry.ExperienceGainCalculator is null)
|
||||||
|
throw new InvalidOperationException("Experience gain calculator not found in plugins.");
|
||||||
var scriptResolver = new ScriptResolver(registry.ScriptTypes, registry.ItemScriptTypes);
|
var scriptResolver = new ScriptResolver(registry.ScriptTypes, registry.ItemScriptTypes);
|
||||||
return new LoadResult(registry, scriptResolver, staticLibrary);
|
return new LoadResult(registry, scriptResolver, staticLibrary);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1184,6 +1184,11 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||||||
BattleData.BattleSide.MarkFaint(BattleData.Position);
|
BattleData.BattleSide.MarkFaint(BattleData.Position);
|
||||||
BattleData.BattleSide.ForceClearPokemonFromField(BattleData.Position);
|
BattleData.BattleSide.ForceClearPokemonFromField(BattleData.Position);
|
||||||
|
|
||||||
|
foreach (var opponent in BattleData.SeenOpponents.WhereNotNull())
|
||||||
|
{
|
||||||
|
opponent.AddExperience(Library.ExperienceGainCalculator.CalculateExperienceGain(this, opponent));
|
||||||
|
}
|
||||||
|
|
||||||
// Validate the battle state to see if the battle is over.
|
// Validate the battle state to see if the battle is over.
|
||||||
BattleData.Battle.ValidateBattleState();
|
BattleData.Battle.ValidateBattleState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public class ScriptRegistry
|
|||||||
private IDamageCalculator? _damageCalculator;
|
private IDamageCalculator? _damageCalculator;
|
||||||
private IMiscLibrary? _miscLibrary;
|
private IMiscLibrary? _miscLibrary;
|
||||||
private ICaptureLibrary? _captureLibrary;
|
private ICaptureLibrary? _captureLibrary;
|
||||||
|
private IExperienceGainCalculator? _experienceGainCalculator;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Automatically register all scripts in the given assembly that have the <see cref="ScriptAttribute"/>, and
|
/// Automatically register all scripts in the given assembly that have the <see cref="ScriptAttribute"/>, and
|
||||||
@@ -110,11 +111,18 @@ public class ScriptRegistry
|
|||||||
public void RegisterCaptureLibrary<T>(T captureLibrary) where T : ICaptureLibrary =>
|
public void RegisterCaptureLibrary<T>(T captureLibrary) where T : ICaptureLibrary =>
|
||||||
_captureLibrary = captureLibrary;
|
_captureLibrary = captureLibrary;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register an experience gain calculator.
|
||||||
|
/// </summary>
|
||||||
|
public void RegisterExperienceGainCalculator<T>(T experienceGainCalculator) where T : IExperienceGainCalculator =>
|
||||||
|
_experienceGainCalculator = experienceGainCalculator;
|
||||||
|
|
||||||
internal IReadOnlyDictionary<(ScriptCategory category, StringKey name), Func<Script>> ScriptTypes => _scriptTypes;
|
internal IReadOnlyDictionary<(ScriptCategory category, StringKey name), Func<Script>> ScriptTypes => _scriptTypes;
|
||||||
internal IReadOnlyDictionary<StringKey, Func<IItem, ItemScript>> ItemScriptTypes => _itemScriptTypes;
|
internal IReadOnlyDictionary<StringKey, Func<IItem, ItemScript>> ItemScriptTypes => _itemScriptTypes;
|
||||||
internal IBattleStatCalculator? BattleStatCalculator => _battleStatCalculator;
|
internal IBattleStatCalculator? BattleStatCalculator => _battleStatCalculator;
|
||||||
internal IDamageCalculator? DamageCalculator => _damageCalculator;
|
internal IDamageCalculator? DamageCalculator => _damageCalculator;
|
||||||
internal IMiscLibrary? MiscLibrary => _miscLibrary;
|
internal IMiscLibrary? MiscLibrary => _miscLibrary;
|
||||||
internal ICaptureLibrary? CaptureLibrary => _captureLibrary;
|
internal ICaptureLibrary? CaptureLibrary => _captureLibrary;
|
||||||
|
internal IExperienceGainCalculator? ExperienceGainCalculator => _experienceGainCalculator;
|
||||||
public ExplicitAIHandlers ExplicitAIHandlers { get; } = new();
|
public ExplicitAIHandlers ExplicitAIHandlers { get; } = new();
|
||||||
}
|
}
|
||||||
@@ -49,6 +49,7 @@ public class Gen7Plugin : Plugin<Gen7PluginConfiguration>, IResourceProvider
|
|||||||
registry.RegisterDamageCalculator(new Gen7DamageCalculator(Configuration));
|
registry.RegisterDamageCalculator(new Gen7DamageCalculator(Configuration));
|
||||||
registry.RegisterMiscLibrary(new Gen7MiscLibrary());
|
registry.RegisterMiscLibrary(new Gen7MiscLibrary());
|
||||||
registry.RegisterCaptureLibrary(new Gen7CaptureLibrary(Configuration));
|
registry.RegisterCaptureLibrary(new Gen7CaptureLibrary(Configuration));
|
||||||
|
registry.RegisterExperienceGainCalculator(new Gen7ExperienceGainCalculator());
|
||||||
|
|
||||||
ExplicitAIFunctionRegistration.RegisterAIFunctions(registry.ExplicitAIHandlers);
|
ExplicitAIFunctionRegistration.RegisterAIFunctions(registry.ExplicitAIHandlers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using PkmnLib.Dynamic.Libraries;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Libraries.Battling;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public class Gen7ExperienceGainCalculator : IExperienceGainCalculator
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
[SuppressMessage("ReSharper", "UselessBinaryOperation")]
|
||||||
|
public uint CalculateExperienceGain(IPokemon defeatedPokemon, IPokemon victoriousPokemon)
|
||||||
|
{
|
||||||
|
var b = defeatedPokemon.Form.BaseExperience;
|
||||||
|
var levelFainted = defeatedPokemon.Level;
|
||||||
|
var levelOpponent = victoriousPokemon.Level;
|
||||||
|
// TODO: Experience share, in which case s = 2 for Pokemon that did not participate in battle
|
||||||
|
var s = 1;
|
||||||
|
|
||||||
|
var v1 = b * levelFainted / 5 * (1 / s);
|
||||||
|
var v2 = (2 * levelFainted + 10) / (levelFainted + levelOpponent + 10);
|
||||||
|
var res = v1 * Math.Pow(v2, 2.5) + 1;
|
||||||
|
|
||||||
|
// TODO: t = 1.5 if the Pokemon is traded, and 1.7 is traded and has a different language
|
||||||
|
var t = 1;
|
||||||
|
res *= t;
|
||||||
|
// TODO: script modifier, which is e.
|
||||||
|
var e = 1;
|
||||||
|
res *= e;
|
||||||
|
// TODO: v = 1.2 if the Pokemon is at or past the level where it evolves
|
||||||
|
var v = 1;
|
||||||
|
res *= v;
|
||||||
|
|
||||||
|
return res switch
|
||||||
|
{
|
||||||
|
> uint.MaxValue => uint.MaxValue,
|
||||||
|
< 0 => 0,
|
||||||
|
_ => (uint)res,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user