Deukhoofd eea5697109
All checks were successful
Build / Build (push) Successful in 49s
Fixes all warnings
2025-05-19 11:50:51 +02:00

73 lines
2.5 KiB
C#

using PkmnLib.Dynamic.Libraries;
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)
{
var maxHealth = target.BoostedStats.Hp;
var currentHealth = target.CurrentHealth;
var catchRate = target.Species.CaptureRate;
byte bonusBall = 1;
if (target.Library.ScriptResolver.TryResolveBattleItemScript(captureItem, out var script) &&
script is PokeballScript pokeballScript)
{
bonusBall = pokeballScript.GetCatchRate(target);
}
byte bonusStatus = 1;
target.RunScriptHook(x => x.ChangeCatchRateBonus(target, captureItem, ref bonusStatus));
var modifiedCatchRate = (3.0f * maxHealth - 2.0f * currentHealth) * catchRate * bonusBall / (3.0f * maxHealth);
modifiedCatchRate *= bonusStatus;
var shakeProbability = 65536 / Math.Pow(255 / modifiedCatchRate, 0.1875f);
byte shakes = 0;
if (modifiedCatchRate >= 255)
{
shakes = 4;
}
else
{
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)
{
shakes++;
}
}
}
var success = shakes >= 3;
return new CaptureResult(success, shakes, false);
}
}