Style cleanup

This commit is contained in:
2025-03-02 17:19:57 +01:00
parent c0bc905c46
commit 284ab3079c
175 changed files with 588 additions and 650 deletions

View File

@@ -27,21 +27,19 @@ public class DamageCalculatorTests
// Imagine a level 75 Glaceon
attacker.Setup(x => x.Level).Returns(75);
// with an effective Attack stat of 123
attacker.Setup(x => x.BoostedStats).Returns(new StatisticSet<uint>(
1, 123, 1, 1, 1, 1));
attacker.Setup(x => x.BoostedStats).Returns(new StatisticSet<uint>(1, 123, 1, 1, 1, 1));
// We use 10 as the Ice type
attacker.Setup(x => x.Types).Returns([new TypeIdentifier(10)]);
var defender = new Mock<IPokemon>();
// a Garchomp with an effective Defense stat of 163
defender.Setup(x => x.BoostedStats).Returns(new StatisticSet<uint>(
1, 1, 163, 1, 1, 1));
defender.Setup(x => x.BoostedStats).Returns(new StatisticSet<uint>(1, 1, 163, 1, 1, 1));
defender.Setup(x => x.GetScripts()).Returns(new ScriptIterator([]));
var useMove = new Mock<IMoveData>();
// Ice Fang (an Ice-type physical move with a power of 65)
useMove.Setup(x => x.Category).Returns(MoveCategory.Physical);
var damageCalculator = new Gen7DamageCalculator(false);
var executingMove = new Mock<IExecutingMove>();
executingMove.Setup(x => x.UseMove).Returns(useMove.Object);
@@ -54,7 +52,7 @@ public class DamageCalculatorTests
hit.Setup(x => x.Type).Returns(new TypeIdentifier(10));
// has a double weakness to the move's Ice type
hit.Setup(x => x.Effectiveness).Returns(4.0f);
var damage = damageCalculator.GetDamage(executingMove.Object, defender.Object, 0, hit.Object);
// That means Ice Fang will do between 168 and 196 HP damage, depending on luck.
// Note that we are testing deterministic damage, so we expect the maximum damage.

View File

@@ -23,7 +23,7 @@ public class AcrobaticsTests
// Assert
await Assert.That(basePower).IsEqualTo((byte)20);
}
[Test]
public async Task ChangeBasePower_UserHoldingItem_BasePowerUnchanged()
{
@@ -59,5 +59,4 @@ public class AcrobaticsTests
// Assert
await Assert.That(basePower).IsEqualTo(byte.MaxValue);
}
}

View File

@@ -10,7 +10,7 @@ public class Gen7PluginConfiguration : PluginConfiguration
public class Gen7Plugin : Dynamic.ScriptHandling.Registry.Plugin
{
private readonly Gen7PluginConfiguration _configuration;
public Gen7Plugin() : base()
{
_configuration = new Gen7PluginConfiguration();

View File

@@ -2,4 +2,4 @@ global using PkmnLib.Dynamic.ScriptHandling;
global using PkmnLib.Dynamic.ScriptHandling.Registry;
global using PkmnLib.Dynamic.Events;
global using PkmnLib.Dynamic.Models;
global using PkmnLib.Dynamic.Models.Choices;
global using PkmnLib.Dynamic.Models.Choices;

View File

@@ -44,21 +44,24 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
var flatStat = CalculateFlatStat(pokemon, stat);
var boostModifier = GetStatBoostModifier(pokemon, stat);
var boostedStat = flatStat * boostModifier;
if (boostedStat > uint.MaxValue) boostedStat = uint.MaxValue;
if (boostedStat > uint.MaxValue)
boostedStat = uint.MaxValue;
return (uint)boostedStat;
}
/// <inheritdoc />
public byte CalculateModifiedAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, byte moveAccuracy)
public byte CalculateModifiedAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex,
byte moveAccuracy)
{
var accuracyModifier = 1.0f;
executingMove.RunScriptHook(x => x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier));
executingMove.RunScriptHook(
x => x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier));
var modifiedAccuracy = (int)(moveAccuracy * accuracyModifier);
executingMove.RunScriptHook(x => x.ChangeAccuracy(executingMove, target, hitIndex, ref modifiedAccuracy));
var targetEvasion = target.StatBoost.Evasion;
var ignoreEvasion = false;
executingMove.RunScriptHook(x => x.BypassEvasionStatBoosts(executingMove, target, hitIndex, ref ignoreEvasion));
if (ignoreEvasion)
if (ignoreEvasion)
targetEvasion = 0;
var userAccuracy = executingMove.User.StatBoost.Accuracy;
var difference = targetEvasion - userAccuracy;
@@ -66,14 +69,14 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
{
> 0 => 3.0f / (3.0f + Math.Min(difference, 6)),
< 0 => 3.0f + -Math.Max(difference, -6) / 3.0f,
_ => 1.0f
_ => 1.0f,
};
modifiedAccuracy = (int)(modifiedAccuracy * statModifier);
modifiedAccuracy = modifiedAccuracy switch
{
> 255 => 255,
< 0 => 0,
_ => modifiedAccuracy
_ => modifiedAccuracy,
};
// NOTE: the main games also consider friendship here, but we don't yet have the concept of a "player Pokémon"
// in the battle system, so for now we're just ignoring that.
@@ -86,8 +89,9 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
var iv = (ulong)pokemon.IndividualValues.Hp;
var ev = (ulong)pokemon.EffortValues.Hp;
var level = (ulong)pokemon.Level;
var health = (((2 * baseValue + iv + (ev / 4)) * level) / 100) + level + 10;
if (health > uint.MaxValue) health = uint.MaxValue;
var health = (2 * baseValue + iv + ev / 4) * level / 100 + level + 10;
if (health > uint.MaxValue)
health = uint.MaxValue;
return (uint)health;
}
@@ -97,10 +101,11 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
var iv = (ulong)pokemon.IndividualValues.GetStatistic(statistic);
var ev = (ulong)pokemon.EffortValues.GetStatistic(statistic);
var level = (ulong)pokemon.Level;
var unmodified = (((2 * baseValue + iv + (ev / 4)) * level) / 100) + 5;
var unmodified = (2 * baseValue + iv + ev / 4) * level / 100 + 5;
var natureModifier = pokemon.Nature.GetStatModifier(statistic);
var modified = (unmodified * natureModifier);
if (modified > uint.MaxValue) modified = uint.MaxValue;
var modified = unmodified * natureModifier;
if (modified > uint.MaxValue)
modified = uint.MaxValue;
return (uint)modified;
}
@@ -122,7 +127,7 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
4 => 6.0f / 2.0f,
5 => 7.0f / 2.0f,
6 => 8.0f / 2.0f,
_ => throw new System.ArgumentException("Stat boost was out of expected range of -6 to 6"),
_ => throw new ArgumentException("Stat boost was out of expected range of -6 to 6"),
};
}
}

