Implements critical capture, tweaks for integration tests.
All checks were successful
Build / Build (push) Successful in 48s

This commit is contained in:
2025-05-18 17:07:46 +02:00
parent cbd4340b13
commit 377c1a1c68
11 changed files with 158 additions and 52 deletions

View File

@@ -1,27 +1,37 @@
using System;
using PkmnLib.Plugin.Gen7.Libraries.Battling;
using PkmnLib.Static.Libraries;
using PkmnLib.Static.Species;
namespace PkmnLib.Plugin.Gen7;
public class Gen7PluginConfiguration : PluginConfiguration
public class Gen7PluginConfiguration : IPluginConfiguration
{
public bool DamageCalculatorHasRandomness { get; set; } = true;
/// <summary>
/// Whether the damage calculator has randomness or not. If set to false, the damage calculator will always return
/// the same value for the same inputs. If set to true, the damage calculator will randomize the damage output
/// between 0.85 and 1.00 of the calculated damage.
///
/// This should be set to true for most cases, as it simulates the actual damage calculation in the games. Only
/// set to false for testing purposes.
/// </summary>
public bool DamageCalculatorHasRandomness { get; init; } = true;
/// <summary>
/// The number of times a species has been caught. This is used for critical capture calculations.
/// </summary>
public Func<ISpecies, int> TimesSpeciesCaught { get; init; } = _ => 0;
}
public class Gen7Plugin : Dynamic.ScriptHandling.Registry.Plugin, IResourceProvider
public class Gen7Plugin : Plugin<Gen7PluginConfiguration>, IResourceProvider
{
private readonly Gen7PluginConfiguration _configuration;
public Gen7Plugin()
public Gen7Plugin() : base(new Gen7PluginConfiguration())
{
_configuration = new Gen7PluginConfiguration();
}
/// <inheritdoc />
public Gen7Plugin(PluginConfiguration configuration) : base(configuration)
public Gen7Plugin(Gen7PluginConfiguration configuration) : base(configuration)
{
_configuration = (Gen7PluginConfiguration)configuration;
}
/// <inheritdoc />
@@ -35,9 +45,9 @@ public class Gen7Plugin : Dynamic.ScriptHandling.Registry.Plugin, IResourceProvi
{
registry.RegisterAssemblyScripts(typeof(Gen7Plugin).Assembly);
registry.RegisterBattleStatCalculator(new Gen7BattleStatCalculator());
registry.RegisterDamageCalculator(new Gen7DamageCalculator(_configuration.DamageCalculatorHasRandomness));
registry.RegisterDamageCalculator(new Gen7DamageCalculator(Configuration.DamageCalculatorHasRandomness));
registry.RegisterMiscLibrary(new Gen7MiscLibrary());
registry.RegisterCaptureLibrary(new Gen7CaptureLibrary());
registry.RegisterCaptureLibrary(new Gen7CaptureLibrary(Configuration));
}
/// <inheritdoc />

View File

@@ -5,6 +5,13 @@ namespace PkmnLib.Plugin.Gen7.Libraries.Battling;
public class Gen7CaptureLibrary : ICaptureLibrary
{
private readonly Gen7PluginConfiguration _configuration;
public Gen7CaptureLibrary(Gen7PluginConfiguration configuration)
{
_configuration = configuration;
}
/// <inheritdoc />
public CaptureResult TryCapture(IPokemon target, IItem captureItem, IBattleRandom random)
{
@@ -22,10 +29,10 @@ public class Gen7CaptureLibrary : ICaptureLibrary
byte bonusStatus = 1;
target.RunScriptHook(x => x.ChangeCatchRateBonus(target, captureItem, ref bonusStatus));
var modifiedCatchRate = (3.0 * maxHealth - 2.0 * currentHealth) * catchRate * bonusBall / (3.0 * maxHealth);
var modifiedCatchRate = (3.0f * maxHealth - 2.0f * currentHealth) * catchRate * bonusBall / (3.0f * maxHealth);
modifiedCatchRate *= bonusStatus;
var shakeProbability = 65536 / Math.Pow(255 / modifiedCatchRate, 0.1875);
var shakeProbability = 65536 / Math.Pow(255 / modifiedCatchRate, 0.1875f);
byte shakes = 0;
if (modifiedCatchRate >= 255)
{
@@ -33,7 +40,26 @@ public class Gen7CaptureLibrary : ICaptureLibrary
}
else
{
// FIXME: Implement critical capture
var timesCaught = _configuration.TimesSpeciesCaught(target.Species);
if (timesCaught > 30)
{
var criticalCaptureModifier = timesCaught switch
{
> 600 => 2.5f,
> 450 => 2.0f,
> 300 => 1.5f,
> 150 => 1.0f,
> 30 => 0.5f,
// Default arm, should be heuristically unreachable (due to the timesCaught > 30 check above)
_ => throw new ArgumentOutOfRangeException(),
};
var criticalCaptureChance = (int)(modifiedCatchRate * criticalCaptureModifier / 6);
if (random.GetInt(0, 256) < criticalCaptureChance)
{
return new CaptureResult(true, 1, true);
}
}
for (var i = 0; i < 4; i++)
{
if (random.GetInt(0, 65536) < shakeProbability)