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)
|
||||
return null;
|
||||
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()) ??
|
||||
new Dictionary<StringKey, object?>();
|
||||
return new SecondaryEffectImpl(chance, name, parameters);
|
||||
|
|
|
@ -29,6 +29,6 @@ public class SerializedMove
|
|||
public class SerializedMoveEffect
|
||||
{
|
||||
public string Name { get; set; } = null!;
|
||||
public float Chance { get; set; }
|
||||
public float? Chance { get; set; }
|
||||
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));
|
||||
pokemon.RunScriptHook(script => script.OnSwitchIn(pokemon));
|
||||
pokemon.RunScriptHook(script => script.OnSwitchIn(pokemon, position));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -317,6 +317,11 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
|||
/// </summary>
|
||||
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>
|
||||
/// 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.
|
||||
|
@ -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)
|
||||
{
|
||||
// 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)
|
||||
return false;
|
||||
|
||||
var maxAmount = BoostedStats.Hp - CurrentHealth;
|
||||
if (heal > maxAmount)
|
||||
heal = maxAmount;
|
||||
if (heal == 0)
|
||||
return false;
|
||||
var prevented = false;
|
||||
this.RunScriptHook(x => x.PreventHeal(this, heal, allowRevive, ref prevented));
|
||||
if (prevented)
|
||||
return false;
|
||||
|
||||
var newHealth = CurrentHealth + heal;
|
||||
BattleData?.Battle.EventHook.Invoke(new HealEvent(this, 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
|
||||
/// the battlefield.
|
||||
/// </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 PreventHeal(IPokemon pokemon, uint heal, bool allowRevive, ref bool prevented)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -13,6 +13,11 @@ public interface IReadOnlyTypeLibrary
|
|||
/// </summary>
|
||||
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>
|
||||
/// Gets the effectiveness for a single attacking type against a single defending type.
|
||||
/// </summary>
|
||||
|
@ -46,6 +51,18 @@ public class TypeLibrary : IReadOnlyTypeLibrary
|
|||
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 />
|
||||
public float GetSingleEffectiveness(TypeIdentifier attacking, TypeIdentifier defending)
|
||||
{
|
||||
|
|
|
@ -4788,7 +4788,13 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"punch"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "change_user_speed",
|
||||
"parameters": {
|
||||
"amount": -1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "happy_hour",
|
||||
|
@ -4800,6 +4806,7 @@
|
|||
"target": "AllAlly",
|
||||
"category": "status",
|
||||
"flags": []
|
||||
// TODO: Add effect
|
||||
},
|
||||
{
|
||||
"name": "harden",
|
||||
|
@ -4812,7 +4819,13 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"snatch"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "change_user_defense",
|
||||
"parameters": {
|
||||
"amount": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "haze",
|
||||
|
@ -4825,7 +4838,10 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"ignore-substitute"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "reset_target_stats"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "head_charge",
|
||||
|
@ -4840,7 +4856,13 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "recoil",
|
||||
"parameters": {
|
||||
"amount": 0.25
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "head_smash",
|
||||
|
@ -4855,7 +4877,13 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "recoil",
|
||||
"parameters": {
|
||||
"amount": 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headbutt",
|
||||
|
@ -4870,7 +4898,11 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "flinch",
|
||||
"chance": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heal_bell",
|
||||
|
@ -4886,7 +4918,10 @@
|
|||
"sound",
|
||||
"distance",
|
||||
"ignore-substitute"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "heal_bell"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heal_block",
|
||||
|
@ -4902,7 +4937,10 @@
|
|||
"reflectable",
|
||||
"mirror",
|
||||
"limit_move_choice"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "heal_block"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heal_order",
|
||||
|
@ -4916,7 +4954,13 @@
|
|||
"flags": [
|
||||
"snatch",
|
||||
"heal"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "heal_percent",
|
||||
"parameters": {
|
||||
"healPercent": 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heal_pulse",
|
||||
|
@ -4933,7 +4977,13 @@
|
|||
"distance",
|
||||
"heal",
|
||||
"pulse"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "heal_percent",
|
||||
"parameters": {
|
||||
"healPercent": 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "healing_wish",
|
||||
|
@ -4947,7 +4997,10 @@
|
|||
"flags": [
|
||||
"snatch",
|
||||
"heal"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "healing_wish"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heart_stamp",
|
||||
|
@ -4962,7 +5015,11 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "flinch",
|
||||
"chance": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heart_swap",
|
||||
|
@ -4977,7 +5034,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"ignore-substitute"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "heart_swap"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heat_crash",
|
||||
|
@ -4993,7 +5053,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"nonskybattle"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "heat_crash"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heat_wave",
|
||||
|
@ -5007,7 +5070,14 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "set_status",
|
||||
"chance": 10,
|
||||
"parameters": {
|
||||
"status": "burned"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "heavy_slam",
|
||||
|
@ -5023,7 +5093,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"nonskybattle"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "heat_crash"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "helping_hand",
|
||||
|
@ -5036,7 +5109,10 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"ignore-substitute"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "helping_hand"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hex",
|
||||
|
@ -5050,7 +5126,10 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "hex"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hidden_power",
|
||||
|
@ -5064,7 +5143,10 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "hidden_power"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "high_horsepower",
|
||||
|
@ -5080,6 +5162,7 @@
|
|||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
// No secondary effect
|
||||
},
|
||||
{
|
||||
"name": "high_jump_kick",
|
||||
|
@ -5095,7 +5178,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"gravity"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "high_jump_kick"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hold_back",
|
||||
|
@ -5110,7 +5196,10 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "false_swipe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hold_hands",
|
||||
|
@ -5124,6 +5213,7 @@
|
|||
"flags": [
|
||||
"ignore-substitute"
|
||||
]
|
||||
// Does nothing
|
||||
},
|
||||
{
|
||||
"name": "hone_claws",
|
||||
|
@ -5136,7 +5226,14 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"snatch"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "change_multiple_user_stat_boosts",
|
||||
"parameters": {
|
||||
"attack": 1,
|
||||
"accuracy": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "horn_attack",
|
||||
|
@ -5152,6 +5249,7 @@
|
|||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
// No secondary effect
|
||||
},
|
||||
{
|
||||
"name": "horn_drill",
|
||||
|
@ -5166,7 +5264,10 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "one_hit_ko"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "horn_leech",
|
||||
|
@ -5182,7 +5283,13 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"heal"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "drain",
|
||||
"parameters": {
|
||||
"drain_modifier": 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "howl",
|
||||
|
@ -5195,7 +5302,13 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"snatch"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "change_user_attack",
|
||||
"parameters": {
|
||||
"amount": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hurricane",
|
||||
|
@ -5210,7 +5323,11 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"distance"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "confuse",
|
||||
"chance": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hydro_cannon",
|
||||
|
@ -5225,7 +5342,10 @@
|
|||
"recharge",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "requires_recharge"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hydro_pump",
|
||||
|
@ -5240,6 +5360,7 @@
|
|||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
// No secondary effect
|
||||
},
|
||||
{
|
||||
"name": "hydro_vortex__physical",
|
||||
|
@ -5276,7 +5397,10 @@
|
|||
"recharge",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "requires_recharge"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hyper_fang",
|
||||
|
@ -5291,7 +5415,11 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "flinch",
|
||||
"chance": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hyper_voice",
|
||||
|
@ -5308,6 +5436,7 @@
|
|||
"sound",
|
||||
"ignore-substitute"
|
||||
]
|
||||
// No secondary effect
|
||||
},
|
||||
{
|
||||
"name": "hyperspace_fury",
|
||||
|
@ -5320,8 +5449,12 @@
|
|||
"category": "physical",
|
||||
"flags": [
|
||||
"mirror",
|
||||
"ignore-substitute"
|
||||
]
|
||||
"ignore-substitute",
|
||||
"protect"
|
||||
],
|
||||
"effect": {
|
||||
"name": "hyperspace_fury"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hyperspace_hole",
|
||||
|
@ -5334,8 +5467,12 @@
|
|||
"category": "special",
|
||||
"flags": [
|
||||
"mirror",
|
||||
"ignore-substitute"
|
||||
]
|
||||
"ignore-substitute",
|
||||
"protect"
|
||||
],
|
||||
"effect": {
|
||||
"name": "hyperspace_fury"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hypnosis",
|
||||
|
@ -5350,7 +5487,13 @@
|
|||
"protect",
|
||||
"reflectable",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "set_status",
|
||||
"parameters": {
|
||||
"status": "sleep"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ice_ball",
|
||||
|
@ -5366,7 +5509,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"ballistics"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "ice_ball"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ice_beam",
|
||||
|
@ -5380,7 +5526,14 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "set_status",
|
||||
"chance": 10,
|
||||
"parameters": {
|
||||
"status": "frozen"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ice_burn",
|
||||
|
@ -5395,7 +5548,10 @@
|
|||
"charge",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "ice_burn"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ice_fang",
|
||||
|
@ -5411,7 +5567,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"bite"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "ice_fang"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ice_hammer",
|
||||
|
@ -5427,7 +5586,13 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"punch"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "change_target_speed",
|
||||
"parameters": {
|
||||
"amount": -1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ice_punch",
|
||||
|
@ -5443,7 +5608,14 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"punch"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "set_status",
|
||||
"chance": 10,
|
||||
"parameters": {
|
||||
"status": "frozen"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ice_shard",
|
||||
|
@ -5458,6 +5630,7 @@
|
|||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
// No secondary effect
|
||||
},
|
||||
{
|
||||
"name": "icicle_crash",
|
||||
|
@ -5471,7 +5644,11 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "flinch",
|
||||
"chance": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "icicle_spear",
|
||||
|
@ -5485,7 +5662,10 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "2_5_hit_move"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "icy_wind",
|
||||
|
@ -5499,7 +5679,14 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "change_target_speed",
|
||||
"chance": 100,
|
||||
"parameters": {
|
||||
"amount": -1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "imprison",
|
||||
|
@ -5513,7 +5700,10 @@
|
|||
"flags": [
|
||||
"snatch",
|
||||
"ignore-substitute"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "imprison"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "incinerate",
|
||||
|
@ -5527,7 +5717,10 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "incinerate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "inferno",
|
||||
|
@ -5541,7 +5734,14 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "set_status",
|
||||
"chance": 100,
|
||||
"parameters": {
|
||||
"status": "burned"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "inferno_overdrive__physical",
|
||||
|
@ -5578,7 +5778,10 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "infestation"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ingrain",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\PkmnLib.Dataloader\PkmnLib.Dataloader.csproj"/>
|
||||
<ProjectReference Include="..\..\PkmnLib.Dynamic\PkmnLib.Dynamic.csproj"/>
|
||||
<ProjectReference Include="..\PkmnLib.Plugin.Gen7\PkmnLib.Plugin.Gen7.csproj"/>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -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.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
|
@ -12,7 +14,8 @@ public class FuryCutter : Script
|
|||
if (userEffect == null)
|
||||
return;
|
||||
|
||||
if (userEffect.TurnCount < 5)
|
||||
userEffect.TurnCount++;
|
||||
basePower = (byte)(basePower * (userEffect.TurnCount + 1));
|
||||
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