View File

@@ -23,11 +23,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.0 * maxHealth - 2.0 * currentHealth) * catchRate * bonusBall / (3.0 * maxHealth);
modifiedCatchRate *= bonusStatus;
var shakeProbability = 65536 / Math.Pow((255 / modifiedCatchRate), 0.1875);
var shakeProbability = 65536 / Math.Pow(255 / modifiedCatchRate, 0.1875);
byte shakes = 0;
if (modifiedCatchRate >= 255)
{

View File

@@ -17,7 +17,7 @@ public class Gen7DamageCalculator(bool hasRandomness) : IDamageCalculator
if (hitData.Effectiveness == 0)
return 0;
var levelModifier = (2.0f * executingMove.User.Level) / 5.0f + 2.0f;
var levelModifier = 2.0f * executingMove.User.Level / 5.0f + 2.0f;
var basePower = (float)hitData.BasePower;
var statModifier = GetStatModifier(executingMove, target, hitNumber, hitData);
var damageModifier = GetDamageModifier(executingMove, target, hitNumber);
@@ -62,10 +62,8 @@ public class Gen7DamageCalculator(bool hasRandomness) : IDamageCalculator
< 1 => 1,
_ => (uint)floatDamage,
};
executingMove.RunScriptHook(script =>
script.ChangeMoveDamage(executingMove, target, hitNumber, ref damage));
target.RunScriptHook(script =>
script.ChangeIncomingMoveDamage(executingMove, target, hitNumber, ref damage));
executingMove.RunScriptHook(script => script.ChangeMoveDamage(executingMove, target, hitNumber, ref damage));
target.RunScriptHook(script => script.ChangeIncomingMoveDamage(executingMove, target, hitNumber, ref damage));
return damage;
}
@@ -76,8 +74,7 @@ public class Gen7DamageCalculator(bool hasRandomness) : IDamageCalculator
if (executingMove.UseMove.Category == MoveCategory.Status)
return 0;
var basePower = executingMove.UseMove.BasePower;
executingMove.RunScriptHook(script =>
script.ChangeBasePower(executingMove, target, hitNumber, ref basePower));
executingMove.RunScriptHook(script => script.ChangeBasePower(executingMove, target, hitNumber, ref basePower));
return basePower;
}
@@ -100,7 +97,8 @@ public class Gen7DamageCalculator(bool hasRandomness) : IDamageCalculator
};
}
private static float GetStatModifier(IExecutingMove executingMove, IPokemon target, byte hitNumber, IHitData hitData)
private static float GetStatModifier(IExecutingMove executingMove, IPokemon target, byte hitNumber,
IHitData hitData)
{
var category = executingMove.UseMove.Category;
if (category == MoveCategory.Status)
@@ -135,7 +133,7 @@ public class Gen7DamageCalculator(bool hasRandomness) : IDamageCalculator
if (bypassDefense)
targetStats = target.FlatStats;
var defensiveStat = targetStats.GetStatistic(defensive);
executingMove.RunScriptHook(script =>
script.ChangeOffensiveStatValue(executingMove, target, hitNumber, ref offensiveStat));
executingMove.RunScriptHook(script =>

View File

@@ -11,14 +11,12 @@ namespace PkmnLib.Plugin.Gen7.Libraries;
public class Gen7MiscLibrary : IMiscLibrary
{
private readonly IMoveData _struggleData = new MoveDataImpl("struggle", new TypeIdentifier(0),
MoveCategory.Physical, 50,
255, 255, MoveTarget.Any, 0,
MoveCategory.Physical, 50, 255, 255, MoveTarget.Any, 0,
new SecondaryEffectImpl(-1, "struggle", new Dictionary<StringKey, object?>()), []);
/// <inheritdoc />
public ITurnChoice ReplacementChoice(IPokemon user, byte targetSide, byte targetPosition) =>
new MoveChoice(user, new LearnedMoveImpl(_struggleData, MoveLearnMethod.Unknown), targetSide,
targetPosition);
new MoveChoice(user, new LearnedMoveImpl(_struggleData, MoveLearnMethod.Unknown), targetSide, targetPosition);
/// <inheritdoc />
public TimeOfDay GetTimeOfDay()
@@ -46,18 +44,18 @@ public class Gen7MiscLibrary : IMiscLibrary
var opponent = opponentSide.Pokemon.FirstOrDefault(x => x is not null);
if (opponent == null)
return true;
var userSpeed = user.FlatStats.Speed;
var opponentSpeed = opponent.FlatStats.Speed;
// If the player's active Pokémon's Speed is greater than or equal to the wild Pokémon's Speed, fleeing will
// always succeed
if (userSpeed >= opponentSpeed)
return true;
var userSide = battle.Sides[battleData.SideIndex];
userSide.RegisterFleeAttempt();
var fleeChance = ((userSpeed * 32) / (opponentSpeed / 4) + (30 * userSide.FleeAttempts)) / 256;
var fleeChance = (userSpeed * 32 / (opponentSpeed / 4) + 30 * userSide.FleeAttempts) / 256;
var random = battle.Random.GetInt(0, 100);
return random < fleeChance;
}

View File

@@ -4,7 +4,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Battle;
public class FairyLockEffect : Script
{
private int _turns = 1;
/// <inheritdoc />
public override void PreventSelfRunAway(IFleeChoice choice, ref bool prevent)
{
@@ -20,7 +20,7 @@ public class FairyLockEffect : Script
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{
if (_turns <= 0)
if (_turns <= 0)
RemoveSelf();
_turns--;
}

View File

@@ -5,8 +5,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts;
public static class CustomTriggers
{
public static readonly StringKey AuroraVeilDuration = "aurora_veil_duration";
public static readonly StringKey BindNumberOfTurns = "bind_number_of_turns";
public static readonly StringKey BindPercentOfMaxHealth = "bind_percent_of_max_health";
}

View File

@@ -30,8 +30,5 @@ public class StaticPokeball : PokeballScript
}
/// <inheritdoc />
public override byte GetCatchRate(IPokemon target)
{
return _catchRate;
}
public override byte GetCatchRate(IPokemon target) => _catchRate;
}

View File

@@ -3,7 +3,8 @@ using PkmnLib.Static;
namespace PkmnLib.Plugin.Gen7.Scripts.MoveVolatile;
[Script(ScriptCategory.MoveVolatile, "electrify")]
public class ElectrifyEffect : Script {
public class ElectrifyEffect : Script
{
/// <inheritdoc />
public override void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier moveType)
{

View File

@@ -18,7 +18,7 @@ public class AfterYou : Script
var queue = move.User.BattleData!.Battle.ChoiceQueue;
if (queue == null)
return;
// If the queue doesn't change, the move fails
if (!queue.MovePokemonChoiceNext(target))
{

View File

@@ -45,11 +45,11 @@ public class AuroraVeil : Script
var numberOfTurns = 5;
var dict = new Dictionary<StringKey, object?>()
{
{ "duration", numberOfTurns }
{ "duration", numberOfTurns },
};
move.User.RunScriptHook(x => x.CustomTrigger(CustomTriggers.AuroraVeilDuration, dict));
numberOfTurns = (int)dict.GetOrDefault("duration", numberOfTurns)!;
var script = side.VolatileScripts.StackOrAdd(ScriptUtils.ResolveName<AuroraVeilEffect>(), () =>
{
var effect = new AuroraVeilEffect(numberOfTurns);

View File

@@ -24,13 +24,12 @@ public class Autotomize : Script
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var user = move.User;
if (user.ChangeStatBoost(Statistic.Speed, 2, true) &&
user.ChangeWeightInKgBy(-100.0f))
if (user.ChangeStatBoost(Statistic.Speed, 2, true) && user.ChangeWeightInKgBy(-100.0f))
{
var battle = user.BattleData?.Battle;
battle?.EventHook.Invoke(new DialogEvent("pokemon_became_nimble", new Dictionary<string, object>()
{
{ "pokemon", user }
{ "pokemon", user },
}));
}
}

View File

@@ -6,8 +6,5 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
public class BanefulBunker : ProtectionScript
{
/// <inheritdoc />
protected override Script GetEffectScript()
{
return new BanefulBunkerEffect();
}
protected override Script GetEffectScript() => new BanefulBunkerEffect();
}

View File

@@ -20,14 +20,14 @@ public class BatonPass : Script
var battleData = user.BattleData;
if (battleData == null)
return;
var statBoosts = user.StatBoost;
var volatileScripts = user.Volatile.Select(x => x.Script).WhereNotNull().ToList();
foreach (var container in user.Volatile)
{
container.ClearWithoutRemoving();
}
var side = battleData.Battle.Sides[battleData.SideIndex];
side.SwapPokemon(battleData.Position, toSwitch);
@@ -36,7 +36,7 @@ public class BatonPass : Script
toSwitch.StatBoost.SetStatistic(stat, statBoosts.GetStatistic(stat));
}
toSwitch.RecalculateBoostedStats();
foreach (var script in volatileScripts)
{
toSwitch.Volatile.Add(script);

View File

@@ -15,7 +15,7 @@ public class BeakBlast : Script
choice.User.Volatile.Add(new BeakBlastEffect());
battleData.Battle.EventHook.Invoke(new DialogEvent("beak_blast_charge", new Dictionary<string, object>()
{
{ "user", choice.User }
{ "user", choice.User },
}));
}

View File

@@ -8,6 +8,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
public class BeatUp : Script
{
private IPokemon[]? _relevantPartyMembers;
private static IEnumerable<IPokemon> GetRelevantPartyMembers(IPokemon user)
{
var battleData = user.BattleData;
@@ -17,12 +18,12 @@ public class BeatUp : Script
var party = battleData.Battle.Parties.FirstOrDefault(x => x.Party.Contains(user));
return party?.Party.WhereNotNull().Where(x => x.IsUsable && x.StatusScript.IsEmpty) ?? [];
}
/// <inheritdoc />
public override void ChangeNumberOfHits(IMoveChoice choice, ref byte numberOfHits)
{
var relevantPartyMembers = _relevantPartyMembers ??= GetRelevantPartyMembers(choice.User).ToArray();
numberOfHits = (byte)relevantPartyMembers.Count();
if (numberOfHits == 0)
numberOfHits = 1;

View File

@@ -12,7 +12,7 @@ public class Belch : Script
var battleData = choice.User.BattleData;
if (battleData == null)
return;
if (battleData.ConsumedItems.All(x => x.Category != ItemCategory.Berry))
prevent = true;
}

View File

@@ -14,7 +14,7 @@ public class BellyDrum : Script
move.GetHitData(target, hit).Fail();
return;
}
target.Damage(maxHealthHalved, DamageSource.Misc);
// Raising the user's Attack by 12 stages should always set it to +6.
target.ChangeStatBoost(Statistic.Attack, 12, true);

View File

@@ -9,13 +9,13 @@ public class Bestow : Script
var user = move.User;
var userHeldItem = user.RemoveHeldItemForBattle();
var targetHeldItem = target.HeldItem;
if (userHeldItem == null || targetHeldItem != null)
{
move.GetHitData(target, hit).Fail();
return;
}
_ = target.SetHeldItem(userHeldItem);
}
}

View File

@@ -9,13 +9,13 @@ public class Bounce : Script
/// <inheritdoc />
public override void PreventMove(IExecutingMove move, ref bool prevent)
{
if (move.User.Volatile.Contains<ChargeBounceEffect>())
if (move.User.Volatile.Contains<ChargeBounceEffect>())
return;
move.User.Volatile.Add(new ChargeBounceEffect(move.User));
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("bounce_charge", new Dictionary<string, object>()
{
{ "user", move.User }
{ "user", move.User },
}));
prevent = true;
}

View File

@@ -12,9 +12,9 @@ public class BugBite : Script
var battleData = user.BattleData;
if (battleData == null)
return;
var targetHeldItem = target.HeldItem;
if (targetHeldItem is not { Category: ItemCategory.Berry })
{
move.GetHitData(target, hit).Fail();

View File

@@ -19,8 +19,8 @@ public class BurnUp : Script
move.GetHitData(target, hit).Fail();
return;
}
if (move.User.HasStatus("frozen"))
if (move.User.HasStatus("frozen"))
move.User.ClearStatus();
move.User.RemoveType(fireType);
}

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Dynamic.Events;
public class ChangeAllTargetStats : Script
{
private sbyte _amount;
/// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
public class ChangeMultipleUserStatBoosts : Script
{
private Dictionary<Statistic, sbyte> _statBoosts = new();
/// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{
@@ -21,7 +21,7 @@ public class ChangeMultipleUserStatBoosts : Script
foreach (var par in parameters)
{
if (!Enum.TryParse<Statistic>(par.Key, true, out var stat))
if (!Enum.TryParse<Statistic>(par.Key, true, out var stat))
continue;
if (par.Value is sbyte value)
{
@@ -30,7 +30,6 @@ public class ChangeMultipleUserStatBoosts : Script
}
}
/// <inheritdoc />
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
@@ -40,4 +39,4 @@ public class ChangeMultipleUserStatBoosts : Script
move.User.ChangeStatBoost(stat.Key, stat.Value, true, batchId);
}
}
}
}

View File

@@ -8,6 +8,6 @@ public class ChipAway : Script
bypass = true;
/// <inheritdoc />
public override void BypassEvasionStatBoosts(IExecutingMove move, IPokemon target, byte hitIndex, ref bool bypass)
=> bypass = true;
public override void
BypassEvasionStatBoosts(IExecutingMove move, IPokemon target, byte hitIndex, ref bool bypass) => bypass = true;
}

View File

@@ -27,8 +27,7 @@ public class Conversion2 : Script
if (indexOfNext == -1)
return x;
return x.Take(indexOfNext);
})
.SelectMany(x => x)
}).SelectMany(x => x)
// We only want the last move choice by the target
.OfType<IMoveChoice>().FirstOrDefault(x => x.User == target);
if (lastMoveByTarget == null)
@@ -42,11 +41,9 @@ public class Conversion2 : Script
var type = typeLibrary.GetAllEffectivenessFromAttacking(lastMoveByTarget.ChosenMove.MoveData.MoveType)
.Where(x => x.effectiveness < 1)
// Shuffle them randomly, but deterministically
.OrderBy(_ => move.User.BattleData.Battle.Random.GetInt())
.ThenBy(x => x.type.Value)
.OrderBy(_ => move.User.BattleData.Battle.Random.GetInt()).ThenBy(x => x.type.Value)
// And grab the first one
.Select(x => x.type)
.FirstOrDefault();
.Select(x => x.type).FirstOrDefault();
if (type == null)
{
move.GetHitData(target, hit).Fail();

View File

@@ -10,9 +10,7 @@ public class Copycat : Script
/// <inheritdoc />
public override void ChangeMove(IMoveChoice choice, ref StringKey moveName)
{
var lastMove = choice.User.BattleData?.Battle.PreviousTurnChoices
.SelectMany(x => x)
.OfType<IMoveChoice>()
var lastMove = choice.User.BattleData?.Battle.PreviousTurnChoices.SelectMany(x => x).OfType<IMoveChoice>()
.LastOrDefault();
if (lastMove == null || !lastMove.ChosenMove.MoveData.CanCopyMove())
{

View File

@@ -14,7 +14,7 @@ public class CoreEnforcer : Script
return;
var turnChoices = battleData.Battle.PreviousTurnChoices.Last();
var currentChoiceIndex = turnChoices.IndexOf(move.MoveChoice);
if (currentChoiceIndex == -1 ||
if (currentChoiceIndex == -1 ||
!turnChoices.Take(currentChoiceIndex).Any(choice => choice is IMoveChoice or IItemChoice))
{
move.GetHitData(target, hit).Fail();

View File

@@ -16,13 +16,13 @@ public class Defog : Script
"toxic_spikes",
"stealth_rock",
};
/// <inheritdoc />
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (target.BattleData == null)
return;
var targetSide = target.BattleData.Battle.Sides[target.BattleData.SideIndex];
foreach (var effect in DefoggedEffects)
{

View File

@@ -9,17 +9,17 @@ public class Dig : Script
/// <inheritdoc />
public override void PreventMove(IExecutingMove move, ref bool prevent)
{
if (move.User.Volatile.Contains<DigEffect>())
if (move.User.Volatile.Contains<DigEffect>())
return;
move.User.Volatile.Add(new DigEffect(move.User));
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dig_charge", new Dictionary<string, object>()
{
{ "user", move.User }
{ "user", move.User },
}));
prevent = true;
}
/// <inheritdoc />
public override void OnBeforeMove(IExecutingMove move)
{

View File

@@ -13,10 +13,7 @@ public class Disable : Script
if (battleData == null)
return;
var choiceQueue = battleData.Battle.PreviousTurnChoices;
var lastMove = choiceQueue
.SelectMany(x => x)
.OfType<IMoveChoice>()
.LastOrDefault(x => x.User == target);
var lastMove = choiceQueue.SelectMany(x => x).OfType<IMoveChoice>().LastOrDefault(x => x.User == target);
if (lastMove == null)
{
move.GetHitData(target, hit).Fail();

View File

@@ -9,13 +9,13 @@ public class Dive : Script
/// <inheritdoc />
public override void PreventMove(IExecutingMove move, ref bool prevent)
{
if (move.User.Volatile.Contains<DiveEffect>())
if (move.User.Volatile.Contains<DiveEffect>())
return;
move.User.Volatile.Add(new DigEffect(move.User));
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dive_charge", new Dictionary<string, object>()
{
{ "user", move.User }
{ "user", move.User },
}));
prevent = true;
}

View File

@@ -24,7 +24,7 @@ public class DoublePowerIfTargetDamagedInTurn : Script
var battle = move.User.BattleData?.Battle;
if (battle == null)
return;
if (target.BattleData == null)
if (target.BattleData == null)
return;
var side = battle.Sides[target.BattleData.SideIndex];
var data = side.VolatileScripts.Get<DoublePowerIfTargetDamagedInTurnData>();

View File

@@ -7,7 +7,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
public class Drain : Script
{
public float DrainModifier { get; set; } = 0.5f;
/// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{

View File

@@ -9,7 +9,7 @@ public class DreamEater : Script
if (!target.HasStatus("asleep"))
block = true;
}
/// <inheritdoc />
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{

View File

@@ -12,7 +12,8 @@ public class Electrify : Script
if (choiceQueue == null)
return;
if (choiceQueue.FirstOrDefault(x => x is IMoveChoice moveChoice && moveChoice.User == target) is not IMoveChoice choice)
if (choiceQueue.FirstOrDefault(x => x is IMoveChoice moveChoice && moveChoice.User == target) is not IMoveChoice
choice)
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -9,15 +9,15 @@ public class ElectroBall : Script
var user = move.User;
var targetSpeed = target.BoostedStats.Speed;
var userSpeed = user.BoostedStats.Speed;
var ratio = (float) userSpeed / targetSpeed;
var ratio = (float)userSpeed / targetSpeed;
basePower = ratio switch
{
> 4 => 150,
> 3 => 120,
> 2 => 80,
> 1 => 60,
_ => 40
_ => 40,
};
}
}

View File

@@ -14,17 +14,14 @@ public class Encore : Script
return;
var currentTurn = battle.ChoiceQueue!.LastRanChoice;
var lastMove = battle.PreviousTurnChoices
.SelectMany(x => x)
.OfType<IMoveChoice>()
.TakeWhile(x => x != currentTurn)
.LastOrDefault(x => x.User == target);
var lastMove = battle.PreviousTurnChoices.SelectMany(x => x).OfType<IMoveChoice>()
.TakeWhile(x => x != currentTurn).LastOrDefault(x => x.User == target);
if (lastMove == null)
{
move.GetHitData(target, hit).Fail();
return;
}
var effect = new EncoreEffect(target, lastMove.ChosenMove.MoveData.Name, 3);
target.Volatile.Add(effect);
}

View File

@@ -13,13 +13,13 @@ public class Entrainment : Script
move.GetHitData(target, hit).Fail();
return;
}
if (userAbility.HasFlag("cant_be_copied") || targetAbility?.HasFlag("cant_be_changed") != false)
{
move.GetHitData(target, hit).Fail();
return;
}
target.ChangeAbility(userAbility);
}
}

