This commit is contained in:
parent
db3f7f2403
commit
77d7b86a3c
@ -106,7 +106,7 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The happiness of the Pokemon. Also known as friendship.
|
/// The happiness of the Pokemon. Also known as friendship.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
byte Happiness { get; }
|
byte Happiness { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The stats of the Pokemon when disregarding any stat boosts.
|
/// The stats of the Pokemon when disregarding any stat boosts.
|
||||||
@ -708,7 +708,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||||||
public float HeightInMeters { get; set; }
|
public float HeightInMeters { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public byte Happiness { get; }
|
public byte Happiness { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public StatisticSet<uint> FlatStats { get; } = new();
|
public StatisticSet<uint> FlatStats { get; } = new();
|
||||||
|
@ -17,13 +17,23 @@ public abstract class PokeballScript : ItemScript
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the catch rate of the Pokéball against the given target Pokémon.
|
/// Returns the catch rate of the Pokéball against the given target Pokémon.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract byte GetCatchRate(IPokemon target);
|
public abstract void ChangeCatchRate(IPokemon target, ref byte catchRate);
|
||||||
|
|
||||||
|
public virtual void OnAfterSuccessfulCapture(IPokemon target)
|
||||||
|
{
|
||||||
|
// Default implementation does nothing.
|
||||||
|
// Override this method in derived classes to add custom behavior after a successful capture.
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnUseWithTarget(IPokemon target, EventHook eventHook)
|
public override void OnUseWithTarget(IPokemon target, EventHook eventHook)
|
||||||
{
|
{
|
||||||
var battleData = target.BattleData;
|
var battleData = target.BattleData;
|
||||||
|
|
||||||
battleData?.Battle.AttempCapture(battleData.SideIndex, battleData.Position, Item);
|
var result = battleData?.Battle.AttempCapture(battleData.SideIndex, battleData.Position, Item);
|
||||||
|
if (result is { IsCaught: true })
|
||||||
|
{
|
||||||
|
OnAfterSuccessfulCapture(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,6 +20,18 @@ public static class NumericHelpers
|
|||||||
return result > byte.MaxValue ? byte.MaxValue : (byte)result;
|
return result > byte.MaxValue ? byte.MaxValue : (byte)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte AddOrMax(this byte value, byte addend)
|
||||||
|
{
|
||||||
|
var result = value + addend;
|
||||||
|
return result > byte.MaxValue ? byte.MaxValue : (byte)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte SubtractOrMin(this byte value, byte subtrahend)
|
||||||
|
{
|
||||||
|
var result = value - subtrahend;
|
||||||
|
return result < 0 ? (byte)0 : (byte)result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Multiplies two values. If this overflows, returns <see cref="byte.MaxValue"/>.
|
/// Multiplies two values. If this overflows, returns <see cref="byte.MaxValue"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -869,6 +869,12 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1280,6 +1286,7 @@
|
|||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
}
|
}
|
||||||
|
// TODO: implement dive_ball (How do we know when the battle is triggered while surfing, fishing, or diving?)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dna_splicers",
|
"name": "dna_splicers",
|
||||||
@ -1448,6 +1455,7 @@
|
|||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
}
|
}
|
||||||
|
// TODO: implement dusk_ball (How do we know when the battle is triggered at night or in a cave?)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dusk_stone",
|
"name": "dusk_stone",
|
||||||
@ -1744,6 +1752,9 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "fast_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1974,6 +1985,9 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "friend_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2267,6 +2281,12 @@
|
|||||||
"price": 600,
|
"price": 600,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 1.5
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2493,6 +2513,9 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "heavy_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3088,6 +3111,9 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "level_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3219,6 +3245,9 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "love_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3306,6 +3335,7 @@
|
|||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
}
|
}
|
||||||
|
// TODO: implement lure ball effect (how to know if the pokemon was encountered while fishing)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lustrous_orb",
|
"name": "lustrous_orb",
|
||||||
@ -3324,6 +3354,12 @@
|
|||||||
"price": 1000,
|
"price": 1000,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3472,6 +3508,12 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 255
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3819,6 +3861,9 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "love_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3914,6 +3959,9 @@
|
|||||||
"price": 1000,
|
"price": 1000,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "nest_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3924,6 +3972,9 @@
|
|||||||
"price": 1000,
|
"price": 1000,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "net_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -4454,7 +4505,7 @@
|
|||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
},
|
},
|
||||||
"battleEffect": {
|
"battleEffect": {
|
||||||
"name": "pokeball",
|
"name": "pokeball_flat_modifier",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"catchRate": 1
|
"catchRate": 1
|
||||||
}
|
}
|
||||||
@ -4649,6 +4700,12 @@
|
|||||||
"price": 20,
|
"price": 20,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -4816,6 +4873,9 @@
|
|||||||
"price": 1000,
|
"price": 1000,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "quick_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -5099,6 +5159,9 @@
|
|||||||
"price": 1000,
|
"price": 1000,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "repeat_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -5418,6 +5481,12 @@
|
|||||||
"price": -1,
|
"price": -1,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -5903,6 +5972,12 @@
|
|||||||
"price": 300,
|
"price": 300,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -6267,6 +6342,9 @@
|
|||||||
"price": 1000,
|
"price": 1000,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "timer_ball"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -7285,6 +7363,12 @@
|
|||||||
"price": 800,
|
"price": 800,
|
||||||
"additionalData": {
|
"additionalData": {
|
||||||
"flingPower": 0
|
"flingPower": 0
|
||||||
|
},
|
||||||
|
"battleEffect": {
|
||||||
|
"name": "pokeball_flat_modifier",
|
||||||
|
"parameters": {
|
||||||
|
"catchRate": 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using PkmnLib.Dynamic.Libraries;
|
using PkmnLib.Dynamic.Libraries;
|
||||||
|
using PkmnLib.Static.Species;
|
||||||
|
|
||||||
namespace PkmnLib.Plugin.Gen7.Libraries.Battling;
|
namespace PkmnLib.Plugin.Gen7.Libraries.Battling;
|
||||||
|
|
||||||
@ -11,6 +12,8 @@ public class Gen7CaptureLibrary : ICaptureLibrary
|
|||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasPokemonBeenCaughtBefore(ISpecies species) => _configuration.TimesSpeciesCaught(species) > 0;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public CaptureResult TryCapture(IPokemon target, IItem captureItem, IBattleRandom random)
|
public CaptureResult TryCapture(IPokemon target, IItem captureItem, IBattleRandom random)
|
||||||
{
|
{
|
||||||
@ -18,18 +21,17 @@ public class Gen7CaptureLibrary : ICaptureLibrary
|
|||||||
var currentHealth = target.CurrentHealth;
|
var currentHealth = target.CurrentHealth;
|
||||||
var catchRate = target.Species.CaptureRate;
|
var catchRate = target.Species.CaptureRate;
|
||||||
|
|
||||||
byte bonusBall = 1;
|
|
||||||
if (target.Library.ScriptResolver.TryResolveBattleItemScript(captureItem, out var script) &&
|
if (target.Library.ScriptResolver.TryResolveBattleItemScript(captureItem, out var script) &&
|
||||||
script is PokeballScript pokeballScript)
|
script is PokeballScript pokeballScript)
|
||||||
{
|
{
|
||||||
bonusBall = pokeballScript.GetCatchRate(target);
|
pokeballScript.ChangeCatchRate(target, ref catchRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte bonusStatus = 1;
|
byte bonusStatus = 1;
|
||||||
target.RunScriptHook<IScriptChangeCatchRateBonus>(x =>
|
target.RunScriptHook<IScriptChangeCatchRateBonus>(x =>
|
||||||
x.ChangeCatchRateBonus(target, captureItem, ref bonusStatus));
|
x.ChangeCatchRateBonus(target, captureItem, ref bonusStatus));
|
||||||
|
|
||||||
var modifiedCatchRate = (3.0f * maxHealth - 2.0f * currentHealth) * catchRate * bonusBall / (3.0f * maxHealth);
|
var modifiedCatchRate = (3.0f * maxHealth - 2.0f * currentHealth) * catchRate / (3.0f * maxHealth);
|
||||||
modifiedCatchRate *= bonusStatus;
|
modifiedCatchRate *= bonusStatus;
|
||||||
|
|
||||||
var shakeProbability = 65536 / Math.Pow(255 / modifiedCatchRate, 0.1875f);
|
var shakeProbability = 65536 / Math.Pow(255 / modifiedCatchRate, 0.1875f);
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user