Implements a bunch more moves
This commit is contained in:
parent
8f262cb4a6
commit
77f1ab243b
|
@ -13,7 +13,7 @@ internal static class CommonDataLoaderHelper
|
||||||
if (effect == null)
|
if (effect == null)
|
||||||
return null;
|
return null;
|
||||||
var name = effect.Name;
|
var name = effect.Name;
|
||||||
var chance = effect.Chance;
|
var chance = effect.Chance ?? -1;
|
||||||
var parameters = effect.Parameters?.ToDictionary(x => (StringKey)x.Key, x => x.Value.ToParameter()) ??
|
var parameters = effect.Parameters?.ToDictionary(x => (StringKey)x.Key, x => x.Value.ToParameter()) ??
|
||||||
new Dictionary<StringKey, object?>();
|
new Dictionary<StringKey, object?>();
|
||||||
return new SecondaryEffectImpl(chance, name, parameters);
|
return new SecondaryEffectImpl(chance, name, parameters);
|
||||||
|
|
|
@ -29,6 +29,6 @@ public class SerializedMove
|
||||||
public class SerializedMoveEffect
|
public class SerializedMoveEffect
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = null!;
|
public string Name { get; set; } = null!;
|
||||||
public float Chance { get; set; }
|
public float? Chance { get; set; }
|
||||||
public Dictionary<string, JsonNode>? Parameters { get; set; } = null!;
|
public Dictionary<string, JsonNode>? Parameters { get; set; } = null!;
|
||||||
}
|
}
|
|
@ -255,7 +255,7 @@ public class BattleSideImpl : ScriptSource, IBattleSide
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Battle.EventHook.Invoke(new SwitchEvent(Index, position, pokemon));
|
Battle.EventHook.Invoke(new SwitchEvent(Index, position, pokemon));
|
||||||
pokemon.RunScriptHook(script => script.OnSwitchIn(pokemon));
|
pokemon.RunScriptHook(script => script.OnSwitchIn(pokemon, position));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -317,6 +317,11 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Damage(uint damage, DamageSource source, EventBatchId batchId = default);
|
void Damage(uint damage, DamageSource source, EventBatchId batchId = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forces the Pokémon to faint.
|
||||||
|
/// </summary>
|
||||||
|
void Faint(DamageSource source, EventBatchId batchId = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Heals the Pokemon by a specific amount. Unless allow_revive is set to true, this will not
|
/// Heals the Pokemon by a specific amount. Unless allow_revive is set to true, this will not
|
||||||
/// heal if the Pokemon has 0 health. If the amount healed is 0, this will return false.
|
/// heal if the Pokemon has 0 health. If the amount healed is 0, this will return false.
|
||||||
|
@ -967,6 +972,13 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Faint(DamageSource source, EventBatchId batchId = default)
|
||||||
|
{
|
||||||
|
CurrentHealth = 0;
|
||||||
|
OnFaint(source);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnFaint(DamageSource source)
|
private void OnFaint(DamageSource source)
|
||||||
{
|
{
|
||||||
// If the Pokémon is not in a battle, we don't need to do anything.
|
// If the Pokémon is not in a battle, we don't need to do anything.
|
||||||
|
@ -996,11 +1008,17 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||||
{
|
{
|
||||||
if (IsFainted && !allowRevive)
|
if (IsFainted && !allowRevive)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var maxAmount = BoostedStats.Hp - CurrentHealth;
|
var maxAmount = BoostedStats.Hp - CurrentHealth;
|
||||||
if (heal > maxAmount)
|
if (heal > maxAmount)
|
||||||
heal = maxAmount;
|
heal = maxAmount;
|
||||||
if (heal == 0)
|
if (heal == 0)
|
||||||
return false;
|
return false;
|
||||||
|
var prevented = false;
|
||||||
|
this.RunScriptHook(x => x.PreventHeal(this, heal, allowRevive, ref prevented));
|
||||||
|
if (prevented)
|
||||||
|
return false;
|
||||||
|
|
||||||
var newHealth = CurrentHealth + heal;
|
var newHealth = CurrentHealth + heal;
|
||||||
BattleData?.Battle.EventHook.Invoke(new HealEvent(this, CurrentHealth, newHealth));
|
BattleData?.Battle.EventHook.Invoke(new HealEvent(this, CurrentHealth, newHealth));
|
||||||
CurrentHealth = newHealth;
|
CurrentHealth = newHealth;
|
||||||
|
|
|
@ -477,7 +477,7 @@ public abstract class Script : IDeepCloneable
|
||||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon is switched into
|
/// This function is triggered on a Pokemon and its parents when the given Pokemon is switched into
|
||||||
/// the battlefield.
|
/// the battlefield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void OnSwitchIn(IPokemon pokemon)
|
public virtual void OnSwitchIn(IPokemon pokemon, byte position)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,4 +563,8 @@ public abstract class Script : IDeepCloneable
|
||||||
public virtual void ChangeWeatherDuration(StringKey weatherName, ref int duration)
|
public virtual void ChangeWeatherDuration(StringKey weatherName, ref int duration)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void PreventHeal(IPokemon pokemon, uint heal, bool allowRevive, ref bool prevented)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,11 @@ public interface IReadOnlyTypeLibrary
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool TryGetTypeIdentifier(StringKey key, out TypeIdentifier typeIdentifier);
|
bool TryGetTypeIdentifier(StringKey key, out TypeIdentifier typeIdentifier);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type identifier for a type with an index.
|
||||||
|
/// </summary>
|
||||||
|
bool TryGetTypeIdentifierFromIndex(byte index, [MaybeNullWhen(false)] out TypeIdentifier typeIdentifier);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the effectiveness for a single attacking type against a single defending type.
|
/// Gets the effectiveness for a single attacking type against a single defending type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -46,6 +51,18 @@ public class TypeLibrary : IReadOnlyTypeLibrary
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool TryGetTypeIdentifierFromIndex(byte index, out TypeIdentifier typeIdentifier)
|
||||||
|
{
|
||||||
|
if (index < 1 || index > _types.Count)
|
||||||
|
{
|
||||||
|
typeIdentifier = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
typeIdentifier = _types[index - 1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public float GetSingleEffectiveness(TypeIdentifier attacking, TypeIdentifier defending)
|
public float GetSingleEffectiveness(TypeIdentifier attacking, TypeIdentifier defending)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4788,7 +4788,13 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"punch"
|
"punch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_speed",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "happy_hour",
|
"name": "happy_hour",
|
||||||
|
@ -4800,6 +4806,7 @@
|
||||||
"target": "AllAlly",
|
"target": "AllAlly",
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": []
|
"flags": []
|
||||||
|
// TODO: Add effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "harden",
|
"name": "harden",
|
||||||
|
@ -4812,7 +4819,13 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_defense",
|
||||||
|
"parameters": {
|
||||||
|
"amount": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "haze",
|
"name": "haze",
|
||||||
|
@ -4825,7 +4838,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "reset_target_stats"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "head_charge",
|
"name": "head_charge",
|
||||||
|
@ -4840,7 +4856,13 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "recoil",
|
||||||
|
"parameters": {
|
||||||
|
"amount": 0.25
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "head_smash",
|
"name": "head_smash",
|
||||||
|
@ -4855,7 +4877,13 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "recoil",
|
||||||
|
"parameters": {
|
||||||
|
"amount": 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "headbutt",
|
"name": "headbutt",
|
||||||
|
@ -4870,7 +4898,11 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "flinch",
|
||||||
|
"chance": 30
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heal_bell",
|
"name": "heal_bell",
|
||||||
|
@ -4886,7 +4918,10 @@
|
||||||
"sound",
|
"sound",
|
||||||
"distance",
|
"distance",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "heal_bell"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heal_block",
|
"name": "heal_block",
|
||||||
|
@ -4902,7 +4937,10 @@
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror",
|
"mirror",
|
||||||
"limit_move_choice"
|
"limit_move_choice"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "heal_block"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heal_order",
|
"name": "heal_order",
|
||||||
|
@ -4916,7 +4954,13 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch",
|
"snatch",
|
||||||
"heal"
|
"heal"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "heal_percent",
|
||||||
|
"parameters": {
|
||||||
|
"healPercent": 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heal_pulse",
|
"name": "heal_pulse",
|
||||||
|
@ -4933,7 +4977,13 @@
|
||||||
"distance",
|
"distance",
|
||||||
"heal",
|
"heal",
|
||||||
"pulse"
|
"pulse"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "heal_percent",
|
||||||
|
"parameters": {
|
||||||
|
"healPercent": 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "healing_wish",
|
"name": "healing_wish",
|
||||||
|
@ -4947,7 +4997,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch",
|
"snatch",
|
||||||
"heal"
|
"heal"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "healing_wish"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heart_stamp",
|
"name": "heart_stamp",
|
||||||
|
@ -4962,7 +5015,11 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "flinch",
|
||||||
|
"chance": 30
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heart_swap",
|
"name": "heart_swap",
|
||||||
|
@ -4977,7 +5034,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "heart_swap"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heat_crash",
|
"name": "heat_crash",
|
||||||
|
@ -4993,7 +5053,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"nonskybattle"
|
"nonskybattle"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "heat_crash"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heat_wave",
|
"name": "heat_wave",
|
||||||
|
@ -5007,7 +5070,14 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"chance": 10,
|
||||||
|
"parameters": {
|
||||||
|
"status": "burned"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "heavy_slam",
|
"name": "heavy_slam",
|
||||||
|
@ -5023,7 +5093,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"nonskybattle"
|
"nonskybattle"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "heat_crash"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "helping_hand",
|
"name": "helping_hand",
|
||||||
|
@ -5036,7 +5109,10 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "helping_hand"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hex",
|
"name": "hex",
|
||||||
|
@ -5050,7 +5126,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "hex"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hidden_power",
|
"name": "hidden_power",
|
||||||
|
@ -5064,7 +5143,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "hidden_power"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "high_horsepower",
|
"name": "high_horsepower",
|
||||||
|
@ -5080,6 +5162,7 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "high_jump_kick",
|
"name": "high_jump_kick",
|
||||||
|
@ -5095,7 +5178,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"gravity"
|
"gravity"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "high_jump_kick"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hold_back",
|
"name": "hold_back",
|
||||||
|
@ -5110,7 +5196,10 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "false_swipe"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hold_hands",
|
"name": "hold_hands",
|
||||||
|
@ -5124,6 +5213,7 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
]
|
||||||
|
// Does nothing
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hone_claws",
|
"name": "hone_claws",
|
||||||
|
@ -5136,7 +5226,14 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_multiple_user_stat_boosts",
|
||||||
|
"parameters": {
|
||||||
|
"attack": 1,
|
||||||
|
"accuracy": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "horn_attack",
|
"name": "horn_attack",
|
||||||
|
@ -5152,6 +5249,7 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "horn_drill",
|
"name": "horn_drill",
|
||||||
|
@ -5166,7 +5264,10 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "one_hit_ko"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "horn_leech",
|
"name": "horn_leech",
|
||||||
|
@ -5182,7 +5283,13 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"heal"
|
"heal"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "drain",
|
||||||
|
"parameters": {
|
||||||
|
"drain_modifier": 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "howl",
|
"name": "howl",
|
||||||
|
@ -5195,7 +5302,13 @@
|
||||||
"category": "status",
|
"category": "status",
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch"
|
"snatch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_user_attack",
|
||||||
|
"parameters": {
|
||||||
|
"amount": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hurricane",
|
"name": "hurricane",
|
||||||
|
@ -5210,7 +5323,11 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"distance"
|
"distance"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "confuse",
|
||||||
|
"chance": 30
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hydro_cannon",
|
"name": "hydro_cannon",
|
||||||
|
@ -5225,7 +5342,10 @@
|
||||||
"recharge",
|
"recharge",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "requires_recharge"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hydro_pump",
|
"name": "hydro_pump",
|
||||||
|
@ -5240,6 +5360,7 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hydro_vortex__physical",
|
"name": "hydro_vortex__physical",
|
||||||
|
@ -5276,7 +5397,10 @@
|
||||||
"recharge",
|
"recharge",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "requires_recharge"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hyper_fang",
|
"name": "hyper_fang",
|
||||||
|
@ -5291,7 +5415,11 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "flinch",
|
||||||
|
"chance": 10
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hyper_voice",
|
"name": "hyper_voice",
|
||||||
|
@ -5308,6 +5436,7 @@
|
||||||
"sound",
|
"sound",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hyperspace_fury",
|
"name": "hyperspace_fury",
|
||||||
|
@ -5320,8 +5449,12 @@
|
||||||
"category": "physical",
|
"category": "physical",
|
||||||
"flags": [
|
"flags": [
|
||||||
"mirror",
|
"mirror",
|
||||||
"ignore-substitute"
|
"ignore-substitute",
|
||||||
]
|
"protect"
|
||||||
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "hyperspace_fury"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hyperspace_hole",
|
"name": "hyperspace_hole",
|
||||||
|
@ -5334,8 +5467,12 @@
|
||||||
"category": "special",
|
"category": "special",
|
||||||
"flags": [
|
"flags": [
|
||||||
"mirror",
|
"mirror",
|
||||||
"ignore-substitute"
|
"ignore-substitute",
|
||||||
]
|
"protect"
|
||||||
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "hyperspace_fury"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hypnosis",
|
"name": "hypnosis",
|
||||||
|
@ -5350,7 +5487,13 @@
|
||||||
"protect",
|
"protect",
|
||||||
"reflectable",
|
"reflectable",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"parameters": {
|
||||||
|
"status": "sleep"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ice_ball",
|
"name": "ice_ball",
|
||||||
|
@ -5366,7 +5509,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"ballistics"
|
"ballistics"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "ice_ball"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ice_beam",
|
"name": "ice_beam",
|
||||||
|
@ -5380,7 +5526,14 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"chance": 10,
|
||||||
|
"parameters": {
|
||||||
|
"status": "frozen"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ice_burn",
|
"name": "ice_burn",
|
||||||
|
@ -5395,7 +5548,10 @@
|
||||||
"charge",
|
"charge",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "ice_burn"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ice_fang",
|
"name": "ice_fang",
|
||||||
|
@ -5411,7 +5567,10 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"bite"
|
"bite"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "ice_fang"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ice_hammer",
|
"name": "ice_hammer",
|
||||||
|
@ -5427,7 +5586,13 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"punch"
|
"punch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_speed",
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ice_punch",
|
"name": "ice_punch",
|
||||||
|
@ -5443,7 +5608,14 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror",
|
"mirror",
|
||||||
"punch"
|
"punch"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"chance": 10,
|
||||||
|
"parameters": {
|
||||||
|
"status": "frozen"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ice_shard",
|
"name": "ice_shard",
|
||||||
|
@ -5458,6 +5630,7 @@
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
]
|
||||||
|
// No secondary effect
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "icicle_crash",
|
"name": "icicle_crash",
|
||||||
|
@ -5471,7 +5644,11 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "flinch",
|
||||||
|
"chance": 30
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "icicle_spear",
|
"name": "icicle_spear",
|
||||||
|
@ -5485,7 +5662,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "2_5_hit_move"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "icy_wind",
|
"name": "icy_wind",
|
||||||
|
@ -5499,7 +5679,14 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "change_target_speed",
|
||||||
|
"chance": 100,
|
||||||
|
"parameters": {
|
||||||
|
"amount": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "imprison",
|
"name": "imprison",
|
||||||
|
@ -5513,7 +5700,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"snatch",
|
"snatch",
|
||||||
"ignore-substitute"
|
"ignore-substitute"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "imprison"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "incinerate",
|
"name": "incinerate",
|
||||||
|
@ -5527,7 +5717,10 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "incinerate"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "inferno",
|
"name": "inferno",
|
||||||
|
@ -5541,7 +5734,14 @@
|
||||||
"flags": [
|
"flags": [
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "set_status",
|
||||||
|
"chance": 100,
|
||||||
|
"parameters": {
|
||||||
|
"status": "burned"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "inferno_overdrive__physical",
|
"name": "inferno_overdrive__physical",
|
||||||
|
@ -5578,7 +5778,10 @@
|
||||||
"contact",
|
"contact",
|
||||||
"protect",
|
"protect",
|
||||||
"mirror"
|
"mirror"
|
||||||
]
|
],
|
||||||
|
"effect": {
|
||||||
|
"name": "infestation"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ingrain",
|
"name": "ingrain",
|
||||||
|
|
|
@ -10,14 +10,15 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70"/>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
||||||
<PackageReference Include="TUnit" Version="0.5.18" />
|
<PackageReference Include="TUnit" Version="0.5.18"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\PkmnLib.Dynamic\PkmnLib.Dynamic.csproj" />
|
<ProjectReference Include="..\..\PkmnLib.Dataloader\PkmnLib.Dataloader.csproj"/>
|
||||||
<ProjectReference Include="..\PkmnLib.Plugin.Gen7\PkmnLib.Plugin.Gen7.csproj" />
|
<ProjectReference Include="..\..\PkmnLib.Dynamic\PkmnLib.Dynamic.csproj"/>
|
||||||
|
<ProjectReference Include="..\PkmnLib.Plugin.Gen7\PkmnLib.Plugin.Gen7.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
using PkmnLib.Dynamic.Libraries;
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
using PkmnLib.Static;
|
||||||
|
using PkmnLib.Static.Libraries;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
||||||
|
|
||||||
|
public class HiddenPowerTests
|
||||||
|
{
|
||||||
|
public record TestCaseData(IndividualValueStatisticSet Ivs, StringKey ExpectedType, byte ExpectedPower)
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString() =>
|
||||||
|
$"Hidden Power type is {ExpectedType}, base power is {ExpectedPower} " +
|
||||||
|
$"with IVs: HP {Ivs.Hp}, Atk {Ivs.Attack}, Def {Ivs.Defense}, SpA {Ivs.SpecialAttack}, SpD {Ivs.SpecialDefense}, Spe {Ivs.Speed}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Func<TestCaseData>> HiddenPowerTestData()
|
||||||
|
{
|
||||||
|
yield return () => new TestCaseData(new IndividualValueStatisticSet(31, 31, 31, 31, 31, 31), "dark", 70);
|
||||||
|
yield return () => new TestCaseData(new IndividualValueStatisticSet(25, 2, 12, 5, 8, 17), "bug", 31);
|
||||||
|
yield return () => new TestCaseData(new IndividualValueStatisticSet(29, 19, 18, 22, 15, 28), "fire", 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test, MethodDataSource(nameof(HiddenPowerTestData))]
|
||||||
|
public async Task HiddenPower_ChangesType(TestCaseData test)
|
||||||
|
{
|
||||||
|
var typeLibrary = new TypeLibrary();
|
||||||
|
typeLibrary.RegisterType("normal");
|
||||||
|
typeLibrary.RegisterType("fighting");
|
||||||
|
typeLibrary.RegisterType("flying");
|
||||||
|
typeLibrary.RegisterType("poison");
|
||||||
|
typeLibrary.RegisterType("ground");
|
||||||
|
typeLibrary.RegisterType("rock");
|
||||||
|
typeLibrary.RegisterType("bug");
|
||||||
|
typeLibrary.RegisterType("ghost");
|
||||||
|
typeLibrary.RegisterType("steel");
|
||||||
|
typeLibrary.RegisterType("fire");
|
||||||
|
typeLibrary.RegisterType("water");
|
||||||
|
typeLibrary.RegisterType("grass");
|
||||||
|
typeLibrary.RegisterType("electric");
|
||||||
|
typeLibrary.RegisterType("psychic");
|
||||||
|
typeLibrary.RegisterType("ice");
|
||||||
|
typeLibrary.RegisterType("dragon");
|
||||||
|
typeLibrary.RegisterType("dark");
|
||||||
|
typeLibrary.RegisterType("fairy");
|
||||||
|
|
||||||
|
var executingMove = new Mock<IExecutingMove>(MockBehavior.Strict);
|
||||||
|
var user = new Mock<IPokemon>(MockBehavior.Strict);
|
||||||
|
var target = new Mock<IPokemon>(MockBehavior.Strict);
|
||||||
|
var dynamicLibrary = new Mock<IDynamicLibrary>(MockBehavior.Strict);
|
||||||
|
var staticLibrary = new Mock<IStaticLibrary>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
executingMove.SetupGet(x => x.User).Returns(user.Object);
|
||||||
|
user.SetupGet(x => x.IndividualValues).Returns(test.Ivs);
|
||||||
|
user.SetupGet(x => x.Library).Returns(dynamicLibrary.Object);
|
||||||
|
staticLibrary.Setup(x => x.Types).Returns(typeLibrary);
|
||||||
|
dynamicLibrary.Setup(x => x.StaticLibrary).Returns(staticLibrary.Object);
|
||||||
|
|
||||||
|
var moveType = new TypeIdentifier(1, "normal");
|
||||||
|
|
||||||
|
var hiddenPower = new HiddenPower();
|
||||||
|
hiddenPower.ChangeMoveType(executingMove.Object, target.Object, 0, ref moveType);
|
||||||
|
|
||||||
|
await Assert.That(moveType.Name).IsEqualTo(test.ExpectedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test, MethodDataSource(nameof(HiddenPowerTestData))]
|
||||||
|
public async Task HiddenPower_ChangesBasePower(TestCaseData test)
|
||||||
|
{
|
||||||
|
var executingMove = new Mock<IExecutingMove>(MockBehavior.Strict);
|
||||||
|
var user = new Mock<IPokemon>(MockBehavior.Strict);
|
||||||
|
var target = new Mock<IPokemon>(MockBehavior.Strict);
|
||||||
|
var dynamicLibrary = new Mock<IDynamicLibrary>(MockBehavior.Strict);
|
||||||
|
var staticLibrary = new Mock<IStaticLibrary>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
executingMove.SetupGet(x => x.User).Returns(user.Object);
|
||||||
|
user.SetupGet(x => x.IndividualValues).Returns(test.Ivs);
|
||||||
|
user.SetupGet(x => x.Library).Returns(dynamicLibrary.Object);
|
||||||
|
dynamicLibrary.Setup(x => x.StaticLibrary).Returns(staticLibrary.Object);
|
||||||
|
|
||||||
|
var hiddenPower = new HiddenPower();
|
||||||
|
byte power = 0;
|
||||||
|
hiddenPower.ChangeBasePower(executingMove.Object, target.Object, 0, ref power);
|
||||||
|
|
||||||
|
await Assert.That(power).IsEqualTo(test.ExpectedPower);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
|
using System;
|
||||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
@ -12,7 +14,8 @@ public class FuryCutter : Script
|
||||||
if (userEffect == null)
|
if (userEffect == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
userEffect.TurnCount++;
|
if (userEffect.TurnCount < 5)
|
||||||
basePower = (byte)(basePower * (userEffect.TurnCount + 1));
|
userEffect.TurnCount++;
|
||||||
|
basePower = basePower.MultiplyOrMax((byte)Math.Pow(2, userEffect.TurnCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System.Linq;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "heal_bell")]
|
||||||
|
public class HealBell : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var party = move.User.BattleData?.Battle.Parties.FirstOrDefault(p => p.Party.Contains(target));
|
||||||
|
if (party == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var pokemon in party.Party.WhereNotNull())
|
||||||
|
{
|
||||||
|
pokemon.ClearStatus();
|
||||||
|
var confusion = ScriptUtils.ResolveName<Confusion>();
|
||||||
|
if (pokemon.Volatile.Contains(confusion))
|
||||||
|
pokemon.Volatile.Remove(confusion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "heal_block")]
|
||||||
|
public class HealBlock : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
target.Volatile.Add(new HealBlockEffect());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "heal_percent")]
|
||||||
|
public class HealPercent : Script
|
||||||
|
{
|
||||||
|
private float _healPercent = 0.5f;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
|
||||||
|
{
|
||||||
|
if (parameters?.TryGetValue("healPercent", out var variable) == true && variable is float healPercent)
|
||||||
|
{
|
||||||
|
_healPercent = healPercent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
target.Heal((uint)(move.User.BoostedStats.Hp * _healPercent));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "healing_wish")]
|
||||||
|
public class HealingWish : 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 HealingWishEffect(battleData.Position));
|
||||||
|
|
||||||
|
move.User.Faint(DamageSource.Misc);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using PkmnLib.Static;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "heart_swap")]
|
||||||
|
public class HeartSwap : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
EventBatchId eventBatchId = new();
|
||||||
|
var userStats = move.User.StatBoost;
|
||||||
|
var targetStats = target.StatBoost;
|
||||||
|
|
||||||
|
foreach (Statistic stat in Enum.GetValues(typeof(Statistic)))
|
||||||
|
{
|
||||||
|
var userStat = userStats.GetStatistic(stat);
|
||||||
|
var targetStat = targetStats.GetStatistic(stat);
|
||||||
|
if (userStat == targetStat)
|
||||||
|
continue;
|
||||||
|
move.User.ChangeStatBoost(stat, (sbyte)(userStat - targetStat), true, eventBatchId);
|
||||||
|
target.ChangeStatBoost(stat, (sbyte)(targetStat - userStat), false, eventBatchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "heat_crash")]
|
||||||
|
public class HeatCrash : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||||
|
{
|
||||||
|
var weightMultiplier = move.User.WeightInKg / target.WeightInKg;
|
||||||
|
basePower = weightMultiplier switch
|
||||||
|
{
|
||||||
|
> 5 => 120,
|
||||||
|
> 4 => 100,
|
||||||
|
> 3 => 80,
|
||||||
|
> 2 => 60,
|
||||||
|
_ => 40,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "helping_hand")]
|
||||||
|
public class HelpingHand : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit) =>
|
||||||
|
target.Volatile.Add(new HelpingHandEffect());
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "hex")]
|
||||||
|
public class Hex : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||||
|
{
|
||||||
|
if (!target.StatusScript.IsEmpty)
|
||||||
|
{
|
||||||
|
basePower = basePower.MultiplyOrMax(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using PkmnLib.Static;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "hidden_power")]
|
||||||
|
public class HiddenPower : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier moveType)
|
||||||
|
{
|
||||||
|
var ivs = move.User.IndividualValues;
|
||||||
|
|
||||||
|
var type = GetHiddenPowerValue(ivs, 0x00000001) * 15 / 63;
|
||||||
|
|
||||||
|
move.User.Library.StaticLibrary.Types.TryGetTypeIdentifierFromIndex((byte)(type + 2), out moveType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||||
|
{
|
||||||
|
var ivs = move.User.IndividualValues;
|
||||||
|
|
||||||
|
var power = GetHiddenPowerValue(ivs, 0x00000002) * 40 / 63 + 30;
|
||||||
|
// cast to byte with overflow check
|
||||||
|
basePower = (byte)Math.Min(power, byte.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method to calculate the hidden power value from the IVs.
|
||||||
|
/// This is used to determine the type and power of the move.
|
||||||
|
/// </summary>
|
||||||
|
private static int GetHiddenPowerValue(IndividualValueStatisticSet ivs, int significance) =>
|
||||||
|
((ivs.Hp & significance) >> (significance - 1)) + (((ivs.Attack & significance) >> (significance - 1)) << 1) +
|
||||||
|
(((ivs.Defense & significance) >> (significance - 1)) << 2) +
|
||||||
|
(((ivs.Speed & significance) >> (significance - 1)) << 3) +
|
||||||
|
(((ivs.SpecialAttack & significance) >> (significance - 1)) << 4) +
|
||||||
|
(((ivs.SpecialDefense & significance) >> (significance - 1)) << 5);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "high_jump_kick")]
|
||||||
|
public class HighJumpKick : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnMoveMiss(IExecutingMove move, IPokemon target)
|
||||||
|
{
|
||||||
|
var damage = move.GetHitData(target, 0).Damage;
|
||||||
|
var recoil = damage / 2;
|
||||||
|
// This recoil damage will not exceed half the user's max HP
|
||||||
|
var maxHp = move.User.BoostedStats.Hp;
|
||||||
|
recoil = Math.Min(recoil, maxHp / 2);
|
||||||
|
move.User.Damage(recoil, DamageSource.Misc);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System.Linq;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "hyperspace_fury")]
|
||||||
|
public class HyperspaceFury : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var protectionScripts = target.Volatile.Select(x => x.Script).OfType<ProtectionEffectScript>();
|
||||||
|
foreach (var protectionScript in protectionScripts.ToList())
|
||||||
|
{
|
||||||
|
target.Volatile.Remove(protectionScript.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "ice_ball")]
|
||||||
|
public class IceBall : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||||
|
{
|
||||||
|
var userEffect = move.User.Volatile.Get<IceBallEffect>();
|
||||||
|
if (userEffect == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
basePower = basePower.MultiplyOrMax((byte)Math.Pow(2, userEffect.TurnCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var userEffect = move.User.Volatile.Get<IceBallEffect>();
|
||||||
|
if (userEffect == null)
|
||||||
|
{
|
||||||
|
userEffect = new IceBallEffect(move.User, move.UseMove.Name);
|
||||||
|
move.User.Volatile.Add(userEffect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
userEffect.TurnCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "ice_burn")]
|
||||||
|
public class IceBurn : BaseChargeMove<RequireChargeEffect>
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override RequireChargeEffect CreateVolatile(IPokemon user) => new(user, "ice_burn");
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var battleData = move.User.BattleData;
|
||||||
|
if (battleData == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (battleData.Battle.Random.EffectChance(30, move, target, hit))
|
||||||
|
{
|
||||||
|
target.SetStatus("burned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "ice_fang")]
|
||||||
|
public class IceFang : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var battleData = move.User.BattleData;
|
||||||
|
if (battleData == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (battleData.Battle.Random.EffectChance(10, move, target, hit))
|
||||||
|
{
|
||||||
|
target.SetStatus("frozen");
|
||||||
|
}
|
||||||
|
if (battleData.Battle.Random.EffectChance(10, move, target, hit))
|
||||||
|
{
|
||||||
|
target.Volatile.Add(new FlinchEffect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "imprison")]
|
||||||
|
public class Imprison : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
target.Volatile.Add(new ImprisonEffect(move.User));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using PkmnLib.Static;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "incinerate")]
|
||||||
|
public class Incinerate : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
if (target.HeldItem is { Category: ItemCategory.Berry })
|
||||||
|
{
|
||||||
|
target.RemoveHeldItemForBattle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "infestation")]
|
||||||
|
public class Infestation : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var infestationEffect = ScriptUtils.ResolveName<InfestationEffect>();
|
||||||
|
if (target.Volatile.Contains(infestationEffect))
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var battleData = move.User.BattleData;
|
||||||
|
if (battleData == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var turns = 4;
|
||||||
|
if (battleData.Battle.Random.GetBool())
|
||||||
|
{
|
||||||
|
turns = 5;
|
||||||
|
}
|
||||||
|
target.Volatile.Add(new InfestationEffect(target, turns));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Pokemon, "heal_block")]
|
||||||
|
public class HealBlockEffect : Script
|
||||||
|
{
|
||||||
|
private int _duration;
|
||||||
|
|
||||||
|
public HealBlockEffect(int duration = 5)
|
||||||
|
{
|
||||||
|
_duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnEndTurn(IBattle battle)
|
||||||
|
{
|
||||||
|
_duration--;
|
||||||
|
if (_duration <= 0)
|
||||||
|
RemoveSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
|
||||||
|
{
|
||||||
|
if (choice.ChosenMove.MoveData.HasFlag("heal"))
|
||||||
|
prevent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventMove(IExecutingMove move, ref bool prevent)
|
||||||
|
{
|
||||||
|
if (move.ChosenMove.MoveData.HasFlag("heal"))
|
||||||
|
prevent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventHeal(IPokemon pokemon, uint heal, bool allowRevive, ref bool prevented)
|
||||||
|
{
|
||||||
|
prevented = true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
public class HelpingHandEffect : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower) =>
|
||||||
|
basePower = basePower.MultiplyOrMax(1.5f);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnEndTurn(IBattle battle) => RemoveSelf();
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Utils;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Pokemon, "ice_ball")]
|
||||||
|
public class IceBallEffect : Script
|
||||||
|
{
|
||||||
|
private readonly IPokemon _owner;
|
||||||
|
private readonly StringKey _moveName;
|
||||||
|
public int TurnCount { get; set; }
|
||||||
|
|
||||||
|
public IceBallEffect(IPokemon owner, StringKey moveName)
|
||||||
|
{
|
||||||
|
_owner = owner;
|
||||||
|
_moveName = moveName;
|
||||||
|
TurnCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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, _moveName, opposingSideIndex, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnMoveMiss(IExecutingMove move, IPokemon target)
|
||||||
|
{
|
||||||
|
RemoveSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnEndTurn(IBattle battle)
|
||||||
|
{
|
||||||
|
if (TurnCount < 5)
|
||||||
|
TurnCount++;
|
||||||
|
else
|
||||||
|
RemoveSelf();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Linq;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Pokemon, "imprison")]
|
||||||
|
public class ImprisonEffect : Script
|
||||||
|
{
|
||||||
|
private readonly IPokemon _user;
|
||||||
|
|
||||||
|
public ImprisonEffect(IPokemon user)
|
||||||
|
{
|
||||||
|
_user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
|
||||||
|
{
|
||||||
|
if (_user.Moves.WhereNotNull().Any(x => x.MoveData.Name == choice.ChosenMove.MoveData.Name))
|
||||||
|
prevent = true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Pokemon, "infestation")]
|
||||||
|
public class InfestationEffect : Script
|
||||||
|
{
|
||||||
|
private readonly IPokemon _owner;
|
||||||
|
private int _turns;
|
||||||
|
|
||||||
|
public InfestationEffect(IPokemon owner, int turns)
|
||||||
|
{
|
||||||
|
_owner = owner;
|
||||||
|
_turns = turns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventSelfSwitch(ISwitchChoice choice, ref bool prevent) => prevent = true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventSelfRunAway(IFleeChoice choice, ref bool prevent) => prevent = true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnEndTurn(IBattle battle)
|
||||||
|
{
|
||||||
|
var damage = _owner.BoostedStats.Hp / 8;
|
||||||
|
_owner.Damage(damage, DamageSource.Misc);
|
||||||
|
|
||||||
|
_turns--;
|
||||||
|
if (_turns <= 0)
|
||||||
|
{
|
||||||
|
RemoveSelf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Side, "healing_wish")]
|
||||||
|
public class HealingWishEffect : Script
|
||||||
|
{
|
||||||
|
private readonly byte _position;
|
||||||
|
|
||||||
|
public HealingWishEffect(byte position)
|
||||||
|
{
|
||||||
|
_position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSwitchIn(IPokemon pokemon, byte position)
|
||||||
|
{
|
||||||
|
if (position == _position)
|
||||||
|
{
|
||||||
|
pokemon.Heal(pokemon.BoostedStats.Hp);
|
||||||
|
pokemon.ClearStatus();
|
||||||
|
RemoveSelf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue