More moves implemented
This commit is contained in:
@@ -55,6 +55,10 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
|
||||
executingMove.RunScriptHook(x => x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier));
|
||||
var modifiedAccuracy = (int)(moveAccuracy * accuracyModifier);
|
||||
var targetEvasion = target.StatBoost.Evasion;
|
||||
var ignoreEvasion = false;
|
||||
executingMove.RunScriptHook(x => x.BypassEvasionStatBoosts(executingMove, target, hitIndex, ref ignoreEvasion));
|
||||
if (ignoreEvasion)
|
||||
targetEvasion = 0;
|
||||
var userAccuracy = executingMove.User.StatBoost.Accuracy;
|
||||
var difference = targetEvasion - userAccuracy;
|
||||
var statModifier = difference switch
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.MoveVolatile;
|
||||
|
||||
[Script(ScriptCategory.MoveVolatile, "electrify")]
|
||||
public class ElectrifyEffect : Script {
|
||||
/// <inheritdoc />
|
||||
public override void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier moveType)
|
||||
{
|
||||
var battleData = target.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
if (!battleData.Battle.Library.StaticLibrary.Types.TryGetTypeIdentifier("electric", out var electricType))
|
||||
return;
|
||||
moveType = electricType;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "bulk_up")]
|
||||
public class BulkUp : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId eventBatchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.Attack, 1, true, eventBatchId);
|
||||
move.User.ChangeStatBoost(Statistic.Defense, 1, true, eventBatchId);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "calm_mind")]
|
||||
public class CalmMind : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId eventBatchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.SpecialAttack, 1, true, eventBatchId);
|
||||
move.User.ChangeStatBoost(Statistic.SpecialDefense, 1, true, eventBatchId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PkmnLib.Static;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "change_multiple_user_stat_boosts")]
|
||||
public class ChangeMultipleUserStatBoosts : Script
|
||||
{
|
||||
private Dictionary<Statistic, sbyte> _statBoosts = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(parameters));
|
||||
}
|
||||
|
||||
foreach (var par in parameters)
|
||||
{
|
||||
if (!Enum.TryParse<Statistic>(par.Key, true, out var stat))
|
||||
continue;
|
||||
if (par.Value is sbyte value)
|
||||
{
|
||||
_statBoosts[stat] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId batchId = new();
|
||||
foreach (var stat in _statBoosts!)
|
||||
{
|
||||
move.User.ChangeStatBoost(stat.Key, stat.Value, true, batchId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,4 +76,20 @@ public class ChangeUserSpeed : ChangeUserStats
|
||||
public ChangeUserSpeed() : base(Statistic.Speed)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Script(ScriptCategory.Move, "change_user_accuracy")]
|
||||
public class ChangeUserAccuracy : ChangeUserStats
|
||||
{
|
||||
public ChangeUserAccuracy() : base(Statistic.Accuracy)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Script(ScriptCategory.Move, "change_user_evasion")]
|
||||
public class ChangeUserEvasion : ChangeUserStats
|
||||
{
|
||||
public ChangeUserEvasion() : base(Statistic.Evasion)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,10 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
public class ChipAway : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void BypassDefensiveStatBoosts(IExecutingMove move, IPokemon target, byte hit, ref bool bypass)
|
||||
{
|
||||
public override void BypassDefensiveStatBoosts(IExecutingMove move, IPokemon target, byte hit, ref bool bypass) =>
|
||||
bypass = true;
|
||||
}
|
||||
|
||||
// TODO: bypass evasion stat.
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void BypassEvasionStatBoosts(IExecutingMove move, IPokemon target, byte hitIndex, ref bool bypass)
|
||||
=> bypass = true;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "coil")]
|
||||
public class Coil : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId eventBatchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.Attack, 1, true, eventBatchId);
|
||||
move.User.ChangeStatBoost(Statistic.Defense, 1, true, eventBatchId);
|
||||
move.User.ChangeStatBoost(Statistic.Accuracy, 1, true, eventBatchId);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "cosmic_power")]
|
||||
public class CosmicPower : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId eventBatchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.Defense, 1, true, eventBatchId);
|
||||
move.User.ChangeStatBoost(Statistic.SpecialDefense, 1, true, eventBatchId);
|
||||
}
|
||||
}
|
||||
41
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Counter.cs
Normal file
41
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Counter.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "counter")]
|
||||
public class Counter : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnBeforeTurnStart(ITurnChoice choice)
|
||||
{
|
||||
choice.User.Volatile.Add(new CounterHelperEffect());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ChangeTargets(IMoveChoice moveChoice, ref IReadOnlyList<IPokemon?> targets)
|
||||
{
|
||||
var counterHelper = moveChoice.User.Volatile.Get<CounterHelperEffect>();
|
||||
var lastHitBy = counterHelper?.LastHitBy;
|
||||
if (lastHitBy == null)
|
||||
{
|
||||
moveChoice.Fail();
|
||||
return;
|
||||
}
|
||||
targets = [lastHitBy];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ChangeDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
|
||||
{
|
||||
var counterHelper = move.User.Volatile.Get<CounterHelperEffect>();
|
||||
if (counterHelper == null || counterHelper.LastHitBy == null || counterHelper.LastHitBy != target)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
var lastDamage = counterHelper.LastDamage;
|
||||
damage = lastDamage.MultiplyOrMax(2);
|
||||
}
|
||||
}
|
||||
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Covet.cs
Normal file
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Covet.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "covet")]
|
||||
public class Covet : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
if (target.HeldItem == null)
|
||||
return;
|
||||
if (move.User.HeldItem != null)
|
||||
return;
|
||||
_ = move.User.SetHeldItem(target.RemoveHeldItem());
|
||||
}
|
||||
}
|
||||
17
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CraftyShield.cs
Normal file
17
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CraftyShield.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "crafty_shield")]
|
||||
public class CraftyShield : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var battleData = move.User.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
var side = battleData.Battle.Sides[battleData.SideIndex];
|
||||
side.VolatileScripts.Add(new CraftyShieldEffect());
|
||||
}
|
||||
}
|
||||
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CrushGrip.cs
Normal file
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CrushGrip.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "crush_grip")]
|
||||
public class CrushGrip : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||
{
|
||||
basePower = Math.Max((byte)(120 * target.CurrentHealth / target.BoostedStats.Hp), (byte)1);
|
||||
}
|
||||
}
|
||||
34
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Curse.cs
Normal file
34
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Curse.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Linq;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "curse")]
|
||||
public class Curse : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var battleData = move.User.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
var typeLibrary = battleData.Battle.Library.StaticLibrary.Types;
|
||||
if (!typeLibrary.TryGetTypeIdentifier("ghost", out var ghostType))
|
||||
return;
|
||||
if (move.User.Types.Contains(ghostType))
|
||||
{
|
||||
move.User.Damage(move.User.CurrentHealth / 2, DamageSource.Misc);
|
||||
if (move.User.CurrentHealth == 0)
|
||||
return;
|
||||
target.Volatile.Add(new GhostCurseEffect(target));
|
||||
}
|
||||
else
|
||||
{
|
||||
EventBatchId batchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.Speed, -1, true, batchId);
|
||||
move.User.ChangeStatBoost(Statistic.Defense, 1, true, batchId);
|
||||
move.User.ChangeStatBoost(Statistic.Attack, 1, true, batchId);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DarkestLariat.cs
Normal file
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DarkestLariat.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "darkest_lariat")]
|
||||
public class DarkestLariat : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void BypassDefensiveStatBoosts(IExecutingMove move, IPokemon target, byte hit, ref bool bypass) =>
|
||||
bypass = true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void
|
||||
BypassEvasionStatBoosts(IExecutingMove move, IPokemon target, byte hitIndex, ref bool bypass) => bypass = true;
|
||||
}
|
||||
32
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Defog.cs
Normal file
32
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Defog.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
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",
|
||||
"spikes",
|
||||
"toxic_spikes",
|
||||
"stealth_rock",
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
if (target.BattleData == null)
|
||||
return;
|
||||
|
||||
var targetSide = target.BattleData.Battle.Sides[target.BattleData.SideIndex];
|
||||
foreach (var effect in DefoggedEffects)
|
||||
{
|
||||
targetSide.VolatileScripts.Remove(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DestinyBond.cs
Normal file
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DestinyBond.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "destiny_bond")]
|
||||
public class DestinyBond : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
move.User.Volatile.Add(new DestinyBondEffect());
|
||||
}
|
||||
}
|
||||
29
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Dig.cs
Normal file
29
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Dig.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "dig")]
|
||||
public class Dig : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void PreventMove(IExecutingMove move, ref bool prevent)
|
||||
{
|
||||
if (move.User.Volatile.Contains<DigEffect>())
|
||||
return;
|
||||
|
||||
move.User.Volatile.Add(new DigEffect(move.User));
|
||||
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dig_charge", new Dictionary<string, object>()
|
||||
{
|
||||
{ "user", move.User }
|
||||
}));
|
||||
prevent = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
move.User.Volatile.Remove(ScriptUtils.ResolveName<DigEffect>());
|
||||
}
|
||||
|
||||
}
|
||||
28
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Disable.cs
Normal file
28
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Disable.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Linq;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "disable")]
|
||||
public class Disable : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var battleData = move.User.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
var choiceQueue = battleData.Battle.PreviousTurnChoices;
|
||||
var lastMove = choiceQueue
|
||||
.SelectMany(x => x)
|
||||
.OfType<IMoveChoice>()
|
||||
.LastOrDefault(x => x.User == target);
|
||||
if (lastMove == null)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
var lastMoveName = lastMove.ChosenMove.MoveData.Name;
|
||||
target.Volatile.Add(new DisableEffect(lastMoveName));
|
||||
}
|
||||
}
|
||||
28
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Dive.cs
Normal file
28
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Dive.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "dive")]
|
||||
public class Dive : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void PreventMove(IExecutingMove move, ref bool prevent)
|
||||
{
|
||||
if (move.User.Volatile.Contains<DiveEffect>())
|
||||
return;
|
||||
|
||||
move.User.Volatile.Add(new DigEffect(move.User));
|
||||
move.User.BattleData?.Battle.EventHook.Invoke(new DialogEvent("dive_charge", new Dictionary<string, object>()
|
||||
{
|
||||
{ "user", move.User }
|
||||
}));
|
||||
prevent = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
move.User.Volatile.Remove(ScriptUtils.ResolveName<DiveEffect>());
|
||||
}
|
||||
}
|
||||
31
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DoomDesire.cs
Normal file
31
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DoomDesire.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Linq;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "doom_desire")]
|
||||
public class DoomDesire : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void BlockOutgoingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
|
||||
{
|
||||
var battleData = target.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
var side = battleData.Battle.Sides[battleData.SideIndex];
|
||||
var effect = side.VolatileScripts.Get<DoomDesireEffect>();
|
||||
if (effect != null && effect.HasTarget(battleData.Position))
|
||||
{
|
||||
executingMove.GetHitData(target, hitIndex).Fail();
|
||||
return;
|
||||
}
|
||||
|
||||
if (effect == null)
|
||||
{
|
||||
effect = new DoomDesireEffect(side);
|
||||
side.VolatileScripts.Add(effect);
|
||||
}
|
||||
effect.AddTarget(battleData.Position, executingMove.GetHitData(target, hitIndex).Damage);
|
||||
block = true;
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,14 @@ using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "close_combat")]
|
||||
public class CloseCombat : Script
|
||||
[Script(ScriptCategory.Move, "dragon_ascent")]
|
||||
public class DragonAscent : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId eventBatchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.Defense, -1, true, eventBatchId);
|
||||
move.User.ChangeStatBoost(Statistic.SpecialDefense, -1, true, eventBatchId);
|
||||
EventBatchId batchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.Defense, -1, true, batchId);
|
||||
move.User.ChangeStatBoost(Statistic.SpecialDefense, -1, true, batchId);
|
||||
}
|
||||
}
|
||||
11
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DragonRage.cs
Normal file
11
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DragonRage.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "dragon_rage")]
|
||||
public class DragonRage : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
|
||||
{
|
||||
damage = 40;
|
||||
}
|
||||
}
|
||||
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DreamEater.cs
Normal file
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/DreamEater.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "dream_eater")]
|
||||
public class DreamEater : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void BlockOutgoingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
|
||||
{
|
||||
if (!target.HasStatus("asleep"))
|
||||
block = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var user = move.User;
|
||||
var damage = move.GetHitData(target, hit).Damage;
|
||||
var healed = (uint)(damage * 0.5f);
|
||||
if (move.User.HasHeldItem("big_root"))
|
||||
healed = (uint)(healed * 1.3f);
|
||||
user.Heal(healed, false);
|
||||
}
|
||||
}
|
||||
31
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/EchoedVoice.cs
Normal file
31
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/EchoedVoice.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "echoed_voice")]
|
||||
public class EchoedVoice : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
|
||||
{
|
||||
var battleData = move.User.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
var side = battleData.Battle.Sides[battleData.SideIndex];
|
||||
var echoedVoiceData = side.VolatileScripts.Get<EchoedVoiceData>();
|
||||
if (echoedVoiceData == null)
|
||||
return;
|
||||
|
||||
modifier *= 2;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var battleData = move.User.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
var side = battleData.Battle.Sides[battleData.SideIndex];
|
||||
side.VolatileScripts.Add(new EchoedVoiceData());
|
||||
}
|
||||
}
|
||||
12
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ElectricTerrain.cs
Normal file
12
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ElectricTerrain.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "electric_terrain")]
|
||||
public class ElectricTerrain : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var battleData = move.User.BattleData;
|
||||
battleData?.Battle.SetTerrain(ScriptUtils.ResolveName<ElectricTerrain>());
|
||||
}
|
||||
}
|
||||
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Electrify.cs
Normal file
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Electrify.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.MoveVolatile;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "electrify")]
|
||||
public class Electrify : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var choiceQueue = target.BattleData?.Battle.ChoiceQueue;
|
||||
if (choiceQueue == null)
|
||||
return;
|
||||
|
||||
if (choiceQueue.Where(x => x is IMoveChoice moveChoice && moveChoice.User == target) is not IMoveChoice choice)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
|
||||
choice.Volatile.Add(new ElectrifyEffect());
|
||||
}
|
||||
}
|
||||
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ElectroBall.cs
Normal file
23
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ElectroBall.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "electro_ball")]
|
||||
public class ElectroBall : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||
{
|
||||
var user = move.User;
|
||||
var targetSpeed = target.BoostedStats.Speed;
|
||||
var userSpeed = user.BoostedStats.Speed;
|
||||
|
||||
var ratio = (float) userSpeed / targetSpeed;
|
||||
basePower = ratio switch
|
||||
{
|
||||
> 4 => 150,
|
||||
> 3 => 120,
|
||||
> 2 => 80,
|
||||
> 1 => 60,
|
||||
_ => 40
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,11 @@ using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
public abstract class ProtectionScript : Script
|
||||
[Script(ScriptCategory.Move, "protect")]
|
||||
public class ProtectionScript : Script
|
||||
{
|
||||
protected abstract ProtectionEffectScript GetEffectScript();
|
||||
|
||||
protected virtual ProtectionEffectScript GetEffectScript() => new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using PkmnLib.Static.Moves;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "counterhelper")]
|
||||
public class CounterHelperEffect : Script
|
||||
{
|
||||
public IPokemon? LastHitBy { get; private set; }
|
||||
public uint LastDamage { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
if (move.UseMove.Category == MoveCategory.Physical)
|
||||
{
|
||||
LastHitBy = move.User;
|
||||
LastDamage = move.GetHitData(target, hit).Damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "destiny_bond")]
|
||||
public class DestinyBondEffect : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnFaint(IPokemon pokemon, DamageSource source)
|
||||
{
|
||||
if (source == DamageSource.MoveDamage)
|
||||
{
|
||||
if (pokemon.BattleData?.Battle.ChoiceQueue?.LastRanChoice is not IMoveChoice lastChoice)
|
||||
return;
|
||||
lastChoice.User.Damage(lastChoice.User.BoostedStats.Hp * 10, DamageSource.Misc);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnBeforeMove(IExecutingMove move)
|
||||
{
|
||||
RemoveSelf();
|
||||
}
|
||||
}
|
||||
34
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/DigEffect.cs
Normal file
34
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/DigEffect.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "dig")]
|
||||
public class DigEffect : Script
|
||||
{
|
||||
private readonly IPokemon _owner;
|
||||
|
||||
public DigEffect(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, "dig", opposingSideIndex, position);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void BlockIncomingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
|
||||
{
|
||||
if (!executingMove.UseMove.HasFlag("hit_underground"))
|
||||
block = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ChangeIncomingDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
|
||||
{
|
||||
if (!move.UseMove.HasFlag("effective_against_underground"))
|
||||
damage *= 2;
|
||||
}
|
||||
}
|
||||
21
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/DisableEffect.cs
Normal file
21
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/DisableEffect.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "disable")]
|
||||
public class DisableEffect : Script
|
||||
{
|
||||
private readonly StringKey _move;
|
||||
|
||||
public DisableEffect(StringKey move)
|
||||
{
|
||||
_move = move;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
|
||||
{
|
||||
if (choice.ChosenMove.MoveData.Name == _move)
|
||||
prevent = true;
|
||||
}
|
||||
}
|
||||
34
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/DiveEffect.cs
Normal file
34
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/DiveEffect.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "dive")]
|
||||
public class DiveEffect : Script
|
||||
{
|
||||
private readonly IPokemon _owner;
|
||||
|
||||
public DiveEffect(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, "dive", opposingSideIndex, position);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void BlockIncomingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
|
||||
{
|
||||
if (!executingMove.UseMove.HasFlag("hit_underwater"))
|
||||
block = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ChangeIncomingDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
|
||||
{
|
||||
if (!move.UseMove.HasFlag("effective_against_underwater"))
|
||||
damage *= 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "ghostcurse")]
|
||||
public class GhostCurseEffect : Script
|
||||
{
|
||||
private IPokemon _pokemon;
|
||||
|
||||
public GhostCurseEffect(IPokemon pokemon)
|
||||
{
|
||||
_pokemon = pokemon;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnEndTurn(IBattle battle)
|
||||
{
|
||||
_pokemon.Damage(_pokemon.CurrentHealth / 4, DamageSource.Misc);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
public abstract class ProtectionEffectScript : Script
|
||||
public class ProtectionEffectScript : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void BlockIncomingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using PkmnLib.Static.Moves;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||
|
||||
[Script(ScriptCategory.Side, "crafty_shield")]
|
||||
public class CraftyShieldEffect : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void StopBeforeMove(IExecutingMove move, ref bool stop)
|
||||
{
|
||||
if (move.UseMove.Category == MoveCategory.Status)
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
63
Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/DoomDesireEffect.cs
Normal file
63
Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/DoomDesireEffect.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||
|
||||
[Script(ScriptCategory.Side, "doom_desire_effect")]
|
||||
public class DoomDesireEffect : Script
|
||||
{
|
||||
private class Target
|
||||
{
|
||||
public byte Position { get; }
|
||||
public uint Damage { get; }
|
||||
public int Turns { get; set; }
|
||||
|
||||
public Target(byte position, uint damage)
|
||||
{
|
||||
Position = position;
|
||||
Damage = damage;
|
||||
Turns = 3;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IBattleSide _side;
|
||||
private List<Target> _targets = new();
|
||||
|
||||
public DoomDesireEffect(IBattleSide side)
|
||||
{
|
||||
_side = side;
|
||||
}
|
||||
|
||||
public void AddTarget(byte position, uint damage)
|
||||
{
|
||||
_targets.Add(new Target(position, damage));
|
||||
}
|
||||
|
||||
public bool HasTarget(byte position)
|
||||
{
|
||||
return _targets.Exists(x => x.Position == position);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnEndTurn(IBattle battle)
|
||||
{
|
||||
var toRemove = new List<Target>();
|
||||
foreach (var v in _targets)
|
||||
{
|
||||
v.Turns--;
|
||||
if (v.Turns == 0)
|
||||
{
|
||||
var pokemon = _side.Pokemon[v.Position];
|
||||
pokemon?.Damage(v.Damage, DamageSource.Misc);
|
||||
toRemove.Add(v);
|
||||
}
|
||||
}
|
||||
foreach (var v in toRemove)
|
||||
{
|
||||
_targets.Remove(v);
|
||||
}
|
||||
if (_targets.Count == 0)
|
||||
{
|
||||
RemoveSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/EchoedVoiceData.cs
Normal file
14
Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/EchoedVoiceData.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||
|
||||
/// <summary>
|
||||
/// Just here to indicate that a Pokemon on this side has used Echoed Voice.
|
||||
/// </summary>
|
||||
[Script(ScriptCategory.Side, "echoed_voice_data")]
|
||||
public class EchoedVoiceData : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnEndTurn(IBattle battle)
|
||||
{
|
||||
RemoveSelf();
|
||||
}
|
||||
}
|
||||
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Status/Sleep.cs
Normal file
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Status/Sleep.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Status;
|
||||
|
||||
[Script(ScriptCategory.Status, "sleep")]
|
||||
public class Sleep : Script
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Terrain;
|
||||
|
||||
[Script(ScriptCategory.Terrain, "electric_terrain")]
|
||||
public class ElectricTerrain : Script
|
||||
{
|
||||
// TODO: Implement Electric Terrain
|
||||
}
|
||||
Reference in New Issue
Block a user