View File

@@ -9,5 +9,4 @@ public class Eruption : Script
{
basePower = Math.Max((byte)(150 * move.User.CurrentHealth / move.User.BoostedStats.Hp), (byte)1);
}
}

View File

@@ -15,7 +15,7 @@ public class Flail : Script
< 10 => 100,
< 17 => 80,
< 33 => 40,
_ => 20
_ => 20,
};
}
}

View File

@@ -17,7 +17,7 @@ public class FlameBurst : Script
adjacentFoe.Damage(adjacentFoe.BoostedStats.Hp / 16, DamageSource.Misc, batchId);
}
}
private static IEnumerable<IPokemon?> GetAdjacentFoes(IPokemon pokemon)
{
var battleData = pokemon.BattleData;

View File

@@ -14,8 +14,7 @@ public class FlareBlitz : Script
{
target.SetStatus("burned");
}
var hitData = move.GetHitData(target, hit);
var recoilDamage = (uint)(hitData.Damage * (1 / 3));
move.User.Damage(recoilDamage, DamageSource.Misc);

View File

@@ -9,13 +9,13 @@ public class Fly : Script
/// <inheritdoc />
public override void PreventMove(IExecutingMove move, ref bool prevent)
{
if (move.User.Volatile.Contains<ChargeFlyEffect>())
if (move.User.Volatile.Contains<ChargeFlyEffect>())
return;
move.User.Volatile.Add(new ChargeFlyEffect(move.User));
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("fly_charge", new Dictionary<string, object>()
{
{ "user", move.User }
{ "user", move.User },
}));
prevent = true;
}

