Implement most pokeballs
All checks were successful
Build / Build (push) Successful in 1m2s

This commit is contained in:
2025-07-20 11:15:45 +02:00
parent db3f7f2403
commit 77d7b86a3c
19 changed files with 452 additions and 38 deletions

View File

@@ -0,0 +1,17 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("fast_ball")]
public class FastBall : PokeballScript
{
/// <inheritdoc />
public FastBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
var modifier = target.Form.BaseStats.Speed >= 100 ? 4f : 1f;
catchRate = catchRate.MultiplyOrMax(modifier);
}
}

View File

@@ -0,0 +1,21 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("friend_ball")]
public class FriendBall : PokeballScript
{
/// <inheritdoc />
public FriendBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
}
/// <inheritdoc />
public override void OnAfterSuccessfulCapture(IPokemon target)
{
target.Happiness = 200;
}
}

View File

@@ -0,0 +1,23 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("heal_ball")]
public class HealBall : PokeballScript
{
/// <inheritdoc />
public HealBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
}
/// <inheritdoc />
public override void OnAfterSuccessfulCapture(IPokemon target)
{
target.Heal(target.MaxHealth, true, forceHeal: true);
target.ClearStatus();
target.RestoreAllPP();
}
}

View File

@@ -0,0 +1,38 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("heavy_ball")]
public class HeavyBall : PokeballScript
{
/// <inheritdoc />
public HeavyBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
var weight = target.WeightInKg;
switch (weight)
{
case < 100:
{
catchRate.SubtractOrMin(20);
break;
}
case < 200:
{
break;
}
case < 300:
{
catchRate.AddOrMax(20);
break;
}
default:
{
catchRate.AddOrMax(30);
break;
}
}
}
}

View File

@@ -0,0 +1,31 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("level_ball")]
public class LevelBall : PokeballScript
{
/// <inheritdoc />
public LevelBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
if (target.BattleData is null)
return;
var opponentSide = target.BattleData.SideIndex == 0 ? 1 : 0;
var opponent = target.BattleData.Battle.Sides[opponentSide].Pokemon.FirstOrDefault(x => x is not null);
if (opponent is null)
return;
var levelDifferenceModifier = (float)target.Level / opponent.Level;
var catchModifier = levelDifferenceModifier switch
{
>= 1f => 1f,
>= 0.5f => 2f,
>= 0.25f => 4f,
_ => 8f,
};
catchRate = catchRate.MultiplyOrMax(catchModifier);
}
}

View File

@@ -0,0 +1,26 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("love_ball")]
public class LoveBall : PokeballScript
{
/// <inheritdoc />
public LoveBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
if (target.BattleData is null)
return;
var opponentSide = target.BattleData.SideIndex == 0 ? 1 : 0;
var opponent = target.BattleData.Battle.Sides[opponentSide].Pokemon.FirstOrDefault(x => x is not null);
if (opponent is null)
return;
if (opponent.Species == target.Species && opponent.Gender != target.Gender)
{
catchRate = catchRate.MultiplyOrMax(8f);
}
}
}

View File

@@ -0,0 +1,32 @@
using PkmnLib.Static.Species;
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("moon_ball")]
public class MoonBall : PokeballScript
{
/// <inheritdoc />
public MoonBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
if (target.Species.EvolutionData.Any(x =>
{
switch (x)
{
case ItemUseEvolution itemUseEvolution when itemUseEvolution.Item == "moon_ball":
case ItemGenderEvolution itemGenderEvolution when itemGenderEvolution.Item == "moon_ball":
return true;
default:
return false;
}
}))
{
// If the target can evolve with a Moon Ball, it has a 4x catch rate.
catchRate = catchRate.MultiplyOrMax(4f);
}
}
}

View File

@@ -0,0 +1,19 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("nest_ball")]
public class NestBall : PokeballScript
{
/// <inheritdoc />
public NestBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
if (target.Level >= 30)
return;
var modifier = (41 - target.Level) / 10f;
catchRate = catchRate.MultiplyOrMax(modifier);
}
}

View File

@@ -0,0 +1,22 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("net_ball")]
public class NetBall : PokeballScript
{
/// <inheritdoc />
public NetBall(IItem item) : base(item)
{
}
private static readonly StringKey WaterType = "water";
private static readonly StringKey BugType = "bug";
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
if (target.Types.Any(x => x.Name == WaterType || x.Name == BugType))
{
catchRate = catchRate.MultiplyOrMax(3.5f);
}
}
}

View File

@@ -0,0 +1,38 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
/// <summary>
/// An implementation of a pokeball script that just has a flat catch rate bonus.
/// </summary>
[ItemScript("pokeball_flat_modifier")]
public class PokeballFlatModifier : PokeballScript
{
private float _catchModifier;
/// <inheritdoc />
public PokeballFlatModifier(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{
var catchModifier = 1f;
if (parameters != null && parameters.TryGetValue("catchRate", out var catchRateObj))
{
catchModifier = catchRateObj switch
{
float catchModifierFloat => catchModifierFloat,
int catchModifierInt => catchModifierInt,
_ => catchModifier,
};
}
_catchModifier = catchModifier;
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
catchRate = catchRate.MultiplyOrMax(_catchModifier);
}
}

View File

@@ -0,0 +1,23 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("quick_ball")]
public class QuickBall : PokeballScript
{
/// <inheritdoc />
public QuickBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
var battleData = target.BattleData;
if (battleData is null)
return;
if (battleData.Battle.CurrentTurnNumber == 1)
{
catchRate = catchRate.MultiplyOrMax(5f);
}
}
}

View File

@@ -0,0 +1,22 @@
using PkmnLib.Plugin.Gen7.Libraries.Battling;
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("repeat_ball")]
public class RepeatBall : PokeballScript
{
/// <inheritdoc />
public RepeatBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
if (target.Library.CaptureLibrary is Gen7CaptureLibrary captureLibrary &&
captureLibrary.HasPokemonBeenCaughtBefore(target.Species))
{
catchRate = catchRate.MultiplyOrMax(3.5f);
}
}
}

View File

@@ -0,0 +1,24 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items.Pokeballs;
[ItemScript("timer_ball")]
public class TimerBall : PokeballScript
{
/// <inheritdoc />
public TimerBall(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void ChangeCatchRate(IPokemon target, ref byte catchRate)
{
var battleData = target.BattleData;
if (battleData is null)
return;
var turns = battleData.Battle.CurrentTurnNumber;
var modifier = 1 + turns * (1229 / 4096f);
if (modifier > 4f)
modifier = 4f;
catchRate = catchRate.MultiplyOrMax(modifier);
}
}

View File

@@ -1,30 +0,0 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Items;
/// <summary>
/// An implementation of a pokeball script that just has a flat catch rate bonus.
/// </summary>
[ItemScript("pokeball")]
public class StaticPokeball : PokeballScript
{
private byte _catchRate;
/// <inheritdoc />
public StaticPokeball(IItem item) : base(item)
{
}
/// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{
if (parameters == null || !parameters.TryGetValue("catchRate", out var catchRateObj) ||
catchRateObj is not byte catchRate)
{
catchRate = 1;
}
_catchRate = catchRate;
}
/// <inheritdoc />
public override byte GetCatchRate(IPokemon target) => _catchRate;
}