Implements more move effects
This commit is contained in:
parent
2c987e32ee
commit
a6c73a9c04
|
@ -80,6 +80,12 @@ public interface ILearnedMove : IDeepCloneable
|
|||
/// Restore the remaining PP by a certain amount. Will prevent it from going above max PP.
|
||||
/// </summary>
|
||||
void RestoreUses(byte amount);
|
||||
|
||||
/// <summary>
|
||||
/// Forcibly set the remaining PP to a certain amount.
|
||||
/// </summary>
|
||||
/// <param name="uses"></param>
|
||||
void SetCurrentPP(byte uses);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -136,4 +142,10 @@ public class LearnedMoveImpl : ILearnedMove
|
|||
/// Restore the PP by a certain amount. This will prevent the PP from going above the maximum PP.
|
||||
/// </summary>
|
||||
public void RestoreUses(byte amount) => CurrentPp = (byte)Math.Min(CurrentPp + amount, MaxPp);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetCurrentPP(byte uses)
|
||||
{
|
||||
CurrentPp = Math.Min(uses, MaxPp);
|
||||
}
|
||||
}
|
|
@ -1091,6 +1091,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||
Types = Form.Types;
|
||||
OverrideAbility = null;
|
||||
AbilitySuppressed = false;
|
||||
RecalculateFlatStats();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public interface IScriptSet : IEnumerable<ScriptContainer>
|
|||
/// Adds a script with a name to the set. If the script with that name already exists in this
|
||||
/// set, this makes that script stack instead. The return value here is that script.
|
||||
/// </summary>
|
||||
ScriptContainer? StackOrAdd(StringKey scriptKey, Func<Script> instantiation);
|
||||
ScriptContainer? StackOrAdd(StringKey scriptKey, Func<Script?> instantiation);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a script from the set using its unique name.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PP/@EntryIndexedValue">PP</s:String></wpf:ResourceDictionary>
|
|
@ -4572,7 +4572,10 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"nonskybattle"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "gravity"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "growl",
|
||||
|
@ -4609,7 +4612,14 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"snatch"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "change_multiple_user_stat_boosts",
|
||||
"parameters": {
|
||||
"attack": 1,
|
||||
"specialAttack": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "grudge",
|
||||
|
@ -4622,7 +4632,10 @@
|
|||
"category": "status",
|
||||
"flags": [
|
||||
"ignore-substitute"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "grudge"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "guard_split",
|
||||
|
@ -4650,7 +4663,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"ignore-substitute"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "guard_swap"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "guardian_of_alola",
|
||||
|
@ -4661,7 +4677,10 @@
|
|||
"priority": 0,
|
||||
"target": "Any",
|
||||
"category": "special",
|
||||
"flags": []
|
||||
"flags": [],
|
||||
"effect": {
|
||||
"name": "guardian_of_alola"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "guillotine",
|
||||
|
@ -4676,7 +4695,10 @@
|
|||
"contact",
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "one_hit_ko"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gunk_shot",
|
||||
|
@ -4690,7 +4712,14 @@
|
|||
"flags": [
|
||||
"protect",
|
||||
"mirror"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "set_status",
|
||||
"chance": 30,
|
||||
"parameters": {
|
||||
"status": "poisoned"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gust",
|
||||
|
@ -4723,7 +4752,10 @@
|
|||
"protect",
|
||||
"mirror",
|
||||
"ballistics"
|
||||
]
|
||||
],
|
||||
"effect": {
|
||||
"name": "gyro_ball"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hail",
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Battle;
|
||||
|
||||
[Script(ScriptCategory.Battle, "gravity")]
|
||||
public class Gravity : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeEffectiveness(IExecutingMove move, IPokemon target, byte hit, ref float effectiveness)
|
||||
{
|
||||
var battleData = target.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
|
||||
if (move.UseMove.MoveType.Name == "ground")
|
||||
{
|
||||
var targetTypes = target.Types;
|
||||
var typeLibrary = battleData.Battle.Library.StaticLibrary.Types;
|
||||
effectiveness =
|
||||
// Get the effectiveness of the move against each target type
|
||||
targetTypes.Select(x => typeLibrary.GetSingleEffectiveness(move.UseMove.MoveType, x))
|
||||
// Ignore all types that are immune to ground moves
|
||||
.Where(x => x > 0)
|
||||
// Multiply all effectiveness values together
|
||||
.Aggregate(1.0f, (current, x) => current * x);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void FailIncomingMove(IExecutingMove move, IPokemon target, ref bool fail)
|
||||
{
|
||||
if (move.UseMove.HasFlag("gravity"))
|
||||
fail = true;
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ public class ChangeMultipleUserStatBoosts : Script
|
|||
foreach (var par in parameters)
|
||||
{
|
||||
if (!Enum.TryParse<Statistic>(par.Key, true, out var stat))
|
||||
continue;
|
||||
throw new ArgumentException($"Invalid stat name: {par.Key}");
|
||||
if (par.Value is sbyte value)
|
||||
{
|
||||
_statBoosts[stat] = value;
|
||||
|
|
|
@ -9,6 +9,6 @@ public class Frustration : Script
|
|||
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||
{
|
||||
var friendship = move.User.Happiness;
|
||||
basePower = Math.Min((byte)1, (byte)((255 - friendship) * 2 / 5));
|
||||
basePower = Math.Max((byte)1, (byte)((255 - friendship) * 2 / 5));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "gravity")]
|
||||
public class Gravity : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var battleData = target.BattleData;
|
||||
if (battleData == null)
|
||||
return;
|
||||
|
||||
battleData.Battle.Volatile.StackOrAdd("gravity", () =>
|
||||
{
|
||||
battleData.Battle.Library.ScriptResolver.TryResolve(ScriptCategory.Battle, "gravity",
|
||||
new Dictionary<StringKey, object?>(), out var script);
|
||||
return script;
|
||||
});
|
||||
|
||||
foreach (var pokemon in battleData.Battle.Sides.SelectMany(x => x.Pokemon).WhereNotNull())
|
||||
{
|
||||
var chargeBounceEffect = ScriptUtils.ResolveName<ChargeBounceEffect>();
|
||||
if (pokemon.Volatile.Contains(chargeBounceEffect))
|
||||
pokemon.Volatile.Remove(chargeBounceEffect);
|
||||
var flyEffect = ScriptUtils.ResolveName<ChargeFlyEffect>();
|
||||
if (pokemon.Volatile.Contains(flyEffect))
|
||||
pokemon.Volatile.Remove(flyEffect);
|
||||
// TODO: Sky Drop
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System.Collections.Generic;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "grudge")]
|
||||
public class Grudge : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
move.User.Volatile.StackOrAdd("grudge", () =>
|
||||
{
|
||||
move.User.Library.ScriptResolver.TryResolve(ScriptCategory.Pokemon, "grudge",
|
||||
new Dictionary<StringKey, object?>(), out var script);
|
||||
return script;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "guard_split")]
|
||||
public class GuardSplit : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
var user = move.User;
|
||||
var userStats = user.FlatStats;
|
||||
var targetStats = target.FlatStats;
|
||||
|
||||
var userDefense = userStats.GetStatistic(Statistic.Defense);
|
||||
var targetDefense = targetStats.GetStatistic(Statistic.Defense);
|
||||
var userSpecialDefense = userStats.GetStatistic(Statistic.SpecialDefense);
|
||||
var targetSpecialDefense = targetStats.GetStatistic(Statistic.SpecialDefense);
|
||||
|
||||
var newDefense = (userDefense + targetDefense) / 2;
|
||||
var newSpecialDefense = (userSpecialDefense + targetSpecialDefense) / 2;
|
||||
|
||||
userStats.SetStatistic(Statistic.Defense, newDefense);
|
||||
userStats.SetStatistic(Statistic.SpecialDefense, newSpecialDefense);
|
||||
user.RecalculateFlatStats();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "guard_swap")]
|
||||
public class GuardSwap : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
EventBatchId eventBatchId = new();
|
||||
|
||||
var user = move.User;
|
||||
var userStats = user.StatBoost;
|
||||
var targetStats = target.StatBoost;
|
||||
|
||||
var userDefense = userStats.GetStatistic(Statistic.Defense);
|
||||
var targetDefense = targetStats.GetStatistic(Statistic.Defense);
|
||||
var userSpecialDefense = userStats.GetStatistic(Statistic.SpecialDefense);
|
||||
var targetSpecialDefense = targetStats.GetStatistic(Statistic.SpecialDefense);
|
||||
|
||||
user.ChangeStatBoost(Statistic.Defense, (sbyte)(targetDefense - userDefense), true, eventBatchId);
|
||||
user.ChangeStatBoost(Statistic.SpecialDefense, (sbyte)(targetSpecialDefense - userSpecialDefense), true,
|
||||
eventBatchId);
|
||||
target.ChangeStatBoost(Statistic.Defense, (sbyte)(userDefense - targetDefense), false, eventBatchId);
|
||||
target.ChangeStatBoost(Statistic.SpecialDefense, (sbyte)(userSpecialDefense - targetSpecialDefense), false,
|
||||
eventBatchId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "guardian_of_alola")]
|
||||
public class GuardianOfAlola : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeMoveDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
|
||||
{
|
||||
var maxHp = target.BoostedStats.Hp;
|
||||
damage = (uint)(maxHp * (3f / 4f));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
|
||||
[Script(ScriptCategory.Move, "gyro_ball")]
|
||||
public class GyroBall : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||
{
|
||||
basePower = Math.Min((byte)150, (byte)(25 * target.BoostedStats.Speed / move.User.BoostedStats.Speed + 1));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||
|
||||
[Script(ScriptCategory.Pokemon, "grudge")]
|
||||
public class GrudgeEffect : Script
|
||||
{
|
||||
private ILearnedMove? _lastMove;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
_lastMove = move.ChosenMove;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnFaint(IPokemon pokemon, DamageSource source)
|
||||
{
|
||||
if (_lastMove != null && source == DamageSource.MoveDamage)
|
||||
{
|
||||
_lastMove.SetCurrentPP(0);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue