Implements several more moves
This commit is contained in:
@@ -8,7 +8,8 @@ public class BulkUp : Script
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
move.User.ChangeStatBoost(Statistic.Attack, 1, true);
|
||||
move.User.ChangeStatBoost(Statistic.Defense, 1, true);
|
||||
EventBatchId eventBatchId = new();
|
||||
move.User.ChangeStatBoost(Statistic.Attack, 1, true, eventBatchId);
|
||||
move.User.ChangeStatBoost(Statistic.Defense, 1, true, eventBatchId);
|
||||
}
|
||||
}
|
||||
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CalmMind.cs
Normal file
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CalmMind.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Camouflage.cs
Normal file
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Camouflage.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
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?
|
||||
}
|
||||
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Captivate.cs
Normal file
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Captivate.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using PkmnLib.Static;
|
||||
using PkmnLib.Static.Species;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "captivate")]
|
||||
public class Captivate : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var user = move.User;
|
||||
if (target.Gender == Gender.Genderless || target.Gender == user.Gender)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
if (target.ActiveAbility?.Name == "oblivious")
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
target.ChangeStatBoost(Statistic.SpecialAttack, -2, false);
|
||||
}
|
||||
}
|
||||
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Celebrate.cs
Normal file
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Celebrate.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "celebrate")]
|
||||
public class Celebrate : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
|
||||
{
|
||||
// This move is mostly useless, and it's not worth the effort to implement it.
|
||||
// Prevent it from being selected.
|
||||
prevent = true;
|
||||
}
|
||||
}
|
||||
79
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ChangeUserStats.cs
Normal file
79
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ChangeUserStats.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PkmnLib.Static;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
public abstract class ChangeUserStats : Script
|
||||
{
|
||||
private readonly Statistic _stat;
|
||||
private sbyte _amount;
|
||||
|
||||
protected ChangeUserStats(Statistic stat)
|
||||
{
|
||||
_stat = stat;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(parameters));
|
||||
}
|
||||
|
||||
if (!parameters.TryGetValue("amount", out var amount) || amount == null)
|
||||
{
|
||||
throw new ArgumentException("Parameter 'amount' is required.");
|
||||
}
|
||||
|
||||
_amount = (sbyte)amount;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
move.User.ChangeStatBoost(_stat, _amount, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Script(ScriptCategory.Move, "change_user_attack")]
|
||||
public class ChangeUserAttack : ChangeUserStats
|
||||
{
|
||||
public ChangeUserAttack() : base(Statistic.Attack)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Script(ScriptCategory.Move, "change_user_defense")]
|
||||
public class ChangeUserDefense : ChangeUserStats
|
||||
{
|
||||
public ChangeUserDefense() : base(Statistic.Defense)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Script(ScriptCategory.Move, "change_user_special_attack")]
|
||||
public class ChangeUserSpecialAttack : ChangeUserStats
|
||||
{
|
||||
public ChangeUserSpecialAttack() : base(Statistic.SpecialAttack)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Script(ScriptCategory.Move, "change_user_special_defense")]
|
||||
public class ChangeUserSpecialDefense : ChangeUserStats
|
||||
{
|
||||
public ChangeUserSpecialDefense() : base(Statistic.SpecialDefense)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Script(ScriptCategory.Move, "change_user_speed")]
|
||||
public class ChangeUserSpeed : ChangeUserStats
|
||||
{
|
||||
public ChangeUserSpeed() : base(Statistic.Speed)
|
||||
{
|
||||
}
|
||||
}
|
||||
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Charge.cs
Normal file
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Charge.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "charge")]
|
||||
public class Charge : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
move.User.ChangeStatBoost(Statistic.SpecialDefense, 1, true);
|
||||
move.User.Volatile.Add(new ChargeEffect());
|
||||
}
|
||||
}
|
||||
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ChipAway.cs
Normal file
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/ChipAway.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "chip_away")]
|
||||
public class ChipAway : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void BypassDefensiveStatBoosts(IExecutingMove move, IPokemon target, byte hit, ref bool bypass)
|
||||
{
|
||||
bypass = true;
|
||||
}
|
||||
|
||||
// TODO: bypass evasion stat.
|
||||
}
|
||||
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CircleThrow.cs
Normal file
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CircleThrow.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "circle_throw")]
|
||||
public class CircleThrow : Script
|
||||
{
|
||||
// TODO: Implement this. How to handle forced switch?
|
||||
}
|
||||
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CloseCombat.cs
Normal file
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CloseCombat.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "close_combat")]
|
||||
public class CloseCombat : 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);
|
||||
}
|
||||
}
|
||||
16
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Coil.cs
Normal file
16
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Coil.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Confuse.cs
Normal file
13
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Confuse.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "confuse")]
|
||||
public class Confuse : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
target.Volatile.Add(new Confusion());
|
||||
}
|
||||
}
|
||||
20
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Conversion.cs
Normal file
20
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Conversion.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Linq;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "conversion")]
|
||||
public class Conversion : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var moveType = move.User.Moves.WhereNotNull().FirstOrDefault()?.MoveData.MoveType;
|
||||
if (moveType == null)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
move.User.SetTypes([moveType.Value]);
|
||||
}
|
||||
}
|
||||
57
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Conversion2.cs
Normal file
57
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Conversion2.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Linq;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "conversion_2")]
|
||||
public class Conversion2 : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var previousTurnChoices = target.BattleData?.Battle.PreviousTurnChoices;
|
||||
var nextExecutingChoice = target.BattleData?.Battle.ChoiceQueue?.Peek();
|
||||
var lastMoveByTarget = previousTurnChoices?
|
||||
// The previous turn choices include the choices of the current turn, so we need to have special handling for
|
||||
// the current turn
|
||||
.Select((x, index) =>
|
||||
{
|
||||
// All choices before the current turn are valid
|
||||
if (index < previousTurnChoices.Count - 1)
|
||||
return x;
|
||||
// If there is no next choice, we're at the end of the list, so we can just return the whole list
|
||||
if (nextExecutingChoice == null)
|
||||
return x;
|
||||
// Otherwise we determine where the next choice is and return everything before that
|
||||
var indexOfNext = x.IndexOf(nextExecutingChoice);
|
||||
if (indexOfNext == -1)
|
||||
return x;
|
||||
return x.Take(indexOfNext);
|
||||
})
|
||||
.SelectMany(x => x)
|
||||
// We only want the last move choice by the target
|
||||
.OfType<IMoveChoice>().FirstOrDefault(x => x.User == target);
|
||||
if (lastMoveByTarget == null)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
|
||||
var typeLibrary = move.User.BattleData!.Battle.Library.StaticLibrary.Types;
|
||||
// Get all types against which the last move would be not very effective
|
||||
var type = typeLibrary.GetAllEffectivenessFromAttacking(lastMoveByTarget.ChosenMove.MoveData.MoveType)
|
||||
.Where(x => x.effectiveness < 1)
|
||||
// Shuffle them randomly, but deterministically
|
||||
.OrderBy(_ => move.User.BattleData.Battle.Random.GetInt())
|
||||
.ThenBy(x => x.type.Value)
|
||||
// And grab the first one
|
||||
.Select(x => x.type)
|
||||
.FirstOrDefault();
|
||||
if (type == null)
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
move.User.SetTypes([type]);
|
||||
}
|
||||
}
|
||||
24
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Copycat.cs
Normal file
24
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Copycat.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Linq;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Utils;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "copycat")]
|
||||
public class Copycat : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeMove(IMoveChoice choice, ref StringKey moveName)
|
||||
{
|
||||
var lastMove = choice.User.BattleData?.Battle.PreviousTurnChoices
|
||||
.SelectMany(x => x)
|
||||
.OfType<IMoveChoice>()
|
||||
.LastOrDefault();
|
||||
if (lastMove == null || !lastMove.ChosenMove.MoveData.CanCopyMove())
|
||||
{
|
||||
choice.Fail();
|
||||
return;
|
||||
}
|
||||
moveName = lastMove.ChosenMove.MoveData.Name;
|
||||
}
|
||||
}
|
||||
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CoreEnforcer.cs
Normal file
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CoreEnforcer.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.Linq;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "core_enforcer")]
|
||||
public class CoreEnforcer : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var battleData = target.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
var turnChoices = battleData.Battle.PreviousTurnChoices.Last();
|
||||
var currentChoiceIndex = turnChoices.IndexOf(move.MoveChoice);
|
||||
if (currentChoiceIndex == -1 ||
|
||||
!turnChoices.Take(currentChoiceIndex).Any(choice => choice is IMoveChoice or IItemChoice))
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
target.SuppressAbility();
|
||||
}
|
||||
}
|
||||
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CosmicPower.cs
Normal file
15
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/CosmicPower.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "reset_target_stats")]
|
||||
public class ResetTargetStats : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId eventBatchId = new();
|
||||
foreach (Statistic stat in Enum.GetValues(typeof(Statistic)))
|
||||
{
|
||||
target.ChangeStatBoost(stat, (sbyte)-target.StatBoost.GetStatistic(stat), true, eventBatchId);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/ChargeEffect.cs
Normal file
30
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/ChargeEffect.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "charge_effect")]
|
||||
public class ChargeEffect : Script
|
||||
{
|
||||
private bool _turnOfUse = true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
|
||||
{
|
||||
var library = target.BattleData?.Battle.Library;
|
||||
if (library == null)
|
||||
return;
|
||||
if (!library.StaticLibrary.Types.TryGetTypeIdentifier("electric", out var electricType))
|
||||
return;
|
||||
if (move.UseMove.MoveType == electricType)
|
||||
modifier *= 2;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnEndTurn(IBattle battle)
|
||||
{
|
||||
if (_turnOfUse)
|
||||
{
|
||||
_turnOfUse = false;
|
||||
return;
|
||||
}
|
||||
RemoveSelf();
|
||||
}
|
||||
}
|
||||
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/Confusion.cs
Normal file
7
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/Confusion.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "confusion")]
|
||||
public class Confusion : Script
|
||||
{
|
||||
// TODO: Implement confusion
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class Hail : Script
|
||||
continue;
|
||||
if (pokemon.Types.Contains(iceType))
|
||||
continue;
|
||||
if (_hailIgnoreAbilities.Contains(pokemon.ActiveAbility.Name))
|
||||
if (pokemon.ActiveAbility != null && _hailIgnoreAbilities.Contains(pokemon.ActiveAbility.Name))
|
||||
continue;
|
||||
|
||||
var maxHealth = pokemon.BoostedStats.Hp;
|
||||
|
||||
Reference in New Issue
Block a user