View File

@@ -13,7 +13,7 @@ public class FocusPunch : Script
choice.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_charge",
new Dictionary<string, object>()
{
{ "pokemon", choice.User }
{ "pokemon", choice.User },
}));
}

View File

@@ -10,13 +10,13 @@ public class FollowMe : Script
{
if (targets.Count != 1)
return;
var target = targets[0];
if (target == null)
return;
if (target.BattleData?.SideIndex != moveChoice.User.BattleData?.SideIndex)
return;
targets = [moveChoice.User];
}
}

View File

@@ -18,10 +18,8 @@ public class FreezeDry : Script
if (target.Types.Contains(waterType))
{
var effectivenessWithoutWater = target.Types
.Where(x => x != waterType)
.Select(x => typeLibrary.GetEffectiveness(x, target.Types))
.Aggregate(1f, (a, b) => a * b);
var effectivenessWithoutWater = target.Types.Where(x => x != waterType)
.Select(x => typeLibrary.GetEffectiveness(x, target.Types)).Aggregate(1f, (a, b) => a * b);
effectiveness = effectivenessWithoutWater * 2;
}
}

View File

@@ -17,7 +17,7 @@ public class MultiHitMove : Script
< 35 => 2,
< 70 => 3,
< 85 => 4,
_ => 5
_ => 5,
};
numberOfHits = (byte)newHits;
}

