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