More move scripts
This commit is contained in:
@@ -54,8 +54,8 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
|
||||
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);
|
||||
// ReSharper disable once AccessToModifiedClosure
|
||||
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"),
|
||||
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 />
|
||||
public ITurnChoice ReplacementChoice(IPokemon user, byte targetSide, byte targetPosition) =>
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>12</LangVersion>
|
||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\PkmnLib.Dynamic\PkmnLib.Dynamic.csproj" />
|
||||
<ProjectReference Include="..\..\PkmnLib.Static\PkmnLib.Static.csproj" />
|
||||
<ProjectReference Include="..\..\PkmnLib.Dynamic\PkmnLib.Dynamic.csproj"/>
|
||||
<ProjectReference Include="..\..\PkmnLib.Static\PkmnLib.Static.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</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;
|
||||
|
||||
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 },
|
||||
}));
|
||||
|
||||
@@ -13,7 +13,7 @@ public class BeakBlast : Script
|
||||
if (battleData == null)
|
||||
return;
|
||||
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 },
|
||||
}));
|
||||
|
||||
@@ -13,7 +13,7 @@ public class Bounce : Script
|
||||
return;
|
||||
|
||||
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 },
|
||||
}));
|
||||
|
||||
@@ -3,5 +3,5 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
[Script(ScriptCategory.Move, "camouflage")]
|
||||
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 JetBrains.Annotations;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
@@ -6,16 +8,16 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
[Script(ScriptCategory.Move, "defog")]
|
||||
public class Defog : Script
|
||||
{
|
||||
public static HashSet<StringKey> DefoggedEffects = new()
|
||||
{
|
||||
"mist",
|
||||
"light_screen",
|
||||
"reflect",
|
||||
"safe_guard",
|
||||
[PublicAPI] public static HashSet<StringKey> DefoggedEffects =
|
||||
[
|
||||
ScriptUtils.ResolveName<MistEffect>(),
|
||||
ScriptUtils.ResolveName<LightScreenEffect>(),
|
||||
ScriptUtils.ResolveName<ReflectEffect>(),
|
||||
ScriptUtils.ResolveName<SafeguardEffect>(),
|
||||
"spikes",
|
||||
"toxic_spikes",
|
||||
"stealth_rock",
|
||||
};
|
||||
];
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
|
||||
@@ -13,7 +13,7 @@ public class Dig : Script
|
||||
return;
|
||||
|
||||
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 },
|
||||
}));
|
||||
|
||||
@@ -13,7 +13,7 @@ public class Dive : Script
|
||||
return;
|
||||
|
||||
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 },
|
||||
}));
|
||||
|
||||
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;
|
||||
|
||||
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 },
|
||||
}));
|
||||
|
||||
@@ -11,7 +11,7 @@ public class FocusPunch : Script
|
||||
{
|
||||
choice.User.Volatile.Add(new FocusPunchEffect());
|
||||
choice.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_charge",
|
||||
new Dictionary<string, object>()
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "pokemon", choice.User },
|
||||
}));
|
||||
|
||||
@@ -15,7 +15,7 @@ public class LightScreen : Script
|
||||
return;
|
||||
|
||||
var turns = 5;
|
||||
var dict = new Dictionary<StringKey, object?>()
|
||||
var dict = new Dictionary<StringKey, object?>
|
||||
{
|
||||
{ "duration", turns },
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Magnitude : Script
|
||||
// 5% chance for 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 },
|
||||
{ "user", move.User },
|
||||
|
||||
@@ -9,6 +9,11 @@ public class MeanLook : Script
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var targetEffect = target.Volatile.Add(new MeanLookEffectTarget());
|
||||
if (targetEffect == null)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
var userEffect = new MeanLookEffectUser(targetEffect);
|
||||
move.User.Volatile.Add(userEffect);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,12 @@ public class RagePowder : Script
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
target.BattleData?.Battle.EventHook.Invoke(new DialogEvent("focus_punch_lost_focus",
|
||||
new Dictionary<string, object>()
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "pokemon", target },
|
||||
}));
|
||||
|
||||
@@ -33,7 +33,7 @@ public abstract class OutrageLikeEffect : Script
|
||||
if (_turns <= 0)
|
||||
{
|
||||
RemoveSelf();
|
||||
_owner.Volatile.Add(new Confusion());
|
||||
_owner.Volatile.Add(new Confusion(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public class RequiresRechargeEffect : Script
|
||||
{
|
||||
RemoveSelf();
|
||||
_owner.BattleData?.Battle.EventHook.Invoke(new DialogEvent("pokemon_must_recharge",
|
||||
new Dictionary<string, object>()
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "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,11 +32,10 @@ public class Hail : Script, IWeatherScript
|
||||
if (pokemon.Types.Contains(iceType))
|
||||
continue;
|
||||
var ignoresHail = false;
|
||||
pokemon.RunScriptHook(x => x.CustomTrigger(CustomTriggers.IgnoreHail,
|
||||
new Dictionary<StringKey, object?>()
|
||||
{
|
||||
{ "ignoresHail", ignoresHail },
|
||||
}));
|
||||
pokemon.RunScriptHook(x => x.CustomTrigger(CustomTriggers.IgnoreHail, new Dictionary<StringKey, object?>
|
||||
{
|
||||
{ "ignoresHail", ignoresHail },
|
||||
}));
|
||||
if (ignoresHail)
|
||||
continue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user