Implements several more moves
This commit is contained in:
parent
549b92048a
commit
3a75493912
|
@ -252,12 +252,18 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
||||||
/// <param name="stat">The stat to be changed</param>
|
/// <param name="stat">The stat to be changed</param>
|
||||||
/// <param name="change">The amount to change the stat by</param>
|
/// <param name="change">The amount to change the stat by</param>
|
||||||
/// <param name="selfInflicted">Whether the change was self-inflicted. This can be relevant in scripts.</param>
|
/// <param name="selfInflicted">Whether the change was self-inflicted. This can be relevant in scripts.</param>
|
||||||
bool ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted);
|
/// <param name="batchId">The event batch ID this change is a part of. This is relevant for visual handling</param>
|
||||||
|
bool ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted, EventBatchId batchId = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Suppresses the ability of the Pokémon.
|
||||||
|
/// </summary>
|
||||||
|
public void SuppressAbility();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the currently active ability.
|
/// Returns the currently active ability.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IAbility ActiveAbility { get; }
|
IAbility? ActiveAbility { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the flat stats on the Pokemon. This should be called when for example the base
|
/// Calculates the flat stats on the Pokemon. This should be called when for example the base
|
||||||
|
@ -362,6 +368,11 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
||||||
/// the Pokémon already has it.
|
/// the Pokémon already has it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool AddType(TypeIdentifier type);
|
bool AddType(TypeIdentifier type);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replace the types of the Pokémon with the provided types.
|
||||||
|
/// </summary>
|
||||||
|
void SetTypes(IReadOnlyList<TypeIdentifier> types);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the data structure to a serializable format.
|
/// Converts the data structure to a serializable format.
|
||||||
|
@ -714,7 +725,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted)
|
public bool ChangeStatBoost(Statistic stat, sbyte change, bool selfInflicted, EventBatchId batchId = default)
|
||||||
{
|
{
|
||||||
var prevented = false;
|
var prevented = false;
|
||||||
this.RunScriptHook(script => script.PreventStatBoostChange(this, stat, change, selfInflicted, ref prevented));
|
this.RunScriptHook(script => script.PreventStatBoostChange(this, stat, change, selfInflicted, ref prevented));
|
||||||
|
@ -736,18 +747,34 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||||
if (BattleData != null)
|
if (BattleData != null)
|
||||||
{
|
{
|
||||||
var newBoost = StatBoost.GetStatistic(stat);
|
var newBoost = StatBoost.GetStatistic(stat);
|
||||||
BattleData.Battle.EventHook.Invoke(new StatBoostEvent(this, stat, oldBoost, newBoost));
|
BattleData.Battle.EventHook.Invoke(new StatBoostEvent(this, stat, oldBoost, newBoost)
|
||||||
|
{
|
||||||
|
BatchId = batchId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
RecalculateBoostedStats();
|
RecalculateBoostedStats();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the ability of the Pokémon is suppressed.
|
||||||
|
/// </summary>
|
||||||
|
public bool AbilitySuppressed { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void SuppressAbility()
|
||||||
|
{
|
||||||
|
OverrideAbility = null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IAbility ActiveAbility
|
public IAbility? ActiveAbility
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
if (AbilitySuppressed)
|
||||||
|
return null;
|
||||||
if (OverrideAbility != null)
|
if (OverrideAbility != null)
|
||||||
return OverrideAbility;
|
return OverrideAbility;
|
||||||
var ability = Form.GetAbility(AbilityIndex);
|
var ability = Form.GetAbility(AbilityIndex);
|
||||||
|
@ -1004,6 +1031,9 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||||
Volatile.Clear();
|
Volatile.Clear();
|
||||||
WeightInKg = Form.Weight;
|
WeightInKg = Form.Weight;
|
||||||
HeightInMeters = Form.Height;
|
HeightInMeters = Form.Height;
|
||||||
|
Types = Form.Types;
|
||||||
|
OverrideAbility = null;
|
||||||
|
AbilitySuppressed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1032,6 +1062,12 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void SetTypes(IReadOnlyList<TypeIdentifier> types)
|
||||||
|
{
|
||||||
|
_types = types.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SerializedPokemon Serialize() => new(this);
|
public SerializedPokemon Serialize() => new(this);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ public interface IReadOnlyTypeLibrary
|
||||||
/// This is equivalent to running get_single_effectiveness on each defending type, and multiplying the results with each other.
|
/// This is equivalent to running get_single_effectiveness on each defending type, and multiplying the results with each other.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
float GetEffectiveness(TypeIdentifier attacking, IReadOnlyList<TypeIdentifier> defending);
|
float GetEffectiveness(TypeIdentifier attacking, IReadOnlyList<TypeIdentifier> defending);
|
||||||
|
|
||||||
|
IEnumerable<(TypeIdentifier type, float effectiveness)> GetAllEffectivenessFromAttacking(TypeIdentifier attacking);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -70,6 +72,17 @@ public class TypeLibrary : IReadOnlyTypeLibrary
|
||||||
defending.Aggregate<TypeIdentifier, float>(1,
|
defending.Aggregate<TypeIdentifier, float>(1,
|
||||||
(current, type) => current * GetSingleEffectiveness(attacking, type));
|
(current, type) => current * GetSingleEffectiveness(attacking, type));
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IEnumerable<(TypeIdentifier, float)> GetAllEffectivenessFromAttacking(TypeIdentifier attacking)
|
||||||
|
{
|
||||||
|
if (attacking.Value < 1 || attacking.Value > _effectiveness.Count)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(attacking));
|
||||||
|
for (var i = 0; i < _effectiveness.Count; i++)
|
||||||
|
{
|
||||||
|
yield return (new TypeIdentifier((byte)(i + 1)), _effectiveness[attacking.Value - 1][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a new type in the library.
|
/// Registers a new type in the library.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -29,4 +29,16 @@ public enum Statistic : byte
|
||||||
/// Speed determines the order that a Pokémon can act in battle.
|
/// Speed determines the order that a Pokémon can act in battle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Speed,
|
Speed,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Evasion determines the likelihood that a Pokémon will dodge an attack.
|
||||||
|
/// This is not part of base stats, but is a temporary stat boost.
|
||||||
|
/// </summary>
|
||||||
|
Evasion,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Accuracy determines the likelihood that a Pokémon will hit an attack.
|
||||||
|
/// This is not part of base stats, but is a temporary stat boost.
|
||||||
|
/// </summary>
|
||||||
|
Accuracy,
|
||||||
}
|
}
|
|
@ -168,12 +168,24 @@ public record StatisticSet<T> : ImmutableStatisticSet<T>, IEnumerable<T>, IDeepC
|
||||||
Speed = Add(Speed, value);
|
Speed = Add(Speed, value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Invalid statistic.");
|
SetUnknownStat(stat, Add(GetUnknownStat(stat), value));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual T GetUnknownStat(Statistic stat)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Invalid statistic {stat}");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void SetUnknownStat(Statistic stat, T value)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Invalid statistic {stat}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decreases a statistic in the set by a value.
|
/// Decreases a statistic in the set by a value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -200,14 +212,15 @@ public record StatisticSet<T> : ImmutableStatisticSet<T>, IEnumerable<T>, IDeepC
|
||||||
Speed = Subtract(Speed, value);
|
Speed = Subtract(Speed, value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Invalid statistic.");
|
SetUnknownStat(stat, Subtract(GetUnknownStat(stat), value));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerator<T> GetEnumerator()
|
public virtual IEnumerator<T> GetEnumerator()
|
||||||
{
|
{
|
||||||
yield return Hp;
|
yield return Hp;
|
||||||
yield return Attack;
|
yield return Attack;
|
||||||
|
@ -332,6 +345,47 @@ public record StatBoostStatisticSet : ClampedStatisticSet<sbyte>
|
||||||
sbyte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
sbyte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override sbyte GetUnknownStat(Statistic stat)
|
||||||
|
{
|
||||||
|
return stat switch
|
||||||
|
{
|
||||||
|
Statistic.Evasion => Evasion,
|
||||||
|
Statistic.Accuracy => Accuracy,
|
||||||
|
_ => throw new ArgumentException($"Invalid statistic {stat}"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void SetUnknownStat(Statistic stat, sbyte value)
|
||||||
|
{
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case Statistic.Evasion:
|
||||||
|
Evasion = value;
|
||||||
|
break;
|
||||||
|
case Statistic.Accuracy:
|
||||||
|
Accuracy = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Invalid statistic {stat}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override IEnumerator<sbyte> GetEnumerator()
|
||||||
|
{
|
||||||
|
yield return Hp;
|
||||||
|
yield return Attack;
|
||||||
|
yield return Defense;
|
||||||
|
yield return SpecialAttack;
|
||||||
|
yield return SpecialDefense;
|
||||||
|
yield return Speed;
|
||||||
|
yield return Evasion;
|
||||||
|
yield return Accuracy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1424,7 +1424,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "calm_mind"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "camouflage",
|
"name": "camouflage",
|
||||||
|
@ -1437,7 +1440,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "camouflage"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "captivate",
|
"name": "captivate",
|
||||||
|
@ -1452,7 +1458,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "captivate"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "catastropika",
|
"name": "catastropika",
|
||||||
|
@ -1476,7 +1485,10 @@
|
||||||
"priority": 0,
|
"priority": 0,
|
||||||
"target": "Self",
|
"target": "Self",
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": []
|
"flags": [],
|
||||||
|
"effect": {
|
||||||
|
"name": "celebrate"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "charge",
|
"name": "charge",
|
||||||
|
@ -1489,7 +1501,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "charge"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "charge_beam",
|
"name": "charge_beam",
|
||||||
|
@ -1503,7 +1518,14 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_special_attack",
|
||||||
|
"chance": 70,
|
||||||
|
"parameters": {
|
||||||
|
"amount": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "charm",
|
"name": "charm",
|
||||||
|
@ -1518,7 +1540,13 @@
|
||||||
"protect",
|
"protect",
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_attack",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -2
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chatter",
|
"name": "chatter",
|
||||||
|
@ -1535,7 +1563,10 @@
|
||||||
"sound",
|
"sound",
|
||||||
"distance",
|
"distance",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "confuse"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chip_away",
|
"name": "chip_away",
|
||||||
|
@ -1550,7 +1581,10 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "chip_away"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "circle_throw",
|
"name": "circle_throw",
|
||||||
|
@ -1565,7 +1599,10 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "circle_throw"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "clamp",
|
"name": "clamp",
|
||||||
|
@ -1580,7 +1617,10 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "bind"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "clanging_scales",
|
"name": "clanging_scales",
|
||||||
|
@ -1596,7 +1636,13 @@
|
||||||
"mirror",
|
"mirror",
|
||||||
"sound",
|
"sound",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_defense",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "clear_smog",
|
"name": "clear_smog",
|
||||||
|
@ -1610,7 +1656,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "reset_target_stats"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "close_combat",
|
"name": "close_combat",
|
||||||
|
@ -1625,7 +1674,13 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_defense",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "coil",
|
"name": "coil",
|
||||||
|
@ -1638,7 +1693,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "coil"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "comet_punch",
|
"name": "comet_punch",
|
||||||
|
@ -1654,7 +1712,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"punch"
|
"punch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "2_5_hit_move"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "confide",
|
"name": "confide",
|
||||||
|
@ -1670,7 +1731,13 @@
|
||||||
"mirror",
|
"mirror",
|
||||||
"sound",
|
"sound",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_special_attack",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "confuse_ray",
|
"name": "confuse_ray",
|
||||||
|
@ -1685,7 +1752,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "confuse"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "confusion",
|
"name": "confusion",
|
||||||
|
@ -1699,7 +1769,11 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "confuse",
|
||||||
|
"chance": 10
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "constrict",
|
"name": "constrict",
|
||||||
|
@ -1714,7 +1788,14 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_speed",
|
||||||
|
"chance": 10,
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "continental_crush__physical",
|
"name": "continental_crush__physical",
|
||||||
|
@ -1749,7 +1830,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "conversion"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "conversion_2",
|
"name": "conversion_2",
|
||||||
|
@ -1762,7 +1846,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "conversion_2"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "copycat",
|
"name": "copycat",
|
||||||
|
@ -1773,7 +1860,10 @@
|
||||||
"priority": 0,
|
"priority": 0,
|
||||||
"target": "Self",
|
"target": "Self",
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": []
|
"flags": [],
|
||||||
|
"effect": {
|
||||||
|
"name": "copycat"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "core_enforcer",
|
"name": "core_enforcer",
|
||||||
|
@ -1787,7 +1877,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "core_enforcer"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "corkscrew_crash__physical",
|
"name": "corkscrew_crash__physical",
|
||||||
|
@ -1822,7 +1915,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "cosmic_power"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cotton_guard",
|
"name": "cotton_guard",
|
||||||
|
@ -1835,7 +1931,13 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_defense",
|
||||||
|
"parameters": {
|
||||||
|
"amount": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cotton_spore",
|
"name": "cotton_spore",
|
||||||
|
@ -1851,7 +1953,13 @@
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror",
|
"mirror",
|
||||||
"powder"
|
"powder"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_speed",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -2
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "counter",
|
"name": "counter",
|
||||||
|
|
|
@ -8,7 +8,8 @@ public class BulkUp : Script
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
{
|
{
|
||||||
move.User.ChangeStatBoost(Statistic.Attack, 1, true);
|
EventBatchId eventBatchId = new();
|
||||||
move.User.ChangeStatBoost(Statistic.Defense, 1, true);
|
move.User.ChangeStatBoost(Statistic.Attack, 1, true, eventBatchId);
|
||||||
|
move.User.ChangeStatBoost(Statistic.Defense, 1, true, eventBatchId);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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?
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.
|
||||||
|
}
|
|
@ -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?
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
continue;
|
||||||
if (pokemon.Types.Contains(iceType))
|
if (pokemon.Types.Contains(iceType))
|
||||||
continue;
|
continue;
|
||||||
if (_hailIgnoreAbilities.Contains(pokemon.ActiveAbility.Name))
|
if (pokemon.ActiveAbility != null && _hailIgnoreAbilities.Contains(pokemon.ActiveAbility.Name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var maxHealth = pokemon.BoostedStats.Hp;
|
var maxHealth = pokemon.BoostedStats.Hp;
|
||||||
|
|
Loading…
Reference in New Issue