Even more abilities
All checks were successful
Build / Build (push) Successful in 52s

This commit is contained in:
Deukhoofd 2025-06-14 11:30:56 +02:00
parent 24712fbb0d
commit 6c13d20bf7
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
13 changed files with 278 additions and 12 deletions

View File

@ -437,9 +437,13 @@
"effect": "poison_touch" "effect": "poison_touch"
}, },
"power_construct": { "power_construct": {
"canBeChanged": false,
"effect": "power_construct" "effect": "power_construct"
}, },
"power_of_alchemy": { "power_of_alchemy": {
"flags": [
"cant_be_copied"
],
"effect": "power_of_alchemy" "effect": "power_of_alchemy"
}, },
"prankster": { "prankster": {
@ -448,13 +452,27 @@
"pressure": { "pressure": {
"effect": "pressure" "effect": "pressure"
}, },
"primordial_sea": {}, "primordial_sea": {
"prism_armor": {}, "effect": "primordial_sea"
"protean": {}, },
"psychic_surge": {}, "prism_armor": {
"pure_power": {}, "effect": "prism_armor"
"queenly_majesty": {}, },
"quick_feet": {}, "protean": {
"effect": "protean"
},
"psychic_surge": {
"effect": "psychic_surge"
},
"pure_power": {
"effect": "pure_power"
},
"queenly_majesty": {
"effect": "queenly_majesty"
},
"quick_feet": {
"effect": "quick_feet"
},
"rain_dish": {}, "rain_dish": {},
"rattled": {}, "rattled": {},
"receiver": { "receiver": {

View File

@ -8,5 +8,17 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "parental_bond")] [Script(ScriptCategory.Ability, "parental_bond")]
public class ParentalBond : Script public class ParentalBond : Script
{ {
// TODO: Implement Parental Bond effect. /// <inheritdoc />
public override void ChangeNumberOfHits(IMoveChoice choice, ref byte numberOfHits)
{
if (numberOfHits == 1)
numberOfHits = 2;
}
/// <inheritdoc />
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
{
if (hit == 1)
basePower = (ushort)(basePower / 4);
}
} }

View File

@ -0,0 +1,25 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Primordial Sea is an ability that creates heavy rain when the Pokémon enters battle and prevents Fire-type moves from being used.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Primordial_Sea_(Ability)">Bulbapedia - Primordial Sea</see>
/// </summary>
[Script(ScriptCategory.Ability, "primordial_sea")]
public class PrimordialSeaAbility : Script
{
/// <inheritdoc />
public override void OnSwitchIn(IPokemon pokemon, byte position)
{
var battle = pokemon.BattleData?.Battle;
if (battle == null)
return;
battle.SetWeather(ScriptUtils.ResolveName<Weather.PrimordialSea>(), -1);
if (battle.WeatherName == ScriptUtils.ResolveName<Weather.PrimordialSea>())
{
((Weather.PrimordialSea)battle.WeatherScript.Script!).MarkAsPlaced(pokemon);
battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
}
}
}

View File

@ -0,0 +1,17 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Prism Armor is an ability that reduces the damage taken from super effective moves.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Prism_Armor_(Ability)">Bulbapedia - Prism Armor</see>
/// </summary>
[Script(ScriptCategory.Ability, "prism_armor")]
public class PrismArmor : Script
{
/// <inheritdoc />
public override void ChangeIncomingMoveDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
{
if (move.GetHitData(target, hit).Effectiveness >= 2)
damage = (uint)(damage * 0.75);
}
}

View File

@ -0,0 +1,19 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Protean is an ability that changes the Pokémon's type to the type of the move it is about to use.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Protean_(Ability)">Bulbapedia - Protean</see>
/// </summary>
[Script(ScriptCategory.Ability, "protean")]
public class Protean : Script
{
/// <inheritdoc />
public override void OnBeforeMove(IExecutingMove move)
{
if (move.User.Types.Count == 1 && move.User.Types[0] == move.UseMove.MoveType)
return;
move.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User));
move.User.SetTypes([move.UseMove.MoveType]);
}
}

View File

@ -0,0 +1,28 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Psychic Surge is an ability that creates Psychic Terrain when the Pokémon enters battle.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Psychic_Surge_(Ability)">Bulbapedia - Psychic Surge</see>
/// </summary>
[Script(ScriptCategory.Ability, "psychic_surge")]
public class PsychicSurge : Script
{
/// <inheritdoc />
public override void OnSwitchIn(IPokemon pokemon, byte position)
{
if (pokemon.BattleData?.Battle is null)
return;
var terrainName = ScriptUtils.ResolveName<Terrain.PsychicTerrain>();
if (pokemon.BattleData.Battle.TerrainName == terrainName)
return;
EventBatchId batchId = new();
pokemon.BattleData.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});
pokemon.BattleData.Battle.SetTerrain(terrainName, batchId);
}
}

View File

@ -0,0 +1,20 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Pure Power is an ability that doubles the Pokémon's Attack stat.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Pure_Power_(Ability)">Bulbapedia - Pure Power</see>
/// </summary>
[Script(ScriptCategory.Ability, "pure_power")]
public class PurePower : Script
{
/// <inheritdoc />
public override void ChangeOffensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint defensiveStat,
ImmutableStatisticSet<uint> targetStats, Statistic stat, ref uint value)
{
if (stat == Statistic.Attack)
{
value = value.MultiplyOrMax(2);
}
}
}

View File

@ -0,0 +1,22 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Queenly Majesty is an ability that prevents priority moves from being used against the Pokémon.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Queenly_Majesty_(Ability)">Bulbapedia - Queenly Majesty</see>
/// </summary>
[Script(ScriptCategory.Ability, "queenly_majesty")]
public class QueenlyMajesty : Script
{
/// <inheritdoc />
public override void FailIncomingMove(IExecutingMove move, IPokemon target, ref bool fail)
{
if (move.Targets.Count != 1)
return;
if (move.MoveChoice.Priority > 0)
{
fail = true;
}
}
}

View File

@ -0,0 +1,20 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Quick Feet is an ability that boosts Speed when the Pokémon has a status condition.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Quick_Feet_(Ability)">Bulbapedia - Quick Feet</see>
/// </summary>
[Script(ScriptCategory.Ability, "quick_feet")]
public class QuickFeet : Script
{
/// <inheritdoc />
public override void ChangeSpeed(ITurnChoice choice, ref uint speed)
{
if (choice.User.StatusScript.IsEmpty)
return;
if (choice.User.StatusScript.Script?.Name == "paralyzed")
speed = speed.MultiplyOrMax(2);
speed = speed.MultiplyOrMax(1.5f);
}
}

View File

@ -33,4 +33,10 @@ public class DesolateLands : HarshSunlight
if (move.UseMove.MoveType.Name == "water") if (move.UseMove.MoveType.Name == "water")
fail = true; fail = true;
} }
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{
// We don't want to call base.OnEndTurn here, as we want to prevent the weather from ending
}
} }

View File

@ -6,8 +6,29 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Weather;
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Harsh_sunlight">Bulbapedia - Harsh Sunlight</see> /// <see href="https://bulbapedia.bulbagarden.net/wiki/Harsh_sunlight">Bulbapedia - Harsh Sunlight</see>
/// </summary> /// </summary>
[Script(ScriptCategory.Weather, "harsh_sunlight")] [Script(ScriptCategory.Weather, "harsh_sunlight")]
public class HarshSunlight : Script public class HarshSunlight : Script, ILimitedTurnsScript
{ {
private int? _duration;
/// <inheritdoc />
public int TurnsRemaining => _duration ?? 0;
/// <inheritdoc />
public void SetTurns(int turns)
{
_duration = turns;
}
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{
_duration--;
if (_duration <= 0)
{
battle.SetWeather(null, 0);
}
}
/// <inheritdoc /> /// <inheritdoc />
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
{ {

View File

@ -1,7 +1,7 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Weather; namespace PkmnLib.Plugin.Gen7.Scripts.Weather;
[Script(ScriptCategory.Weather, "primordial_sea")] [Script(ScriptCategory.Weather, "primordial_sea")]
public class PrimordialSea : Script public class PrimordialSea : Rain
{ {
private HashSet<IPokemon> _placers = new(); private HashSet<IPokemon> _placers = new();
@ -26,4 +26,16 @@ public class PrimordialSea : Script
return; return;
preventWeatherChange = true; preventWeatherChange = true;
} }
public override void FailMove(IExecutingMove move, ref bool fail)
{
if (move.UseMove.MoveType.Name == "fire")
fail = true;
}
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{
// We don't want to call base.OnEndTurn here, as we want to prevent the weather from ending
}
} }

View File

@ -1,7 +1,53 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Weather; namespace PkmnLib.Plugin.Gen7.Scripts.Weather;
[Script(ScriptCategory.Weather, "rain")] [Script(ScriptCategory.Weather, "rain")]
public class Rain : Script public class Rain : Script, ILimitedTurnsScript
{ {
// TODO: Implement Rain private int? _duration;
/// <inheritdoc />
public int TurnsRemaining => _duration ?? 0;
/// <inheritdoc />
public void SetTurns(int turns)
{
_duration = turns;
}
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{
_duration--;
if (_duration <= 0)
{
battle.SetWeather(null, 0);
}
}
/// <inheritdoc />
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
{
var hitType = move.GetHitData(target, hit).Type;
if (hitType?.Name == "water")
{
// Increase Water-type move power by 50% in rain
basePower = (ushort)(basePower * 1.5);
}
else if (hitType?.Name == "fire")
{
// Decrease Fire-type move power by 50% in rain
basePower = (ushort)(basePower * 0.5);
}
}
/// <inheritdoc />
public override void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex,
ref int modifiedAccuracy)
{
modifiedAccuracy = executingMove.UseMove.Name.ToString() switch
{
"thunder" or "hurricane" or "bleakwind_storm" or "windbolt_storm" or "sandsear_storm" => 1000,
_ => modifiedAccuracy,
};
}
} }