diff --git a/PkmnLib.Dynamic/Libraries/DataLoaders/Models/SerializedSpecies.cs b/PkmnLib.Dynamic/Libraries/DataLoaders/Models/SerializedSpecies.cs index 451138e..ff5c935 100644 --- a/PkmnLib.Dynamic/Libraries/DataLoaders/Models/SerializedSpecies.cs +++ b/PkmnLib.Dynamic/Libraries/DataLoaders/Models/SerializedSpecies.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; @@ -111,11 +112,40 @@ public class SerializedForm /// public bool IsBattleOnly { get; set; } + public string? InheritFrom { get; set; } + /// /// Additional data that is not part of the standard form data. /// [JsonExtensionData] public Dictionary? ExtensionData { get; set; } + + [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract"), + SuppressMessage("ReSharper", "NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract")] + internal void MakeInheritFrom(SerializedForm other) + { + Abilities ??= other.Abilities.ToArray(); + HiddenAbilities ??= other.HiddenAbilities.ToArray(); + BaseStats ??= other.BaseStats.Copy(); + EVReward ??= other.EVReward.Copy(); + Types ??= other.Types.ToArray(); + if (Height == 0) + Height = other.Height; + if (Weight == 0) + Weight = other.Weight; + if (BaseExp == 0) + BaseExp = other.BaseExp; + Moves ??= new SerializedMoves(); + if (Moves.LevelMoves == null || Moves.LevelMoves.Length == 0) + Moves.LevelMoves = other.Moves.LevelMoves?.ToArray(); + if (Moves.EggMoves == null || Moves.EggMoves.Length == 0) + Moves.EggMoves = other.Moves.EggMoves?.ToArray(); + if (Moves.TutorMoves == null || Moves.TutorMoves.Length == 0) + Moves.TutorMoves = other.Moves.TutorMoves?.ToArray(); + if (Moves.Machine == null || Moves.Machine.Length == 0) + Moves.Machine = other.Moves.Machine?.ToArray(); + Flags ??= other.Flags.ToArray(); + } } /// @@ -159,6 +189,17 @@ public record SerializedStats /// public ushort Speed { get; set; } + + public SerializedStats Copy() => + new() + { + Hp = Hp, + Attack = Attack, + Defense = Defense, + SpecialAttack = SpecialAttack, + SpecialDefense = SpecialDefense, + Speed = Speed, + }; } /// diff --git a/PkmnLib.Dynamic/Libraries/DataLoaders/SpeciesDataLoader.cs b/PkmnLib.Dynamic/Libraries/DataLoaders/SpeciesDataLoader.cs index 70e0acc..e75107f 100644 --- a/PkmnLib.Dynamic/Libraries/DataLoaders/SpeciesDataLoader.cs +++ b/PkmnLib.Dynamic/Libraries/DataLoaders/SpeciesDataLoader.cs @@ -76,6 +76,20 @@ public static class SpeciesDataLoader $"Egg cycles for species {id} is invalid: {serialized.EggCycles}. Must be greater than or equal to 0."); } + foreach (var form in serialized.Formes) + { + if (!string.IsNullOrEmpty(form.Value.InheritFrom)) + { + var inheritedForm = serialized.Formes.GetValueOrDefault(form.Value.InheritFrom); + if (inheritedForm == null) + { + throw new InvalidDataException( + $"Form {form.Key} inherits from {form.Value.InheritFrom}, but that form does not exist."); + } + form.Value.MakeInheritFrom(inheritedForm); + } + } + var forms = serialized.Formes.ToDictionary(x => (StringKey)x.Key, x => DeserializeForm(x.Key, x.Value, typeLibrary)); var evolutions = serialized.Evolutions.Select(DeserializeEvolution).ToList(); diff --git a/PkmnLib.Dynamic/Models/Pokemon.cs b/PkmnLib.Dynamic/Models/Pokemon.cs index ed95315..37b3a9d 100644 --- a/PkmnLib.Dynamic/Models/Pokemon.cs +++ b/PkmnLib.Dynamic/Models/Pokemon.cs @@ -784,6 +784,7 @@ public class PokemonImpl : ScriptSource, IPokemon { var previous = HeldItem; HeldItem = item; + this.RunScriptHook(x => x.OnAfterHeldItemChange(this, previous, item)); return previous; } @@ -799,6 +800,7 @@ public class PokemonImpl : ScriptSource, IPokemon } var previous = HeldItem; HeldItem = null; + this.RunScriptHook(x => x.OnAfterHeldItemChange(this, previous, null)); return previous; } diff --git a/PkmnLib.Dynamic/ScriptHandling/Script.cs b/PkmnLib.Dynamic/ScriptHandling/Script.cs index ca026d8..ef403c3 100644 --- a/PkmnLib.Dynamic/ScriptHandling/Script.cs +++ b/PkmnLib.Dynamic/ScriptHandling/Script.cs @@ -419,7 +419,7 @@ public abstract class Script : IDeepCloneable } /// - /// This function triggers when an opponent on the field faints. + /// This function triggers when an opponent on the field faints due to the move that is being executed. /// public virtual void OnOpponentFaints(IExecutingMove move, IPokemon target, byte hit) { @@ -794,4 +794,11 @@ public abstract class Script : IDeepCloneable ref bool isContact) { } + + /// + /// This function allows a script to run after a held item has changed. + /// + public virtual void OnAfterHeldItemChange(IPokemon pokemon, IItem? previous, IItem? item) + { + } } \ No newline at end of file diff --git a/PkmnLib.Tests/Dataloader/SpeciesDataloaderTests.cs b/PkmnLib.Tests/Dataloader/SpeciesDataloaderTests.cs index 4e98161..d429a89 100644 --- a/PkmnLib.Tests/Dataloader/SpeciesDataloaderTests.cs +++ b/PkmnLib.Tests/Dataloader/SpeciesDataloaderTests.cs @@ -35,4 +35,43 @@ public class SpeciesDataloaderTests var library = SpeciesDataLoader.LoadSpecies(file, typeLibrary); await Assert.That(library).IsNotNull(); } + + [Test] + public async Task TestPrimarySpeciesFileFormInheritance() + { + IResourceProvider plugin = new Plugin.Gen7.Gen7Plugin(); + var result = plugin.GetResource(ResourceFileType.Species)!; + await using var file = result.Open(); + var typeLibrary = new TypeLibrary(); + typeLibrary.RegisterType("Normal"); + typeLibrary.RegisterType("Fire"); + typeLibrary.RegisterType("Water"); + typeLibrary.RegisterType("Electric"); + typeLibrary.RegisterType("Grass"); + typeLibrary.RegisterType("Ice"); + typeLibrary.RegisterType("Fighting"); + typeLibrary.RegisterType("Poison"); + typeLibrary.RegisterType("Ground"); + typeLibrary.RegisterType("Flying"); + typeLibrary.RegisterType("Psychic"); + typeLibrary.RegisterType("Bug"); + typeLibrary.RegisterType("Rock"); + typeLibrary.RegisterType("Ghost"); + typeLibrary.RegisterType("Dragon"); + typeLibrary.RegisterType("Dark"); + typeLibrary.RegisterType("Steel"); + typeLibrary.RegisterType("Fairy"); + + var library = SpeciesDataLoader.LoadSpecies(file, typeLibrary); + await Assert.That(library).IsNotNull(); + + await Assert.That(library.TryGet("arceus", out var species)).IsTrue(); + await Assert.That(species).IsNotNull(); + await Assert.That(species!.TryGetForm("arceus_fighting", out var form)).IsTrue(); + await Assert.That(form).IsNotNull(); + await Assert.That(form!.Types).HasCount().EqualTo(1); + await Assert.That(form.Types[0].Name).IsEqualTo("fighting"); + await Assert.That(form.Flags).IsEqualTo(species.GetDefaultForm().Flags); + await Assert.That(form.BaseStats).IsEqualTo(species.GetDefaultForm().BaseStats); + } } \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc b/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc index 3beb10c..c1bc5a1 100755 --- a/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc +++ b/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc @@ -369,17 +369,34 @@ "misty_surge": { "effect": "misty_surge" }, - "mold_breaker": {}, - "moody": {}, - "motor_drive": {}, - "moxie": {}, - "multiscale": {}, - "multitype": { - "canBeChanged": false + "mold_breaker": { + "effect": "mold_breaker" + }, + "moody": { + "effect": "moody" + }, + "motor_drive": { + "effect": "motor_drive" + }, + "moxie": { + "effect": "moxie" + }, + "multiscale": { + "effect": "multiscale" + }, + "multitype": { + "canBeChanged": false, + "effect": "multitype" + }, + "mummy": { + "effect": "mummy" + }, + "natural_cure": { + "effect": "natural_cure" + }, + "no_guard": { + "effect": "no_guard" }, - "mummy": {}, - "natural_cure": {}, - "no_guard": {}, "normalize": {}, "oblivious": {}, "overcoat": {}, diff --git a/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json b/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json index 2c52e7a..0f89d5c 100755 --- a/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json +++ b/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json @@ -4450,6 +4450,108 @@ ], "formeChange": [] } + }, + "arceus_fighting": { + "inheritFrom": "default", + "types": [ + "fighting" + ] + }, + "arceus_flying": { + "inheritFrom": "default", + "types": [ + "flying" + ] + }, + "arceus_bug": { + "inheritFrom": "default", + "types": [ + "bug" + ] + }, + "arceus_dark": { + "inheritFrom": "default", + "types": [ + "dark" + ] + }, + "arceus_dragon": { + "inheritFrom": "default", + "types": [ + "dragon" + ] + }, + "arceus_electric": { + "inheritFrom": "default", + "types": [ + "electric" + ] + }, + "arceus_fairy": { + "inheritFrom": "default", + "types": [ + "fairy" + ] + }, + "arceus_fire": { + "inheritFrom": "default", + "types": [ + "fire" + ] + }, + "arceus_ghost": { + "inheritFrom": "default", + "types": [ + "ghost" + ] + }, + "arceus_grass": { + "inheritFrom": "default", + "types": [ + "grass" + ] + }, + "arceus_ground": { + "inheritFrom": "default", + "types": [ + "ground" + ] + }, + "arceus_ice": { + "inheritFrom": "default", + "types": [ + "ice" + ] + }, + "arceus_poison": { + "inheritFrom": "default", + "types": [ + "poison" + ] + }, + "arceus_psychic": { + "inheritFrom": "default", + "types": [ + "psychic" + ] + }, + "arceus_rock": { + "inheritFrom": "default", + "types": [ + "rock" + ] + }, + "arceus_steel": { + "inheritFrom": "default", + "types": [ + "steel" + ] + }, + "arceus_water": { + "inheritFrom": "default", + "types": [ + "water" + ] } }, "evolutions": [] diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/MoldBreaker.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/MoldBreaker.cs new file mode 100644 index 0000000..b2827f9 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/MoldBreaker.cs @@ -0,0 +1,17 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Mold Breaker is an ability that allows moves to ignore the target's abilities. +/// +/// Bulbapedia - Mold Breaker +/// +[Script(ScriptCategory.Ability, "mold_breaker")] +public class MoldBreaker : Script +{ + /// + public override void OnBeforeAnyHookInvoked(ref List? suppressedCategories) + { + suppressedCategories ??= []; + suppressedCategories.Add(ScriptCategory.Ability); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Moody.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Moody.cs new file mode 100644 index 0000000..c22a874 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Moody.cs @@ -0,0 +1,55 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Moody is an ability that raises one stat and lowers another at the end of each turn. +/// +/// Bulbapedia - Moody +/// +[Script(ScriptCategory.Ability, "moody")] +public class Moody : Script +{ + private IPokemon? _pokemon; + + /// + public override void OnAddedToParent(IScriptSource source) + { + if (source is not IPokemon pokemon) + throw new InvalidOperationException("Moody script must be attached to a Pokemon."); + _pokemon = pokemon; + } + + /// + public override void OnEndTurn(IBattle battle) + { + if (_pokemon == null) + return; + + var stats = _pokemon.StatBoost; + Statistic? raiseStat = null; + + var possibleStatsToRaise = stats.Where(x => x is + { value: < 6, statistic: not Statistic.Accuracy and not Statistic.Evasion and not Statistic.Hp }) + .Select(x => x.statistic).ToList(); + if (possibleStatsToRaise.Count > 0) + { + raiseStat = possibleStatsToRaise[battle.Random.GetInt(possibleStatsToRaise.Count)]; + } + + Statistic? lowerStat = null; + var possibleStatsToLower = stats.Where(x => x is + { + value: > -6, + statistic: not Statistic.Accuracy and not Statistic.Evasion and not Statistic.Hp, + } && x.statistic != raiseStat).Select(x => x.statistic).ToList(); + + if (possibleStatsToLower.Count > 0) + { + lowerStat = possibleStatsToLower[battle.Random.GetInt(possibleStatsToLower.Count)]; + } + + if (raiseStat != null) + _pokemon.ChangeStatBoost(raiseStat.Value, 1, true, false); + if (lowerStat != null) + _pokemon.ChangeStatBoost(lowerStat.Value, -1, true, false); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/MotorDrive.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/MotorDrive.cs new file mode 100644 index 0000000..d43d333 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/MotorDrive.cs @@ -0,0 +1,20 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Motor Drive is an ability that grants immunity to Electric-type moves and raises Speed when hit by one. +/// +/// Bulbapedia - Motor Drive +/// +[Script(ScriptCategory.Ability, "motor_drive")] +public class MotorDrive : Script +{ + /// + public override void IsInvulnerableToMove(IExecutingMove move, IPokemon target, ref bool invulnerable) + { + if (move.UseMove.MoveType.Name != "electric") + return; + invulnerable = true; + move.Battle.EventHook.Invoke(new AbilityTriggerEvent(target)); + target.ChangeStatBoost(Statistic.Speed, 1, true, false); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Moxie.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Moxie.cs new file mode 100644 index 0000000..f5bd48a --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Moxie.cs @@ -0,0 +1,16 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Moxie is an ability that raises the user's Attack stat after knocking out a Pokémon. +/// +/// Bulbapedia - Moxie +/// +[Script(ScriptCategory.Ability, "moxie")] +public class Moxie : Script +{ + /// + public override void OnOpponentFaints(IExecutingMove move, IPokemon target, byte hit) + { + move.User.ChangeStatBoost(Statistic.Attack, 1, true, false); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Multiscale.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Multiscale.cs new file mode 100644 index 0000000..7258940 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Multiscale.cs @@ -0,0 +1,19 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Multiscale is an ability that reduces damage taken when at full HP. +/// +/// Bulbapedia - Multiscale +/// +[Script(ScriptCategory.Ability, "multiscale")] +public class Multiscale : Script +{ + /// + public override void ChangeIncomingMoveDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage) + { + if (target.CurrentHealth == target.BoostedStats.Hp) + { + damage = (uint)(damage * 0.5); + } + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Multitype.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Multitype.cs new file mode 100644 index 0000000..d3f1776 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Multitype.cs @@ -0,0 +1,79 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Multitype is an ability that changes the Pokémon's type based on its held Plate or Z-Crystal. +/// +/// Bulbapedia - Multitype +/// +[Script(ScriptCategory.Ability, "multitype")] +public class Multitype : Script +{ + /// + public override void OnAfterHeldItemChange(IPokemon pokemon, IItem? previous, IItem? item) + { + if (pokemon.Species.Name != "arceus") + return; + if (item is null && pokemon.Form.Name != "default") + { + pokemon.ChangeForm(pokemon.Species.GetDefaultForm()); + } + else if (item is not null && item.Name.ToString().EndsWith("_plate", StringComparison.OrdinalIgnoreCase)) + { + var platePrefix = item.Name.ToString().Replace("_plate", string.Empty, StringComparison.OrdinalIgnoreCase); + switch (platePrefix) + { + case "fist" when pokemon.Species.TryGetForm("arceus_fighting", out var fightingForm): + pokemon.ChangeForm(fightingForm); + break; + case "flame" when pokemon.Species.TryGetForm("arceus_fire", out var fireForm): + pokemon.ChangeForm(fireForm); + break; + case "shock" when pokemon.Species.TryGetForm("arceus_electric", out var electricForm): + pokemon.ChangeForm(electricForm); + break; + case "draco" when pokemon.Species.TryGetForm("arceus_dragon", out var dragonForm): + pokemon.ChangeForm(dragonForm); + break; + case "dread" when pokemon.Species.TryGetForm("arceus_dark", out var darkForm): + pokemon.ChangeForm(darkForm); + break; + case "earth" when pokemon.Species.TryGetForm("arceus_ground", out var groundForm): + pokemon.ChangeForm(groundForm); + break; + case "icicle" when pokemon.Species.TryGetForm("arceus_ice", out var iceForm): + pokemon.ChangeForm(iceForm); + break; + case "insect" when pokemon.Species.TryGetForm("arceus_bug", out var bugForm): + pokemon.ChangeForm(bugForm); + break; + case "iron" when pokemon.Species.TryGetForm("arceus_steel", out var steelForm): + pokemon.ChangeForm(steelForm); + break; + case "meadow" when pokemon.Species.TryGetForm("arceus_grass", out var grassForm): + pokemon.ChangeForm(grassForm); + break; + case "mind" when pokemon.Species.TryGetForm("arceus_psychic", out var psychicForm): + pokemon.ChangeForm(psychicForm); + break; + case "pixie" when pokemon.Species.TryGetForm("arceus_fairy", out var fairyForm): + pokemon.ChangeForm(fairyForm); + break; + case "sky" when pokemon.Species.TryGetForm("arceus_flying", out var flyingForm): + pokemon.ChangeForm(flyingForm); + break; + case "splash" when pokemon.Species.TryGetForm("arceus_water", out var waterForm): + pokemon.ChangeForm(waterForm); + break; + case "spooky" when pokemon.Species.TryGetForm("arceus_ghost", out var ghostForm): + pokemon.ChangeForm(ghostForm); + break; + case "stone" when pokemon.Species.TryGetForm("arceus_rock", out var rockForm): + pokemon.ChangeForm(rockForm); + break; + case "toxic" when pokemon.Species.TryGetForm("arceus_poison", out var poisonForm): + pokemon.ChangeForm(poisonForm); + break; + } + } + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Mummy.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Mummy.cs new file mode 100644 index 0000000..83ad8ae --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Mummy.cs @@ -0,0 +1,21 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Mummy is an ability that changes the attacker's ability to Mummy if it makes contact. +/// +/// Bulbapedia - Mummy +/// +[Script(ScriptCategory.Ability, "mummy")] +public class Mummy : Script +{ + /// + public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit) + { + if (!move.GetHitData(target, hit).IsContact || move.User.ActiveAbility?.Name == "mummy" || + !move.Battle.Library.StaticLibrary.Abilities.TryGet("mummy", out var mummyAbility)) + return; + + move.Battle.EventHook.Invoke(new AbilityTriggerEvent(target)); + move.User.ChangeAbility(mummyAbility); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/NaturalCure.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/NaturalCure.cs new file mode 100644 index 0000000..29b9665 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/NaturalCure.cs @@ -0,0 +1,20 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Natural Cure is an ability that heals status conditions when switching out. +/// +/// Bulbapedia - Natural Cure +/// +[Script(ScriptCategory.Ability, "natural_cure")] +public class NaturalCure : Script +{ + /// + public override void OnSwitchOut(IPokemon oldPokemon, byte position) + { + if (!oldPokemon.StatusScript.IsEmpty) + { + oldPokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(oldPokemon)); + oldPokemon.ClearStatus(); + } + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/NoGuard.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/NoGuard.cs new file mode 100644 index 0000000..e7b4c71 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/NoGuard.cs @@ -0,0 +1,24 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// No Guard is an ability that ensures all moves used by and against the Pokémon hit without fail. +/// +/// Bulbapedia - No Guard +/// +[Script(ScriptCategory.Ability, "no_guard")] +public class NoGuard : Script +{ + /// + public override void ChangeIncomingAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, + ref int modifiedAccuracy) + { + modifiedAccuracy = 2000; + } + + /// + public override void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, + ref int modifiedAccuracy) + { + modifiedAccuracy = 2000; + } +} \ No newline at end of file