View File

@@ -6,7 +6,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
public class OneHitKo : Script
{
/// <inheritdoc />
public override void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref int modifiedAccuracy)
public override void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex,
ref int modifiedAccuracy)
{
var levelDifference = executingMove.User.Level - target.Level;
if (levelDifference < 0)

View File

@@ -20,7 +20,7 @@ public class ProtectionScript : Script
move.GetHitData(target, hit).Fail();
return;
}
var failure = target.Volatile.Get<ProtectionFailureScript>();
if (failure == null)
{

View File

@@ -8,7 +8,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
public class Recoil : Script
{
private float _recoilPercentage;
/// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{

View File

@@ -25,7 +25,8 @@ public class Struggle : Script
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var damage = move.User.MaxHealth / 4;
if (damage == 0) damage = 1;
move.User.Damage(damage, DamageSource.Struggle, new());
if (damage == 0)
damage = 1;
move.User.Damage(damage, DamageSource.Struggle, new EventBatchId());
}
}

View File

@@ -16,7 +16,7 @@ public class BideEffect : Script
private BideEffect()
{
}
public BideEffect(IPokemon owner)
{
_owner = owner;
@@ -33,7 +33,7 @@ public class BideEffect : Script
{
DamageTaken += oldHealth - newHealth;
}
private ITurnChoice? _choice;
/// <inheritdoc />

View File

@@ -6,8 +6,7 @@ public class BindEffect : Script
private readonly IPokemon? _owner;
private int _turns;
private readonly float _percentOfMaxHealth;
public BindEffect(IPokemon owner, int turns, float percentOfMaxHealth)
{
_owner = owner;
@@ -25,7 +24,7 @@ public class BindEffect : Script
_turns--;
_owner.Damage((uint)(_owner.MaxHealth * _percentOfMaxHealth), DamageSource.Misc);
}
if (_turns <= 0)
if (_turns <= 0)
RemoveSelf();
}

