More move scripts
This commit is contained in:
parent
f8c43b6ba0
commit
1973ff50fa
@ -10,7 +10,7 @@
|
|||||||
"rollForward": false
|
"rollForward": false
|
||||||
},
|
},
|
||||||
"jetbrains.resharper.globaltools": {
|
"jetbrains.resharper.globaltools": {
|
||||||
"version": "2024.3.6",
|
"version": "2025.1.1",
|
||||||
"commands": [
|
"commands": [
|
||||||
"jb"
|
"jb"
|
||||||
],
|
],
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<WarningsAsErrors>nullable</WarningsAsErrors>
|
||||||
<UseArtifactsOutput>true</UseArtifactsOutput>
|
<UseArtifactsOutput>true</UseArtifactsOutput>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ public class BattleImpl : ScriptSource, IBattle
|
|||||||
CanFlee = canFlee;
|
CanFlee = canFlee;
|
||||||
NumberOfSides = numberOfSides;
|
NumberOfSides = numberOfSides;
|
||||||
PositionsPerSide = positionsPerSide;
|
PositionsPerSide = positionsPerSide;
|
||||||
|
Volatile = new ScriptSet(this);
|
||||||
var sides = new IBattleSide[numberOfSides];
|
var sides = new IBattleSide[numberOfSides];
|
||||||
for (byte i = 0; i < numberOfSides; i++)
|
for (byte i = 0; i < numberOfSides; i++)
|
||||||
sides[i] = new BattleSideImpl(i, positionsPerSide, this);
|
sides[i] = new BattleSideImpl(i, positionsPerSide, this);
|
||||||
@ -399,7 +400,7 @@ public class BattleImpl : ScriptSource, IBattle
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IScriptSet Volatile { get; } = new ScriptSet();
|
public IScriptSet Volatile { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public StringKey? WeatherName => WeatherScript.Script?.Name;
|
public StringKey? WeatherName => WeatherScript.Script?.Name;
|
||||||
|
@ -132,6 +132,9 @@ public class BattleChoiceQueue : IDeepCloneable
|
|||||||
public ITurnChoice? FirstOrDefault(Func<ITurnChoice, bool> predicate) =>
|
public ITurnChoice? FirstOrDefault(Func<ITurnChoice, bool> predicate) =>
|
||||||
_choices.Skip(_currentIndex).WhereNotNull().FirstOrDefault(predicate);
|
_choices.Skip(_currentIndex).WhereNotNull().FirstOrDefault(predicate);
|
||||||
|
|
||||||
|
public IEnumerable<ITurnChoice> Where(Func<ITurnChoice, bool> predicate) =>
|
||||||
|
_choices.Skip(_currentIndex).WhereNotNull().Where(predicate);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a choice from the queue.
|
/// Removes a choice from the queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -174,7 +174,7 @@ public class BattleSideImpl : ScriptSource, IBattleSide
|
|||||||
_fillablePositions[i] = true;
|
_fillablePositions[i] = true;
|
||||||
}
|
}
|
||||||
Battle = battle;
|
Battle = battle;
|
||||||
VolatileScripts = new ScriptSet();
|
VolatileScripts = new ScriptSet(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -55,6 +55,7 @@ public class MoveChoice : TurnChoice, IMoveChoice
|
|||||||
ChosenMove = usedMove;
|
ChosenMove = usedMove;
|
||||||
TargetSide = targetSide;
|
TargetSide = targetSide;
|
||||||
TargetPosition = targetPosition;
|
TargetPosition = targetPosition;
|
||||||
|
Volatile = new ScriptSet(this);
|
||||||
|
|
||||||
var secondaryEffect = usedMove.MoveData.SecondaryEffect;
|
var secondaryEffect = usedMove.MoveData.SecondaryEffect;
|
||||||
if (secondaryEffect != null)
|
if (secondaryEffect != null)
|
||||||
@ -86,7 +87,7 @@ public class MoveChoice : TurnChoice, IMoveChoice
|
|||||||
public Dictionary<StringKey, object?>? AdditionalData { get; }
|
public Dictionary<StringKey, object?>? AdditionalData { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IScriptSet Volatile { get; } = new ScriptSet();
|
public IScriptSet Volatile { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override int ScriptCount => 2 + User.ScriptCount;
|
public override int ScriptCount => 2 + User.ScriptCount;
|
||||||
|
@ -37,6 +37,11 @@ public enum MoveLearnMethod
|
|||||||
/// The move is learned when the Pokémon changes form.
|
/// The move is learned when the Pokémon changes form.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
FormChange,
|
FormChange,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The move is learned by using a move sketch.
|
||||||
|
/// </summary>
|
||||||
|
Sketch,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -487,6 +487,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||||||
WeightInKg = form.Weight;
|
WeightInKg = form.Weight;
|
||||||
HeightInMeters = form.Height;
|
HeightInMeters = form.Height;
|
||||||
Happiness = species.BaseHappiness;
|
Happiness = species.BaseHappiness;
|
||||||
|
Volatile = new ScriptSet(this);
|
||||||
if (!library.StaticLibrary.Natures.TryGet(natureName, out var nature))
|
if (!library.StaticLibrary.Natures.TryGet(natureName, out var nature))
|
||||||
throw new KeyNotFoundException($"Nature {natureName} not found.");
|
throw new KeyNotFoundException($"Nature {natureName} not found.");
|
||||||
Nature = nature;
|
Nature = nature;
|
||||||
@ -532,6 +533,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||||||
AbilityIndex = form.FindAbilityIndex(ability) ??
|
AbilityIndex = form.FindAbilityIndex(ability) ??
|
||||||
throw new KeyNotFoundException(
|
throw new KeyNotFoundException(
|
||||||
$"Ability {ability.Name} not found on species {species.Name} form {form.Name}.");
|
$"Ability {ability.Name} not found on species {species.Name} form {form.Name}.");
|
||||||
|
Volatile = new ScriptSet(this);
|
||||||
_learnedMoves = serializedPokemon.Moves.Select(move =>
|
_learnedMoves = serializedPokemon.Moves.Select(move =>
|
||||||
{
|
{
|
||||||
if (move == null)
|
if (move == null)
|
||||||
@ -736,7 +738,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||||||
public ScriptContainer StatusScript { get; } = new();
|
public ScriptContainer StatusScript { get; } = new();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IScriptSet Volatile { get; } = new ScriptSet();
|
public IScriptSet Volatile { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool HasHeldItem(StringKey itemName) => HeldItem?.Name == itemName;
|
public bool HasHeldItem(StringKey itemName) => HeldItem?.Name == itemName;
|
||||||
@ -1097,6 +1099,11 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||||||
{
|
{
|
||||||
if (!Library.ScriptResolver.TryResolve(ScriptCategory.Status, status, null, out var statusScript))
|
if (!Library.ScriptResolver.TryResolve(ScriptCategory.Status, status, null, out var statusScript))
|
||||||
throw new KeyNotFoundException($"Status script {status} not found");
|
throw new KeyNotFoundException($"Status script {status} not found");
|
||||||
|
var preventStatus = false;
|
||||||
|
this.RunScriptHook(script => script.PreventStatusChange(this, status, ref preventStatus));
|
||||||
|
if (preventStatus)
|
||||||
|
return false;
|
||||||
|
|
||||||
StatusScript.Set(statusScript);
|
StatusScript.Set(statusScript);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
using PkmnLib.Dynamic.Models;
|
using PkmnLib.Dynamic.Models;
|
||||||
using PkmnLib.Dynamic.Models.Choices;
|
using PkmnLib.Dynamic.Models.Choices;
|
||||||
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
@ -12,6 +13,7 @@ namespace PkmnLib.Dynamic.ScriptHandling;
|
|||||||
/// changes. This allows for easily defining generational differences, and add effects that the
|
/// changes. This allows for easily defining generational differences, and add effects that the
|
||||||
/// developer might require.
|
/// developer might require.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DebuggerDisplay("{Category} - {Name}")]
|
||||||
public abstract class Script : IDeepCloneable
|
public abstract class Script : IDeepCloneable
|
||||||
{
|
{
|
||||||
internal event Action<Script>? OnRemoveEvent;
|
internal event Action<Script>? OnRemoveEvent;
|
||||||
@ -683,4 +685,12 @@ public abstract class Script : IDeepCloneable
|
|||||||
public virtual void OnBeforeHit(IExecutingMove move, IPokemon target, byte hitIndex)
|
public virtual void OnBeforeHit(IExecutingMove move, IPokemon target, byte hitIndex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void PreventStatusChange(IPokemon pokemonImpl, StringKey status, ref bool preventStatus)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void PreventVolatileAdd(Script script, ref bool preventVolatileAdd)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
using PkmnLib.Static.Utils;
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
@ -14,8 +15,11 @@ public interface IScriptSet : IEnumerable<ScriptContainer>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a script to the set. If the script with that name already exists in this set, this
|
/// Adds a script to the set. If the script with that name already exists in this set, this
|
||||||
/// makes that script stack instead. The return value here is that script.
|
/// makes that script stack instead. The return value here is that script.
|
||||||
|
/// If the script was blocked from being added, this will return null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ScriptContainer Add(Script script);
|
/// <param name="script">The script to add.</param>
|
||||||
|
/// <param name="forceAdd">If true, the script cannot be blocked, and will always be added</param>
|
||||||
|
ScriptContainer? Add(Script script, bool forceAdd = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a script with a name to the set. If the script with that name already exists in this
|
/// Adds a script with a name to the set. If the script with that name already exists in this
|
||||||
@ -77,8 +81,15 @@ public interface IScriptSet : IEnumerable<ScriptContainer>
|
|||||||
/// <inheritdoc cref="IScriptSet"/>
|
/// <inheritdoc cref="IScriptSet"/>
|
||||||
public class ScriptSet : IScriptSet
|
public class ScriptSet : IScriptSet
|
||||||
{
|
{
|
||||||
|
private IScriptSource _source;
|
||||||
|
|
||||||
private readonly List<ScriptContainer> _scripts = [];
|
private readonly List<ScriptContainer> _scripts = [];
|
||||||
|
|
||||||
|
public ScriptSet(IScriptSource source)
|
||||||
|
{
|
||||||
|
_source = source;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerator<ScriptContainer> GetEnumerator() => _scripts.GetEnumerator();
|
public IEnumerator<ScriptContainer> GetEnumerator() => _scripts.GetEnumerator();
|
||||||
|
|
||||||
@ -86,8 +97,16 @@ public class ScriptSet : IScriptSet
|
|||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ScriptContainer Add(Script script)
|
public ScriptContainer? Add(Script script, bool forceAdd = false)
|
||||||
{
|
{
|
||||||
|
if (!forceAdd)
|
||||||
|
{
|
||||||
|
var preventVolatileAdd = false;
|
||||||
|
_source.RunScriptHook(x => x.PreventVolatileAdd(script, ref preventVolatileAdd));
|
||||||
|
if (preventVolatileAdd)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var existing = _scripts.FirstOrDefault(s => s.Script?.Name == script.Name);
|
var existing = _scripts.FirstOrDefault(s => s.Script?.Name == script.Name);
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
{
|
{
|
||||||
|
57
PkmnLib.NET.sln
Normal file
57
PkmnLib.NET.sln
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkmnLib.Static", "PkmnLib.Static\PkmnLib.Static.csproj", "{312782DA-1066-4490-BD0E-DF4DF8713B4A}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkmnLib.Tests", "PkmnLib.Tests\PkmnLib.Tests.csproj", "{42DE3095-0468-4827-AF5C-691C94BA7F92}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkmnLib.Dynamic", "PkmnLib.Dynamic\PkmnLib.Dynamic.csproj", "{D0CBA9A9-7288-41B4-B76B-CB4F20036AB2}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkmnLib.Plugin.Gen7", "Plugins\PkmnLib.Plugin.Gen7\PkmnLib.Plugin.Gen7.csproj", "{FA5380F0-28CC-4AEC-8963-814B347A89BA}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{63C1B450-DC26-444A-AEBD-15979F3EEE53}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkmnLib.Plugin.Gen7.Tests", "Plugins\PkmnLib.Plugin.Gen7.Tests\PkmnLib.Plugin.Gen7.Tests.csproj", "{FBB53861-081F-4DAC-B006-79EE238D0DFC}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkmnLib.Dataloader", "PkmnLib.Dataloader\PkmnLib.Dataloader.csproj", "{E6A733FD-C2A3-4206-B9A9-40DBFBDBE1AC}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionFiles", "SolutionFiles", "{2B99ADF8-10E2-4A3D-906F-27DC8E312A79}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
.editorconfig = .editorconfig
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{312782DA-1066-4490-BD0E-DF4DF8713B4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{312782DA-1066-4490-BD0E-DF4DF8713B4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{312782DA-1066-4490-BD0E-DF4DF8713B4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{312782DA-1066-4490-BD0E-DF4DF8713B4A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{42DE3095-0468-4827-AF5C-691C94BA7F92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{42DE3095-0468-4827-AF5C-691C94BA7F92}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{42DE3095-0468-4827-AF5C-691C94BA7F92}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{42DE3095-0468-4827-AF5C-691C94BA7F92}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D0CBA9A9-7288-41B4-B76B-CB4F20036AB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D0CBA9A9-7288-41B4-B76B-CB4F20036AB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D0CBA9A9-7288-41B4-B76B-CB4F20036AB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D0CBA9A9-7288-41B4-B76B-CB4F20036AB2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FA5380F0-28CC-4AEC-8963-814B347A89BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FA5380F0-28CC-4AEC-8963-814B347A89BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FA5380F0-28CC-4AEC-8963-814B347A89BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FA5380F0-28CC-4AEC-8963-814B347A89BA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FBB53861-081F-4DAC-B006-79EE238D0DFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FBB53861-081F-4DAC-B006-79EE238D0DFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FBB53861-081F-4DAC-B006-79EE238D0DFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FBB53861-081F-4DAC-B006-79EE238D0DFC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E6A733FD-C2A3-4206-B9A9-40DBFBDBE1AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E6A733FD-C2A3-4206-B9A9-40DBFBDBE1AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E6A733FD-C2A3-4206-B9A9-40DBFBDBE1AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E6A733FD-C2A3-4206-B9A9-40DBFBDBE1AC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{FA5380F0-28CC-4AEC-8963-814B347A89BA} = {63C1B450-DC26-444A-AEBD-15979F3EEE53}
|
||||||
|
{FBB53861-081F-4DAC-B006-79EE238D0DFC} = {63C1B450-DC26-444A-AEBD-15979F3EEE53}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
@ -4,7 +4,6 @@
|
|||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -1570,7 +1570,8 @@
|
|||||||
"mirror",
|
"mirror",
|
||||||
"sound",
|
"sound",
|
||||||
"distance",
|
"distance",
|
||||||
"ignore-substitute"
|
"ignore-substitute",
|
||||||
|
"not_sketchable"
|
||||||
],
|
],
|
||||||
"effect": {
|
"effect": {
|
||||||
"name": "confuse"
|
"name": "confuse"
|
||||||
@ -3739,10 +3740,9 @@
|
|||||||
"defrost"
|
"defrost"
|
||||||
],
|
],
|
||||||
"effect": {
|
"effect": {
|
||||||
"name": "set_status",
|
"name": "flame_wheel",
|
||||||
"chance": 10,
|
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"status": "burned"
|
"burn_chance": 10.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -9249,7 +9249,13 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"defrost"
|
"defrost"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "flame_wheel",
|
||||||
|
"parameters": {
|
||||||
|
"burn_chance": 50.0
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sacred_sword",
|
"name": "sacred_sword",
|
||||||
@ -9264,7 +9270,10 @@
|
|||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "chip_away"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "safeguard",
|
"name": "safeguard",
|
||||||
@ -9277,7 +9286,10 @@
|
|||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "safeguard"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sand_attack",
|
"name": "sand_attack",
|
||||||
@ -9292,7 +9304,13 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_accuracy",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sand_tomb",
|
"name": "sand_tomb",
|
||||||
@ -9306,7 +9324,10 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "bind"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sandstorm",
|
"name": "sandstorm",
|
||||||
@ -9317,7 +9338,13 @@
|
|||||||
"priority": 0,
|
"priority": 0,
|
||||||
"target": "All",
|
"target": "All",
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": []
|
"flags": [],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_weather",
|
||||||
|
"parameters": {
|
||||||
|
"weather": "sandstorm"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "savage_spin_out__physical",
|
"name": "savage_spin_out__physical",
|
||||||
@ -9329,6 +9356,7 @@
|
|||||||
"target": "Any",
|
"target": "Any",
|
||||||
"category": "physical",
|
"category": "physical",
|
||||||
"flags": []
|
"flags": []
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "savage_spin_out__special",
|
"name": "savage_spin_out__special",
|
||||||
@ -9340,6 +9368,7 @@
|
|||||||
"target": "Any",
|
"target": "Any",
|
||||||
"category": "special",
|
"category": "special",
|
||||||
"flags": []
|
"flags": []
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scald",
|
"name": "scald",
|
||||||
@ -9354,7 +9383,14 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"defrost"
|
"defrost"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"chance": 30,
|
||||||
|
"parameters": {
|
||||||
|
"status": "burned"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scary_face",
|
"name": "scary_face",
|
||||||
@ -9369,7 +9405,13 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_speed",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -2
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scratch",
|
"name": "scratch",
|
||||||
@ -9385,6 +9427,7 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "screech",
|
"name": "screech",
|
||||||
@ -9401,7 +9444,13 @@
|
|||||||
"mirror",
|
"mirror",
|
||||||
"sound",
|
"sound",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_defense",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "searing_shot",
|
"name": "searing_shot",
|
||||||
@ -9415,7 +9464,14 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"chance": 30,
|
||||||
|
"parameters": {
|
||||||
|
"status": "burned"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "secret_power",
|
"name": "secret_power",
|
||||||
@ -9429,7 +9485,10 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "secret_power"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "secret_sword",
|
"name": "secret_sword",
|
||||||
@ -9443,7 +9502,10 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "psyshock"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "seed_bomb",
|
"name": "seed_bomb",
|
||||||
@ -9459,6 +9521,7 @@
|
|||||||
"mirror",
|
"mirror",
|
||||||
"ballistics"
|
"ballistics"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "seed_flare",
|
"name": "seed_flare",
|
||||||
@ -9472,7 +9535,14 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_special_defense",
|
||||||
|
"chance": 40,
|
||||||
|
"parameters": {
|
||||||
|
"amount": -2
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "seismic_toss",
|
"name": "seismic_toss",
|
||||||
@ -9488,7 +9558,10 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"nonskybattle"
|
"nonskybattle"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "night_shade"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "self_destruct",
|
"name": "self_destruct",
|
||||||
@ -9502,7 +9575,10 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "self_destruct"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shadow_ball",
|
"name": "shadow_ball",
|
||||||
@ -9517,7 +9593,14 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"ballistics"
|
"ballistics"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_special_defense",
|
||||||
|
"chance": 20,
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shadow_bone",
|
"name": "shadow_bone",
|
||||||
@ -9531,7 +9614,14 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_defense",
|
||||||
|
"chance": 20,
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shadow_claw",
|
"name": "shadow_claw",
|
||||||
@ -9546,7 +9636,10 @@
|
|||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "increased_critical_stage"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shadow_force",
|
"name": "shadow_force",
|
||||||
@ -9561,14 +9654,17 @@
|
|||||||
"contact",
|
"contact",
|
||||||
"charge",
|
"charge",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "shadow_force"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shadow_punch",
|
"name": "shadow_punch",
|
||||||
"type": "ghost",
|
"type": "ghost",
|
||||||
"power": 60,
|
"power": 60,
|
||||||
"pp": 20,
|
"pp": 20,
|
||||||
"accuracy": 0,
|
"accuracy": 255,
|
||||||
"priority": 0,
|
"priority": 0,
|
||||||
"target": "Any",
|
"target": "Any",
|
||||||
"category": "physical",
|
"category": "physical",
|
||||||
@ -9578,6 +9674,7 @@
|
|||||||
"mirror",
|
"mirror",
|
||||||
"punch"
|
"punch"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shadow_sneak",
|
"name": "shadow_sneak",
|
||||||
@ -9593,6 +9690,7 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sharpen",
|
"name": "sharpen",
|
||||||
@ -9605,7 +9703,13 @@
|
|||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_attack",
|
||||||
|
"parameters": {
|
||||||
|
"amount": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shattered_psyche__physical",
|
"name": "shattered_psyche__physical",
|
||||||
@ -9617,6 +9721,7 @@
|
|||||||
"target": "Any",
|
"target": "Any",
|
||||||
"category": "physical",
|
"category": "physical",
|
||||||
"flags": []
|
"flags": []
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shattered_psyche__special",
|
"name": "shattered_psyche__special",
|
||||||
@ -9628,6 +9733,7 @@
|
|||||||
"target": "Any",
|
"target": "Any",
|
||||||
"category": "special",
|
"category": "special",
|
||||||
"flags": []
|
"flags": []
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sheer_cold",
|
"name": "sheer_cold",
|
||||||
@ -9641,7 +9747,10 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "one_hit_ko"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shell_smash",
|
"name": "shell_smash",
|
||||||
@ -9654,7 +9763,10 @@
|
|||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "shell_smash"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shell_trap",
|
"name": "shell_trap",
|
||||||
@ -9667,7 +9779,10 @@
|
|||||||
"category": "special",
|
"category": "special",
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect"
|
"protect"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "shell_trap"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shift_gear",
|
"name": "shift_gear",
|
||||||
@ -9680,14 +9795,21 @@
|
|||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_multiple_user_stat_boosts",
|
||||||
|
"parameters": {
|
||||||
|
"attack": 1,
|
||||||
|
"speed": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shock_wave",
|
"name": "shock_wave",
|
||||||
"type": "electric",
|
"type": "electric",
|
||||||
"power": 60,
|
"power": 60,
|
||||||
"pp": 20,
|
"pp": 20,
|
||||||
"accuracy": 0,
|
"accuracy": 255,
|
||||||
"priority": 0,
|
"priority": 0,
|
||||||
"target": "Any",
|
"target": "Any",
|
||||||
"category": "special",
|
"category": "special",
|
||||||
@ -9695,6 +9817,7 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shore_up",
|
"name": "shore_up",
|
||||||
@ -9708,7 +9831,10 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"snatch",
|
"snatch",
|
||||||
"heal"
|
"heal"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "shore_up"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "signal_beam",
|
"name": "signal_beam",
|
||||||
@ -9722,7 +9848,11 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "confuse",
|
||||||
|
"chance": 10
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "silver_wind",
|
"name": "silver_wind",
|
||||||
@ -9736,7 +9866,18 @@
|
|||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_multiple_user_stat_boosts",
|
||||||
|
"chance": 10,
|
||||||
|
"parameters": {
|
||||||
|
"attack": 1,
|
||||||
|
"defense": 1,
|
||||||
|
"specialAttack": 1,
|
||||||
|
"specialDefense": 1,
|
||||||
|
"speed": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "simple_beam",
|
"name": "simple_beam",
|
||||||
@ -9751,7 +9892,10 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "simple_beam"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sing",
|
"name": "sing",
|
||||||
@ -9768,7 +9912,13 @@
|
|||||||
"mirror",
|
"mirror",
|
||||||
"sound",
|
"sound",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"parameters": {
|
||||||
|
"status": "sleep"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sinister_arrow_raid",
|
"name": "sinister_arrow_raid",
|
||||||
@ -9780,6 +9930,7 @@
|
|||||||
"target": "Any",
|
"target": "Any",
|
||||||
"category": "physical",
|
"category": "physical",
|
||||||
"flags": []
|
"flags": []
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sketch",
|
"name": "sketch",
|
||||||
@ -9792,7 +9943,10 @@
|
|||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "sketch"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "skill_swap",
|
"name": "skill_swap",
|
||||||
@ -9807,7 +9961,10 @@
|
|||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "skill_swap"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "skull_bash",
|
"name": "skull_bash",
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
using System.Text.Json.Nodes;
|
||||||
using PkmnLib.Dynamic.Libraries;
|
using PkmnLib.Dynamic.Libraries;
|
||||||
using PkmnLib.Dynamic.ScriptHandling;
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
using PkmnLib.Static.Moves;
|
using PkmnLib.Static.Moves;
|
||||||
using PkmnLib.Tests.Integration;
|
using PkmnLib.Tests.Integration;
|
||||||
|
using TUnit.Core.Logging;
|
||||||
|
|
||||||
namespace PkmnLib.Tests.DataTests;
|
namespace PkmnLib.Tests.DataTests;
|
||||||
|
|
||||||
@ -39,6 +41,17 @@ public class MoveDataTests
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
// Helper method to find the line number of the effect in the JSON file
|
||||||
|
var file = Path.GetFullPath("../../../../PkmnLib.Tests/Data/Moves.jsonc");
|
||||||
|
var json = await File.ReadAllLinesAsync(file);
|
||||||
|
var moveLineNumber = json.Select((line, index) => new { line, index })
|
||||||
|
.FirstOrDefault(x => x.line.Contains($"\"name\": \"{test.Move.Name}\""))?.index + 1;
|
||||||
|
var effectLineNumber = moveLineNumber + json.Skip(moveLineNumber ?? 0)
|
||||||
|
.Select((line, index) => new { line, index }).FirstOrDefault(x => x.line.Contains("effect"))
|
||||||
|
?.index +
|
||||||
|
1 ?? 0;
|
||||||
|
|
||||||
|
await TestContext.Current!.OutputWriter.WriteLineAsync("File: " + $"file://{file}:{effectLineNumber}");
|
||||||
throw new AggregateException($"Failed to resolve script for move {test.Move.Name} with effect {scriptName}",
|
throw new AggregateException($"Failed to resolve script for move {test.Move.Name} with effect {scriptName}",
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public class SerializationTests
|
|||||||
var library = LibraryHelpers.LoadLibrary();
|
var library = LibraryHelpers.LoadLibrary();
|
||||||
await Assert.That(library.StaticLibrary.Species.TryGet("bulbasaur", out var species)).IsTrue();
|
await Assert.That(library.StaticLibrary.Species.TryGet("bulbasaur", out var species)).IsTrue();
|
||||||
|
|
||||||
var pokemon = new PokemonImpl(library, species!, species!.GetDefaultForm(), new AbilityIndex()
|
var pokemon = new PokemonImpl(library, species!, species!.GetDefaultForm(), new AbilityIndex
|
||||||
{
|
{
|
||||||
Index = 0,
|
Index = 0,
|
||||||
IsHidden = false,
|
IsHidden = false,
|
||||||
|
@ -54,8 +54,8 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
|
|||||||
byte moveAccuracy)
|
byte moveAccuracy)
|
||||||
{
|
{
|
||||||
var accuracyModifier = 1.0f;
|
var accuracyModifier = 1.0f;
|
||||||
executingMove.RunScriptHook(
|
executingMove.RunScriptHook(x =>
|
||||||
x => x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier));
|
x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier));
|
||||||
var modifiedAccuracy = (int)(moveAccuracy * accuracyModifier);
|
var modifiedAccuracy = (int)(moveAccuracy * accuracyModifier);
|
||||||
// ReSharper disable once AccessToModifiedClosure
|
// ReSharper disable once AccessToModifiedClosure
|
||||||
executingMove.RunScriptHook(x => x.ChangeAccuracy(executingMove, target, hitIndex, ref modifiedAccuracy));
|
executingMove.RunScriptHook(x => x.ChangeAccuracy(executingMove, target, hitIndex, ref modifiedAccuracy));
|
||||||
|
@ -12,7 +12,7 @@ public class Gen7MiscLibrary : IMiscLibrary
|
|||||||
{
|
{
|
||||||
private readonly IMoveData _struggleData = new MoveDataImpl("struggle", new TypeIdentifier(0, "none"),
|
private readonly IMoveData _struggleData = new MoveDataImpl("struggle", new TypeIdentifier(0, "none"),
|
||||||
MoveCategory.Physical, 50, 255, 255, MoveTarget.Any, 0,
|
MoveCategory.Physical, 50, 255, 255, MoveTarget.Any, 0,
|
||||||
new SecondaryEffectImpl(-1, "struggle", new Dictionary<StringKey, object?>()), []);
|
new SecondaryEffectImpl(-1, "struggle", new Dictionary<StringKey, object?>()), ["not_sketchable"]);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ITurnChoice ReplacementChoice(IPokemon user, byte targetSide, byte targetPosition) =>
|
public ITurnChoice ReplacementChoice(IPokemon user, byte targetSide, byte targetPosition) =>
|
||||||
|
@ -4,12 +4,11 @@
|
|||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\PkmnLib.Dynamic\PkmnLib.Dynamic.csproj" />
|
<ProjectReference Include="..\..\PkmnLib.Dynamic\PkmnLib.Dynamic.csproj"/>
|
||||||
<ProjectReference Include="..\..\PkmnLib.Static\PkmnLib.Static.csproj" />
|
<ProjectReference Include="..\..\PkmnLib.Static\PkmnLib.Static.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.MoveVolatile;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.MoveVolatile, "round")]
|
||||||
|
public class RoundPowerBoost : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower) =>
|
||||||
|
basePower = basePower.MultiplyOrMax(2f);
|
||||||
|
}
|
@ -13,7 +13,7 @@ public abstract class BaseChargeMove<TVolatile> : Script where TVolatile : Requi
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
move.User.Volatile.Add(CreateVolatile(move.User));
|
move.User.Volatile.Add(CreateVolatile(move.User));
|
||||||
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("began_charging", new Dictionary<string, object>()
|
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("began_charging", new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "user", move.User },
|
{ "user", move.User },
|
||||||
}));
|
}));
|
||||||
|
@ -13,7 +13,7 @@ public class BeakBlast : Script
|
|||||||
if (battleData == null)
|
if (battleData == null)
|
||||||
return;
|
return;
|
||||||
choice.User.Volatile.Add(new BeakBlastEffect());
|
choice.User.Volatile.Add(new BeakBlastEffect());
|
||||||
battleData.Battle.EventHook.Invoke(new DialogEvent("beak_blast_charge", new Dictionary<string, object>()
|
battleData.Battle.EventHook.Invoke(new DialogEvent("beak_blast_charge", new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "user", choice.User },
|
{ "user", choice.User },
|
||||||
}));
|
}));
|
||||||
|
@ -13,7 +13,7 @@ public class Bounce : Script
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
move.User.Volatile.Add(new ChargeBounceEffect(move.User));
|
move.User.Volatile.Add(new ChargeBounceEffect(move.User));
|
||||||
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("bounce_charge", new Dictionary<string, object>()
|
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("bounce_charge", new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "user", move.User },
|
{ "user", move.User },
|
||||||
}));
|
}));
|
||||||
|
@ -3,5 +3,5 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|||||||
[Script(ScriptCategory.Move, "camouflage")]
|
[Script(ScriptCategory.Move, "camouflage")]
|
||||||
public class Camouflage : Script
|
public class Camouflage : Script
|
||||||
{
|
{
|
||||||
// FIXME: Implement this. How to get the terrain in a sane manner?
|
// FIXME: Implement this. How to get the terrain in a sane manner? See also SecretPower.cs
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
using PkmnLib.Static.Utils;
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
@ -6,16 +8,16 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|||||||
[Script(ScriptCategory.Move, "defog")]
|
[Script(ScriptCategory.Move, "defog")]
|
||||||
public class Defog : Script
|
public class Defog : Script
|
||||||
{
|
{
|
||||||
public static HashSet<StringKey> DefoggedEffects = new()
|
[PublicAPI] public static HashSet<StringKey> DefoggedEffects =
|
||||||
{
|
[
|
||||||
"mist",
|
ScriptUtils.ResolveName<MistEffect>(),
|
||||||
"light_screen",
|
ScriptUtils.ResolveName<LightScreenEffect>(),
|
||||||
"reflect",
|
ScriptUtils.ResolveName<ReflectEffect>(),
|
||||||
"safe_guard",
|
ScriptUtils.ResolveName<SafeguardEffect>(),
|
||||||
"spikes",
|
"spikes",
|
||||||
"toxic_spikes",
|
"toxic_spikes",
|
||||||
"stealth_rock",
|
"stealth_rock",
|
||||||
};
|
];
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
@ -13,7 +13,7 @@ public class Dig : Script
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
move.User.Volatile.Add(new DigEffect(move.User));
|
move.User.Volatile.Add(new DigEffect(move.User));
|
||||||
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dig_charge", new Dictionary<string, object>()
|
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dig_charge", new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "user", move.User },
|
{ "user", move.User },
|
||||||
}));
|
}));
|
||||||
|
@ -13,7 +13,7 @@ public class Dive : Script
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
move.User.Volatile.Add(new DigEffect(move.User));
|
move.User.Volatile.Add(new DigEffect(move.User));
|
||||||
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dive_charge", new Dictionary<string, object>()
|
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dive_charge", new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "user", move.User },
|
{ "user", move.User },
|
||||||
}));
|
}));
|
||||||
|
37
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/FlameWheel.cs
Normal file
37
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/FlameWheel.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "flame_wheel")]
|
||||||
|
public class FlameWheel : Script
|
||||||
|
{
|
||||||
|
private float _burnChance;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
|
||||||
|
{
|
||||||
|
if (parameters is null || !parameters.TryGetValue("burn_chance", out var burnChance) ||
|
||||||
|
burnChance is not float chance)
|
||||||
|
{
|
||||||
|
throw new Exception("Flame Wheel: Missing or invalid parameters.");
|
||||||
|
}
|
||||||
|
_burnChance = chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
if (move.User.HasStatus("frozen"))
|
||||||
|
{
|
||||||
|
move.User.ClearStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
var burnChance = _burnChance;
|
||||||
|
if (move.Battle.Random.EffectChance(_burnChance, move, target, hit))
|
||||||
|
{
|
||||||
|
target.SetStatus("burned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ public class Fly : Script
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
move.User.Volatile.Add(new ChargeFlyEffect(move.User));
|
move.User.Volatile.Add(new ChargeFlyEffect(move.User));
|
||||||
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("fly_charge", new Dictionary<string, object>()
|
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("fly_charge", new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "user", move.User },
|
{ "user", move.User },
|
||||||
}));
|
}));
|
||||||
|
@ -11,7 +11,7 @@ public class FocusPunch : Script
|
|||||||
{
|
{
|
||||||
choice.User.Volatile.Add(new FocusPunchEffect());
|
choice.User.Volatile.Add(new FocusPunchEffect());
|
||||||
choice.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_charge",
|
choice.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_charge",
|
||||||
new Dictionary<string, object>()
|
new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "pokemon", choice.User },
|
{ "pokemon", choice.User },
|
||||||
}));
|
}));
|
||||||
|
@ -15,7 +15,7 @@ public class LightScreen : Script
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var turns = 5;
|
var turns = 5;
|
||||||
var dict = new Dictionary<StringKey, object?>()
|
var dict = new Dictionary<StringKey, object?>
|
||||||
{
|
{
|
||||||
{ "duration", turns },
|
{ "duration", turns },
|
||||||
};
|
};
|
||||||
|
@ -32,7 +32,7 @@ public class Magnitude : Script
|
|||||||
// 5% chance for 10
|
// 5% chance for 10
|
||||||
_ => 10,
|
_ => 10,
|
||||||
};
|
};
|
||||||
battleData.Battle.EventHook.Invoke(new DialogEvent("magnitude", new Dictionary<string, object>()
|
battleData.Battle.EventHook.Invoke(new DialogEvent("magnitude", new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "magnitude", magnitude },
|
{ "magnitude", magnitude },
|
||||||
{ "user", move.User },
|
{ "user", move.User },
|
||||||
|
@ -9,6 +9,11 @@ public class MeanLook : Script
|
|||||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
{
|
{
|
||||||
var targetEffect = target.Volatile.Add(new MeanLookEffectTarget());
|
var targetEffect = target.Volatile.Add(new MeanLookEffectTarget());
|
||||||
|
if (targetEffect == null)
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
var userEffect = new MeanLookEffectUser(targetEffect);
|
var userEffect = new MeanLookEffectUser(targetEffect);
|
||||||
move.User.Volatile.Add(userEffect);
|
move.User.Volatile.Add(userEffect);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,12 @@ public class RagePowder : Script
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var effect = battleData.BattleSide.VolatileScripts.Add(new RagePowderEffect(move.User));
|
var effect = battleData.BattleSide.VolatileScripts.Add(new RagePowderEffect(move.User));
|
||||||
|
if (effect == null)
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
((RagePowderEffect)effect.Script!).User = move.User;
|
((RagePowderEffect)effect.Script!).User = move.User;
|
||||||
}
|
}
|
||||||
}
|
}
|
29
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Round.cs
Normal file
29
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Round.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.MoveVolatile;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "round")]
|
||||||
|
public class Round : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnAfterMove(IExecutingMove move)
|
||||||
|
{
|
||||||
|
var choiceQueue = move.Battle.ChoiceQueue;
|
||||||
|
if (choiceQueue is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var otherRoundMoves = choiceQueue.Where(x => x is IMoveChoice mc && mc.ChosenMove.MoveData.Name == "round")
|
||||||
|
.Cast<IMoveChoice>().ToList();
|
||||||
|
|
||||||
|
// We reverse the order here, as we're constantly pushing the choices to the front of the queue.
|
||||||
|
// By reversing the order, we ensure that the first choice is the one that is up next.
|
||||||
|
foreach (var otherRoundMove in otherRoundMoves.AsEnumerable().Reverse())
|
||||||
|
{
|
||||||
|
otherRoundMove.Volatile.Add(new RoundPowerBoost());
|
||||||
|
choiceQueue.MovePokemonChoiceNext(otherRoundMove.User);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Safeguard.cs
Normal file
11
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Safeguard.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "safeguard")]
|
||||||
|
public class Safeguard : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
target.BattleData?.BattleSide.VolatileScripts.Add(new Side.SafeguardEffect());
|
||||||
|
}
|
||||||
|
}
|
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SecretPower.cs
Normal file
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SecretPower.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "secret_power")]
|
||||||
|
public class SecretPower : Script
|
||||||
|
{
|
||||||
|
// FIXME: Implement this. How to get the terrain in a sane manner? See also Camouflage.cs
|
||||||
|
}
|
14
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SelfDestruct.cs
Normal file
14
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SelfDestruct.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "self_destruct")]
|
||||||
|
public class SelfDestruct : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnAfterMove(IExecutingMove move)
|
||||||
|
{
|
||||||
|
if (move.User.IsFainted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
move.User.Faint(DamageSource.Misc);
|
||||||
|
}
|
||||||
|
}
|
32
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShadowForce.cs
Normal file
32
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShadowForce.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "shadow_force")]
|
||||||
|
public class ShadowForce : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventMove(IExecutingMove move, ref bool prevent)
|
||||||
|
{
|
||||||
|
if (move.User.Volatile.Contains<ShadowForceCharge>())
|
||||||
|
return;
|
||||||
|
|
||||||
|
move.User.Volatile.Add(new ShadowForceCharge(move.User));
|
||||||
|
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("shadow_force_charge",
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "user", move.User },
|
||||||
|
}));
|
||||||
|
prevent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
if (move.User.Volatile.Contains<ShadowForceCharge>())
|
||||||
|
return;
|
||||||
|
|
||||||
|
move.User.Volatile.Add(new ShadowForceCharge(move.User));
|
||||||
|
}
|
||||||
|
}
|
19
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShellSmash.cs
Normal file
19
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShellSmash.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using PkmnLib.Static;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "shell_smash")]
|
||||||
|
public class ShellSmash : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
EventBatchId eventBatchId = new();
|
||||||
|
move.User.ChangeStatBoost(Statistic.Attack, 2, true, eventBatchId);
|
||||||
|
move.User.ChangeStatBoost(Statistic.SpecialAttack, 2, true, eventBatchId);
|
||||||
|
move.User.ChangeStatBoost(Statistic.Speed, 2, true, eventBatchId);
|
||||||
|
eventBatchId = new EventBatchId();
|
||||||
|
move.User.ChangeStatBoost(Statistic.Defense, -1, true, eventBatchId);
|
||||||
|
move.User.ChangeStatBoost(Statistic.SpecialDefense, -1, true, eventBatchId);
|
||||||
|
}
|
||||||
|
}
|
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShellTrap.cs
Normal file
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShellTrap.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "shell_trap")]
|
||||||
|
public class ShellTrap : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnBeforeMove(IExecutingMove move)
|
||||||
|
{
|
||||||
|
move.User.Volatile.Add(new ShellTrapHelper());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void FailMove(IExecutingMove move, ref bool fail)
|
||||||
|
{
|
||||||
|
var shellTrapHelper = move.User.Volatile.Get<ShellTrapHelper>();
|
||||||
|
if (shellTrapHelper is not { HasHit: true })
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShoreUp.cs
Normal file
19
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ShoreUp.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Weather;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "shore_up")]
|
||||||
|
public class ShoreUp : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var healMod = 0.5f;
|
||||||
|
if (move.Battle.WeatherName == ScriptUtils.ResolveName<Sandstorm>())
|
||||||
|
{
|
||||||
|
healMod = 2f / 3f;
|
||||||
|
}
|
||||||
|
var heal = (uint)(target.MaxHealth * healMod);
|
||||||
|
target.Heal(heal);
|
||||||
|
}
|
||||||
|
}
|
16
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SimpleBeam.cs
Normal file
16
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SimpleBeam.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "simple_beam")]
|
||||||
|
public class SimpleBeam : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
if (!move.Battle.Library.StaticLibrary.Abilities.TryGet("simple", out var simpleAbility))
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target.ChangeAbility(simpleAbility);
|
||||||
|
}
|
||||||
|
}
|
37
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Sketch.cs
Normal file
37
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Sketch.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "sketch")]
|
||||||
|
public class Sketch : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
// Defensive programming; If the move we're using is not the same as the one picked, something changed
|
||||||
|
// our move to sketch. This should never happen, as moves are not allowed to change to sketch, but in the
|
||||||
|
// case it does, we should fail the move.
|
||||||
|
if (move.ChosenMove.MoveData != move.UseMove)
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var moveSlot = move.User.Moves.IndexOf(move.ChosenMove);
|
||||||
|
if (moveSlot == -1)
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var choiceQueue = move.Battle.PreviousTurnChoices;
|
||||||
|
var lastMove = choiceQueue.SelectMany(x => x).OfType<IMoveChoice>().LastOrDefault(x => x.User == target);
|
||||||
|
if (lastMove == null || lastMove.ChosenMove.MoveData.HasFlag("not_sketchable"))
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
move.User.LearnMove(lastMove.ChosenMove.MoveData.Name, MoveLearnMethod.Sketch, (byte)moveSlot);
|
||||||
|
}
|
||||||
|
}
|
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SkillSwap.cs
Normal file
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/SkillSwap.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "skill_swap")]
|
||||||
|
public class SkillSwap : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var targetAbility = target.ActiveAbility;
|
||||||
|
var userAbility = move.User.ActiveAbility;
|
||||||
|
if (targetAbility == null || userAbility == null)
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (targetAbility.HasFlag("cant_be_changed") || userAbility.HasFlag("cant_be_changed"))
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
move.User.ChangeAbility(targetAbility);
|
||||||
|
target.ChangeAbility(userAbility);
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ public class FocusPunchEffect : Script
|
|||||||
{
|
{
|
||||||
WasHit = true;
|
WasHit = true;
|
||||||
target.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_lost_focus",
|
target.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_lost_focus",
|
||||||
new Dictionary<string, object>()
|
new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "pokemon", target },
|
{ "pokemon", target },
|
||||||
}));
|
}));
|
||||||
|
@ -33,7 +33,7 @@ public abstract class OutrageLikeEffect : Script
|
|||||||
if (_turns <= 0)
|
if (_turns <= 0)
|
||||||
{
|
{
|
||||||
RemoveSelf();
|
RemoveSelf();
|
||||||
_owner.Volatile.Add(new Confusion());
|
_owner.Volatile.Add(new Confusion(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ public class RequiresRechargeEffect : Script
|
|||||||
{
|
{
|
||||||
RemoveSelf();
|
RemoveSelf();
|
||||||
_owner.BattleData?.Battle.EventHook.Invoke(new DialogEvent("pokemon_must_recharge",
|
_owner.BattleData?.Battle.EventHook.Invoke(new DialogEvent("pokemon_must_recharge",
|
||||||
new Dictionary<string, object>()
|
new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "pokemon", _owner },
|
{ "pokemon", _owner },
|
||||||
}));
|
}));
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Pokemon, "shadow_force")]
|
||||||
|
public class ShadowForceCharge : Script
|
||||||
|
{
|
||||||
|
private readonly IPokemon _owner;
|
||||||
|
|
||||||
|
public ShadowForceCharge(IPokemon owner)
|
||||||
|
{
|
||||||
|
_owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ForceTurnSelection(byte sideIndex, byte position, ref ITurnChoice? choice)
|
||||||
|
{
|
||||||
|
var opposingSideIndex = (byte)(_owner.BattleData?.SideIndex == 0 ? 1 : 0);
|
||||||
|
choice = TurnChoiceHelper.CreateMoveChoice(_owner, "shadow_force", opposingSideIndex, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void BlockIncomingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
|
||||||
|
{
|
||||||
|
block = true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
using PkmnLib.Static.Moves;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Pokemon, "shell_trap")]
|
||||||
|
public class ShellTrapHelper : Script
|
||||||
|
{
|
||||||
|
public bool HasHit { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
if (move.UseMove.Category == MoveCategory.Physical)
|
||||||
|
HasHit = true;
|
||||||
|
}
|
||||||
|
}
|
20
Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/SafeguardEffect.cs
Normal file
20
Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/SafeguardEffect.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
public class SafeguardEffect : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventStatusChange(IPokemon pokemonImpl, StringKey status, ref bool preventStatus)
|
||||||
|
{
|
||||||
|
preventStatus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventVolatileAdd(Script script, ref bool preventVolatileAdd)
|
||||||
|
{
|
||||||
|
if (script.Category == ScriptCategory.Pokemon && script.Name == ScriptUtils.ResolveName<Confusion>())
|
||||||
|
preventVolatileAdd = true;
|
||||||
|
}
|
||||||
|
}
|
@ -32,8 +32,7 @@ public class Hail : Script, IWeatherScript
|
|||||||
if (pokemon.Types.Contains(iceType))
|
if (pokemon.Types.Contains(iceType))
|
||||||
continue;
|
continue;
|
||||||
var ignoresHail = false;
|
var ignoresHail = false;
|
||||||
pokemon.RunScriptHook(x => x.CustomTrigger(CustomTriggers.IgnoreHail,
|
pokemon.RunScriptHook(x => x.CustomTrigger(CustomTriggers.IgnoreHail, new Dictionary<StringKey, object?>
|
||||||
new Dictionary<StringKey, object?>()
|
|
||||||
{
|
{
|
||||||
{ "ignoresHail", ignoresHail },
|
{ "ignoresHail", ignoresHail },
|
||||||
}));
|
}));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user