View File

@@ -11,7 +11,7 @@ public class ChargeBounceEffect : Script
{
_owner = owner;
}
/// <inheritdoc />
public override void ForceTurnSelection(byte sideIndex, byte position, ref ITurnChoice? choice)
{

View File

@@ -11,7 +11,7 @@ public class ChargeFlyEffect : Script
{
_owner = owner;
}
/// <inheritdoc />
public override void ForceTurnSelection(byte sideIndex, byte position, ref ITurnChoice? choice)
{

View File

@@ -7,7 +7,7 @@ public class CounterHelperEffect : Script
{
public IPokemon? LastHitBy { get; private set; }
public uint LastDamage { get; private set; }
/// <inheritdoc />
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
{

View File

@@ -11,6 +11,7 @@ public class DigEffect : Script
{
_owner = owner;
}
/// <inheritdoc />
public override void ForceTurnSelection(byte sideIndex, byte position, ref ITurnChoice? choice)
{

View File

@@ -11,6 +11,7 @@ public class DiveEffect : Script
{
_owner = owner;
}
/// <inheritdoc />
public override void ForceTurnSelection(byte sideIndex, byte position, ref ITurnChoice? choice)
{

View File

@@ -6,7 +6,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
public class EmbargoEffect : Script
{
private int _turns = 5;
/// <inheritdoc />
public override void PreventHeldItemConsume(IPokemon pokemon, IItem heldItem, ref bool prevented)
{

View File

@@ -16,7 +16,7 @@ public class EncoreEffect : Script
_move = move;
_turns = turns;
}
/// <inheritdoc />
public override void ForceTurnSelection(byte sideIndex, byte position, ref ITurnChoice? choice)
{
@@ -24,9 +24,8 @@ public class EncoreEffect : Script
choice = TurnChoiceHelper.CreateMoveChoice(_owner, _move, opposingSideIndex, position);
if (choice is IMoveChoice { ChosenMove.CurrentPp: <= 0 } moveChoice)
{
choice =
moveChoice.User.BattleData?.Battle.Library.MiscLibrary.ReplacementChoice(_owner, opposingSideIndex,
position);
choice = moveChoice.User.BattleData?.Battle.Library.MiscLibrary.ReplacementChoice(_owner, opposingSideIndex,
position);
}
}

View File

@@ -6,7 +6,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
public class FocusPunchEffect : Script
{
public bool WasHit { get; private set; }
/// <inheritdoc />
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
{
@@ -14,7 +14,7 @@ public class FocusPunchEffect : Script
target.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_lost_focus",
new Dictionary<string, object>()
{
{ "pokemon", target }
{ "pokemon", target },
}));
}
}

View File

@@ -19,18 +19,18 @@ public class ForesightEffect : Script
typeLibrary.TryGetTypeIdentifier("fighting", out _fightingType);
typeLibrary.TryGetTypeIdentifier("ghost", out _ghostType);
}
/// <inheritdoc />
public override void PreventStatBoostChange(IPokemon target, Statistic stat, sbyte amount, bool selfInflicted, ref bool prevent)
public override void PreventStatBoostChange(IPokemon target, Statistic stat, sbyte amount, bool selfInflicted,
ref bool prevent)
{
if (stat == Statistic.Evasion)
if (stat == Statistic.Evasion)
prevent = true;
}
/// <inheritdoc />
public override void ChangeEffectiveness(IExecutingMove move, IPokemon target, byte hit, ref float effectiveness)
{
var hitData = move.GetHitData(target, hit);
if (hitData.Type == _normalType && target.Types.Contains(_fightingType))
effectiveness = _typeLibrary.GetEffectiveness(_normalType, target.Types.Where(x => x != _ghostType));

View File

@@ -4,12 +4,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
public class GhostCurseEffect : Script
{
private IPokemon _pokemon;
public GhostCurseEffect(IPokemon pokemon)
{
_pokemon = pokemon;
}
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{

View File

@@ -9,7 +9,7 @@ public class HealEachEndOfTurnEffect : Script
private HealEachEndOfTurnEffect()
{
}
public HealEachEndOfTurnEffect(float healPercentage, IPokemon pokemon)
{
_healPercentage = healPercentage;
@@ -24,7 +24,7 @@ public class HealEachEndOfTurnEffect : Script
return;
if (_pokemon.BattleData?.IsOnBattlefield != true)
return;
var amount = _pokemon.BoostedStats.Hp * _healPercentage;
if (_pokemon.HasHeldItem("big_root"))
amount *= 1.3f;

View File

@@ -9,7 +9,7 @@ public class ProtectionFailureScript : Script
{
public int ProtectTurns { get; set; }
public bool UsedProtect { get; set; }
/// <inheritdoc />
public override void OnBeforeTurnStart(ITurnChoice choice)
{

View File

@@ -11,7 +11,7 @@ public class RequiresRechargeEffect : Script
{
_owner = owner;
}
/// <inheritdoc />
public override void ForceTurnSelection(byte sideIndex, byte position, ref ITurnChoice? choice)
{
@@ -25,7 +25,7 @@ public class RequiresRechargeEffect : Script
_owner.BattleData?.Battle.EventHook.Invoke(new DialogEvent("pokemon_must_recharge",
new Dictionary<string, object>()
{
{ "pokemon", _owner }
{ "pokemon", _owner },
}));
}
}

View File

@@ -24,8 +24,10 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Side;
public class AuroraVeilEffect : Script
{
public int NumberOfTurns { get; set; }
private AuroraVeilEffect(){}
private AuroraVeilEffect()
{
}
public AuroraVeilEffect(int numberOfTurns)
{
@@ -56,10 +58,8 @@ public class AuroraVeilEffect : Script
var side = move.User.BattleData!.Battle.Sides[targetSide.Value];
switch (move.UseMove.Category)
{
case MoveCategory.Physical when
side.VolatileScripts.Contains(ScriptUtils.ResolveName<ReflectEffect>()):
case MoveCategory.Special when
side.VolatileScripts.Contains(ScriptUtils.ResolveName<LightScreenEffect>()):
case MoveCategory.Physical when side.VolatileScripts.Contains(ScriptUtils.ResolveName<ReflectEffect>()):
case MoveCategory.Special when side.VolatileScripts.Contains(ScriptUtils.ResolveName<LightScreenEffect>()):
return;
}

View File

@@ -8,7 +8,7 @@ public class CraftyShieldEffect : Script
/// <inheritdoc />
public override void StopBeforeMove(IExecutingMove move, ref bool stop)
{
if (move.UseMove.Category == MoveCategory.Status)
if (move.UseMove.Category == MoveCategory.Status)
stop = true;
}
}

View File

@@ -18,7 +18,7 @@ public class DoomDesireEffect : Script
Turns = 3;
}
}
private readonly IBattleSide? _side;
private List<Target> _targets = new();
@@ -26,12 +26,12 @@ public class DoomDesireEffect : Script
{
_side = side;
}
public void AddTarget(byte position, uint damage)
{
_targets.Add(new Target(position, damage));
}
public bool HasTarget(byte position)
{
return _targets.Exists(x => x.Position == position);
@@ -42,7 +42,7 @@ public class DoomDesireEffect : Script
{
if (_side == null)
return;
var toRemove = new List<Target>();
foreach (var v in _targets)
{

View File

@@ -3,5 +3,4 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Status;
[Script(ScriptCategory.Status, "sleep")]
public class Sleep : Script
{
}

View File

@@ -65,6 +65,6 @@ public static class CopyableMoves
"thief",
"transform",
"trick",
"whirlwind"
"whirlwind",
];
}

View File

@@ -13,7 +13,7 @@ public static class TurnChoiceHelper
{
if (!owner.Library.StaticLibrary.Moves.TryGet(moveName, out var moveData))
throw new Exception($"Move '{moveName}' not found in move library.");
move = new LearnedMoveImpl(moveData, MoveLearnMethod.Unknown);
}
return new MoveChoice(owner, move, targetSide, targetPosition);

View File

@@ -18,7 +18,7 @@ public class Hail : Script
"ice_body",
"magic_guard",
"overcoat",
"snow_cloak"
"snow_cloak",
];
/// <inheritdoc />