Replace all raw string comparisons with StringKey, source generator that creates cache keys for all names for Gen7 plugin
All checks were successful
Build / Build (push) Successful in 2m21s

This commit is contained in:
2026-08-27 18:30:57 +02:00
parent 3a58f55bbf
commit 942be8eaeb
160 changed files with 1035 additions and 491 deletions

View File

@@ -5,12 +5,10 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "block")]
public class Block : Script, IScriptOnSecondaryEffect
{
private static StringKey GhostTypeName => new("ghost");
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (target.Types.Any(x => x.Name == GhostTypeName))
if (target.Types.Any(x => x.Name == TypeNames.Ghost))
return;
target.Volatile.Add(new BlockEffect());
}

View File

@@ -35,7 +35,7 @@ public class Bounce : Script, IScriptPreventMove, IScriptOnBeforeMove, IScriptOn
var random = battle.Random;
if (random.EffectChance(30, move, target, hit))
{
target.SetStatus("paralyzed", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Paralyzed>(), move.User);
}
}
}

View File

@@ -10,7 +10,7 @@ public class BurnUp : Script, IScriptOnSecondaryEffect
if (battleData == null)
return;
var typeLibrary = battleData.Battle.Library.StaticLibrary.Types;
if (!typeLibrary.TryGetTypeIdentifier("fire", out var fireType))
if (!typeLibrary.TryGetTypeIdentifier(TypeNames.Fire, out var fireType))
return;
if (!move.User.Types.Contains(fireType))
{
@@ -18,7 +18,7 @@ public class BurnUp : Script, IScriptOnSecondaryEffect
return;
}
if (move.User.HasStatus("frozen"))
if (move.User.HasStatus(ScriptUtils.ResolveName<Status.Frozen>()))
move.User.ClearStatus();
move.User.RemoveType(fireType);
}

View File

@@ -20,23 +20,23 @@ public class Camouflage : Script, IScriptOnSecondaryEffect
var environmentCategory = battle.GetEnvironmentCategory();
return environmentCategory switch
{
EnvironmentHelper.EnvironmentCategory.Electric when typesLibrary.TryGetTypeIdentifier("electric",
EnvironmentHelper.EnvironmentCategory.Electric when typesLibrary.TryGetTypeIdentifier(TypeNames.Electric,
out var electricType) => electricType,
EnvironmentHelper.EnvironmentCategory.Fairy when typesLibrary.TryGetTypeIdentifier("fairy",
EnvironmentHelper.EnvironmentCategory.Fairy when typesLibrary.TryGetTypeIdentifier(TypeNames.Fairy,
out var fairyType) => fairyType,
EnvironmentHelper.EnvironmentCategory.Grass when typesLibrary.TryGetTypeIdentifier("grass",
EnvironmentHelper.EnvironmentCategory.Grass when typesLibrary.TryGetTypeIdentifier(TypeNames.Grass,
out var grassType) => grassType,
EnvironmentHelper.EnvironmentCategory.Psychic when typesLibrary.TryGetTypeIdentifier("psychic",
EnvironmentHelper.EnvironmentCategory.Psychic when typesLibrary.TryGetTypeIdentifier(TypeNames.Psychic,
out var psychicType) => psychicType,
EnvironmentHelper.EnvironmentCategory.Rock when typesLibrary.TryGetTypeIdentifier("rock", out var rockType)
=> rockType,
EnvironmentHelper.EnvironmentCategory.Ground when typesLibrary.TryGetTypeIdentifier("ground",
EnvironmentHelper.EnvironmentCategory.Rock when typesLibrary.TryGetTypeIdentifier(TypeNames.Rock,
out var rockType) => rockType,
EnvironmentHelper.EnvironmentCategory.Ground when typesLibrary.TryGetTypeIdentifier(TypeNames.Ground,
out var groundType) => groundType,
EnvironmentHelper.EnvironmentCategory.Ice when typesLibrary.TryGetTypeIdentifier("ice", out var iceType) =>
iceType,
EnvironmentHelper.EnvironmentCategory.Water when typesLibrary.TryGetTypeIdentifier("water",
EnvironmentHelper.EnvironmentCategory.Ice when typesLibrary.TryGetTypeIdentifier(TypeNames.Ice,
out var iceType) => iceType,
EnvironmentHelper.EnvironmentCategory.Water when typesLibrary.TryGetTypeIdentifier(TypeNames.Water,
out var waterType) => waterType,
EnvironmentHelper.EnvironmentCategory.Normal when typesLibrary.TryGetTypeIdentifier("normal",
EnvironmentHelper.EnvironmentCategory.Normal when typesLibrary.TryGetTypeIdentifier(TypeNames.Normal,
out var normalType) => normalType,
_ => null,
};

View File

@@ -14,7 +14,7 @@ public class Captivate : Script, IScriptOnSecondaryEffect
move.GetHitData(target, hit).Fail();
return;
}
if (target.ActiveAbility?.Name == "oblivious")
if (target.ActiveAbility?.Name == AbilityNames.Oblivious)
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -3,11 +3,14 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "conversion_2")]
public class Conversion2 : Script, IScriptOnSecondaryEffect
{
// The typeless "none" type is not part of the type data, so no generated constant exists for it.
private static readonly StringKey NoneTypeName = "none";
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var lastMoveByTarget = target.BattleData?.LastMoveChoice;
if (lastMoveByTarget == null || lastMoveByTarget.ChosenMove.MoveData.MoveType.Name == "none")
if (lastMoveByTarget == null || lastMoveByTarget.ChosenMove.MoveData.MoveType.Name == NoneTypeName)
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -12,7 +12,7 @@ public class Curse : Script, IScriptOnSecondaryEffect
if (battleData == null)
return;
var typeLibrary = battleData.Battle.Library.StaticLibrary.Types;
if (!typeLibrary.TryGetTypeIdentifier("ghost", out var ghostType))
if (!typeLibrary.TryGetTypeIdentifier(TypeNames.Ghost, out var ghostType))
return;
if (move.User.Types.Contains(ghostType))
{

View File

@@ -19,7 +19,7 @@ public class Drain : Script, IScriptOnInitialize, IScriptOnSecondaryEffect
var user = move.User;
var damage = move.GetHitData(target, hit).Damage;
var healed = (uint)(damage * DrainModifier);
if (move.User.HasHeldItem("big_root"))
if (move.User.HasHeldItem(ItemNames.BigRoot))
healed = (uint)(healed * 1.3f);
var invert = false;

View File

@@ -3,13 +3,11 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "dream_eater")]
public class DreamEater : Script, IScriptOnSecondaryEffect, IScriptBlockOutgoingHit
{
private static readonly StringKey AsleepStatus = new("asleep");
private static readonly StringKey ComatoseAbility = new("comatose");
/// <inheritdoc />
public void BlockOutgoingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
{
if (!target.HasStatus(AsleepStatus) && target.ActiveAbility?.Name != ComatoseAbility)
if (!target.HasStatus(ScriptUtils.ResolveName<Status.Sleep>()) &&
target.ActiveAbility?.Name != AbilityNames.Comatose)
block = true;
}
@@ -19,7 +17,7 @@ public class DreamEater : Script, IScriptOnSecondaryEffect, IScriptBlockOutgoing
var user = move.User;
var damage = move.GetHitData(target, hit).Damage;
var healed = (uint)(damage * 0.5f);
if (move.User.HasHeldItem("big_root"))
if (move.User.HasHeldItem(ItemNames.BigRoot))
healed = (uint)(healed * 1.3f);
var args = new CustomTriggers.ModifyDrainArgs(move, target, hit, damage, healed, false);

View File

@@ -14,7 +14,7 @@ public class FireFang : Script, IScriptOnSecondaryEffect
var random = battleData.Battle.Random;
if (random.EffectChance(10, move, target, hit))
{
target.SetStatus("burned", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Burned>(), move.User);
}
// It also has an independent 10% chance of causing the target to flinch, if the user attacks before the target.

View File

@@ -16,18 +16,19 @@ public class FirePledge : Script, IScriptStopBeforeMove
var pledgeMove = (IMoveChoice?)move.Battle.ChoiceQueue?.FirstOrDefault(x =>
x is IMoveChoice mc && mc.User.BattleData?.SideIndex == move.User.BattleData?.SideIndex &&
(mc.ChosenMove.MoveData.Name == "water_pledge" || mc.ChosenMove.MoveData.Name == "grass_pledge"));
(mc.ChosenMove.MoveData.Name == MoveNames.WaterPledge ||
mc.ChosenMove.MoveData.Name == MoveNames.GrassPledge));
if (pledgeMove is null)
return;
// If a pledge move is already queued, we stop the current move.
stop = true;
if (pledgeMove.ChosenMove.MoveData.Name == "water_pledge")
if (pledgeMove.ChosenMove.MoveData.Name == MoveNames.WaterPledge)
{
pledgeMove.Volatile.Add(new FireWaterPledgeMove());
}
else if (pledgeMove.ChosenMove.MoveData.Name == "grass_pledge")
else if (pledgeMove.ChosenMove.MoveData.Name == MoveNames.GrassPledge)
{
pledgeMove.Volatile.Add(new FireGrassPledgeMove());
}

View File

@@ -19,14 +19,14 @@ public class FlameWheel : Script, IScriptOnInitialize, IScriptOnSecondaryEffect
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (move.User.HasStatus("frozen"))
if (move.User.HasStatus(ScriptUtils.ResolveName<Status.Frozen>()))
{
move.User.ClearStatus();
}
if (move.Battle.Random.EffectChance(_burnChance, move, target, hit))
{
target.SetStatus("burned", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Burned>(), move.User);
}
}
}

View File

@@ -15,7 +15,7 @@ public class FlareBlitz : Script, IScriptOnSecondaryEffect
if (battleData.Battle.Random.EffectChance(10, move, target, hit))
{
target.SetStatus("burned", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Burned>(), move.User);
}
var triggerArgs = new CustomTriggers.ModifyRecoilArgs(move, target, hit, hitData.Damage, (uint)recoilDamage);

View File

@@ -11,7 +11,7 @@ public class FlowerShield : Script, IScriptOnSecondaryEffect
var battleData = target.BattleData;
if (battleData == null)
return;
if (!battleData.Battle.Library.StaticLibrary.Types.TryGetTypeIdentifier("grass", out var grassType))
if (!battleData.Battle.Library.StaticLibrary.Types.TryGetTypeIdentifier(TypeNames.Grass, out var grassType))
return;
var batchId = new EventBatchId();

View File

@@ -8,7 +8,7 @@ public class FlyingPress : Script, IScriptChangeTypesForMove
IList<TypeIdentifier> types)
{
var typeLibrary = executingMove.User.Library.StaticLibrary.Types;
if (!typeLibrary.TryGetTypeIdentifier("flying", out var flyingType))
if (!typeLibrary.TryGetTypeIdentifier(TypeNames.Flying, out var flyingType))
return;
types.Add(flyingType);
}

View File

@@ -12,7 +12,7 @@ public class ForestsCurse : Script, IScriptOnSecondaryEffect
if (battleData == null)
return;
var typeLibrary = battleData.Battle.Library.StaticLibrary.Types;
if (!typeLibrary.TryGetTypeIdentifier("grass", out var grassType) || target.Types.Contains(grassType))
if (!typeLibrary.TryGetTypeIdentifier(TypeNames.Grass, out var grassType) || target.Types.Contains(grassType))
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -11,7 +11,7 @@ public class FreezeDry : Script, IScriptChangeEffectiveness, IScriptOnSecondaryE
return;
var typeLibrary = battleData.Battle.Library.StaticLibrary.Types;
if (!typeLibrary.TryGetTypeIdentifier("water", out var waterType))
if (!typeLibrary.TryGetTypeIdentifier(TypeNames.Water, out var waterType))
return;
var hitDataType = move.GetHitData(target, hit).Type;
@@ -32,7 +32,7 @@ public class FreezeDry : Script, IScriptChangeEffectiveness, IScriptOnSecondaryE
if (battleData.Battle.Random.EffectChance(10, move, target, hit))
{
target.SetStatus("frozen", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Frozen>(), move.User);
}
}
}

View File

@@ -17,7 +17,7 @@ public class FreezeShock : BaseChargeMove<RequireChargeEffect>
if (battleData.Battle.Random.EffectChance(30, move, target, hit))
{
target.SetStatus("paralyzed", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Paralyzed>(), move.User);
}
}
}

View File

@@ -16,7 +16,7 @@ public class FusionBolt : Script, IScriptChangeDamageModifier
.OfType<MoveChoice>().LastOrDefault(x => !x.HasFailed);
// If Fusion Flare was used immediately preceding, Fusion Bolt's power is doubled.
if (choice is not null && choice.ChosenMove.MoveData.Name == "fusion_flare")
if (choice is not null && choice.ChosenMove.MoveData.Name == MoveNames.FusionFlare)
{
modifier *= 2;
}

View File

@@ -16,7 +16,7 @@ public class FusionFlare : Script, IScriptChangeDamageModifier
.OfType<MoveChoice>().LastOrDefault(x => !x.HasFailed);
// If Fusion Bolt was used immediately preceding, Fusion Flare's power is doubled.
if (choice is not null && choice.ChosenMove.MoveData.Name == "fusion_bolt")
if (choice is not null && choice.ChosenMove.MoveData.Name == MoveNames.FusionBolt)
{
modifier *= 2;
}

View File

@@ -15,7 +15,7 @@ public class GearUp : Script, IScriptOnSecondaryEffect
foreach (var pokemon in side.Pokemon.WhereNotNull())
{
var ability = pokemon.ActiveAbility?.Name;
if (ability != "plus" && ability != "minus")
if (ability != AbilityNames.Plus && ability != AbilityNames.Minus)
continue;
pokemon.ChangeStatBoost(Statistic.Attack, 1, pokemon == move.User, false, evtBatchId);
pokemon.ChangeStatBoost(Statistic.SpecialAttack, 1, pokemon == move.User, false, evtBatchId);

View File

@@ -16,18 +16,19 @@ public class GrassPledge : Script, IScriptStopBeforeMove
var pledgeMove = (IMoveChoice?)move.Battle.ChoiceQueue?.FirstOrDefault(x =>
x is IMoveChoice mc && mc.User.BattleData?.SideIndex == move.User.BattleData?.SideIndex &&
(mc.ChosenMove.MoveData.Name == "water_pledge" || mc.ChosenMove.MoveData.Name == "fire_pledge"));
(mc.ChosenMove.MoveData.Name == MoveNames.WaterPledge ||
mc.ChosenMove.MoveData.Name == MoveNames.FirePledge));
if (pledgeMove is null)
return;
// If a pledge move is already queued, we stop the current move.
stop = true;
if (pledgeMove.ChosenMove.MoveData.Name == "water_pledge")
if (pledgeMove.ChosenMove.MoveData.Name == MoveNames.WaterPledge)
{
pledgeMove.Volatile.Add(new GrassWaterPledgeMove());
}
else if (pledgeMove.ChosenMove.MoveData.Name == "fire_pledge")
else if (pledgeMove.ChosenMove.MoveData.Name == MoveNames.FirePledge)
{
pledgeMove.Volatile.Add(new FireGrassPledgeMove());
}

View File

@@ -14,7 +14,7 @@ public class HealBell : Script, IScriptOnSecondaryEffect
foreach (var pokemon in party.Party.WhereNotNull())
{
if (pokemon.BattleData?.IsOnBattlefield == true && pokemon.ActiveAbility?.Name == "soundproof")
if (pokemon.BattleData?.IsOnBattlefield == true && pokemon.ActiveAbility?.Name == AbilityNames.Soundproof)
continue;
pokemon.ClearStatus();
}

View File

@@ -6,7 +6,7 @@ public class Hex : Script, IScriptChangeBasePower
/// <inheritdoc />
public void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
{
if (!target.StatusScript.IsEmpty || target.ActiveAbility?.Name == "comatose")
if (!target.StatusScript.IsEmpty || target.ActiveAbility?.Name == AbilityNames.Comatose)
{
basePower = basePower.MultiplyOrMax(2);
}

View File

@@ -21,12 +21,9 @@ public class HyperspaceFury : Script, IScriptFailMove, IScriptOnSecondaryEffect
move.User.ChangeStatBoost(Statistic.Defense, -1, true, false);
}
private static StringKey HoopaName = "hoopa";
private static StringKey UnboundName = "unbound";
public void FailMove(IExecutingMove move, ref bool fail)
{
if (move.User.Species.Name != HoopaName || move.User.Form.Name != UnboundName)
if (move.User.Species.Name != SpeciesNames.Hoopa || move.User.Form.Name != FormNames.Unbound)
{
fail = true;
}

View File

@@ -17,7 +17,7 @@ public class IceBurn : BaseChargeMove<RequireChargeEffect>
if (battleData.Battle.Random.EffectChance(30, move, target, hit))
{
target.SetStatus("burned", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Burned>(), move.User);
}
}
}

View File

@@ -14,7 +14,7 @@ public class IceFang : Script, IScriptOnSecondaryEffect
var random = battleData.Battle.Random;
if (random.EffectChance(10, move, target, hit))
{
target.SetStatus("frozen", move.User);
target.SetStatus(ScriptUtils.ResolveName<Status.Frozen>(), move.User);
}
// It also has an independent 10% chance of causing the target to flinch, if the user attacks before the target.

View File

@@ -5,6 +5,27 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "judgement")]
public class Judgement : Script, IScriptChangeMoveType
{
private static readonly Dictionary<StringKey, StringKey> PlateTypes = new()
{
{ ItemNames.DreadPlate, TypeNames.Dark },
{ ItemNames.EarthPlate, TypeNames.Ground },
{ ItemNames.FistPlate, TypeNames.Fighting },
{ ItemNames.FlamePlate, TypeNames.Fire },
{ ItemNames.IciclePlate, TypeNames.Ice },
{ ItemNames.InsectPlate, TypeNames.Bug },
{ ItemNames.IronPlate, TypeNames.Steel },
{ ItemNames.MeadowPlate, TypeNames.Grass },
{ ItemNames.MindPlate, TypeNames.Psychic },
{ ItemNames.PixiePlate, TypeNames.Fairy },
{ ItemNames.SkyPlate, TypeNames.Flying },
{ ItemNames.SpookyPlate, TypeNames.Ghost },
{ ItemNames.StonePlate, TypeNames.Rock },
{ ItemNames.ToxicPlate, TypeNames.Poison },
{ ItemNames.ZapPlate, TypeNames.Electric },
{ ItemNames.DracoPlate, TypeNames.Dragon },
{ ItemNames.SplashPlate, TypeNames.Water },
};
/// <inheritdoc />
public void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier? moveType)
{
@@ -19,26 +40,10 @@ public class Judgement : Script, IScriptChangeMoveType
return;
var typeLibrary = target.Library.StaticLibrary.Types;
moveType = heldItem.Name.ToString().ToLowerInvariant() switch
if (PlateTypes.TryGetValue(heldItem.Name, out var typeName) &&
typeLibrary.TryGetTypeIdentifier(typeName, out var type))
{
"dread_plate" when typeLibrary.TryGetTypeIdentifier("dark", out var dark) => dark,
"earth_plate" when typeLibrary.TryGetTypeIdentifier("ground", out var ground) => ground,
"fist_plate" when typeLibrary.TryGetTypeIdentifier("fighting", out var fighting) => fighting,
"flame_plate" when typeLibrary.TryGetTypeIdentifier("fire", out var fire) => fire,
"icicle_plate" when typeLibrary.TryGetTypeIdentifier("ice", out var ice) => ice,
"insect_plate" when typeLibrary.TryGetTypeIdentifier("bug", out var bug) => bug,
"iron_plate" when typeLibrary.TryGetTypeIdentifier("steel", out var steel) => steel,
"meadow_plate" when typeLibrary.TryGetTypeIdentifier("grass", out var grass) => grass,
"mind_plate" when typeLibrary.TryGetTypeIdentifier("psychic", out var psychic) => psychic,
"pixie_plate" when typeLibrary.TryGetTypeIdentifier("fairy", out var fairy) => fairy,
"sky_plate" when typeLibrary.TryGetTypeIdentifier("flying", out var flying) => flying,
"spooky_plate" when typeLibrary.TryGetTypeIdentifier("ghost", out var ghost) => ghost,
"stone_plate" when typeLibrary.TryGetTypeIdentifier("rock", out var rock) => rock,
"toxic_plate" when typeLibrary.TryGetTypeIdentifier("poison", out var poison) => poison,
"zap_plate" when typeLibrary.TryGetTypeIdentifier("electric", out var electric) => electric,
"draco_plate" when typeLibrary.TryGetTypeIdentifier("dragon", out var dragon) => dragon,
"splash_plate" when typeLibrary.TryGetTypeIdentifier("water", out var water) => water,
_ => moveType,
};
moveType = type;
}
}
}

View File

@@ -14,7 +14,7 @@ public class KingsShield : ProtectionScript
if (move.GetHitData(target, hit).HasFailed)
return;
// Default form is shield form
if (move.User.Species.Name == "aegislash" && move.User.Form.Name != "default")
if (move.User.Species.Name == SpeciesNames.Aegislash && move.User.Form.Name != FormNames.Default)
{
move.User.ChangeForm(move.User.Species.GetDefaultForm());
}

View File

@@ -12,7 +12,7 @@ public class LastResort : Script, IScriptPreventMoveSelection
prevent = true;
return;
}
var userMoves = choice.User.Moves.WhereNotNull().Where(x => x.MoveData.Name != "last_resort").ToList();
var userMoves = choice.User.Moves.WhereNotNull().Where(x => x.MoveData.Name != MoveNames.LastResort).ToList();
if (userMoves.Count == 0)
{
prevent = true;

View File

@@ -8,7 +8,7 @@ public class LeechSeed : Script, IScriptOnSecondaryEffect
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (target.Types.Any(x => x.Name == "grass"))
if (target.Types.Any(x => x.Name == TypeNames.Grass))
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -9,7 +9,7 @@ public class MagnetRise : Script, IScriptOnSecondaryEffect
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (move.User.Volatile.Contains(ScriptUtils.ResolveName<IngrainEffect>()) ||
move.User.ActiveAbility?.Name == "levitate" || move.User.Volatile.Contains<MagnetRiseEffect>())
move.User.ActiveAbility?.Name == AbilityNames.Levitate || move.User.Volatile.Contains<MagnetRiseEffect>())
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -12,7 +12,7 @@ public class MagneticFlux : Script, IScriptOnSecondaryEffect
foreach (var pokemon in battleData.BattleSide.Pokemon.WhereNotNull())
{
if (pokemon.ActiveAbility?.Name != "plus" && pokemon.ActiveAbility?.Name != "minus")
if (pokemon.ActiveAbility?.Name != AbilityNames.Plus && pokemon.ActiveAbility?.Name != AbilityNames.Minus)
continue;
EventBatchId batch = new();

View File

@@ -28,7 +28,8 @@ public class MeFirst : Script, IScriptChangeMove
choice.Fail();
return;
}
if (!targetMove.ChosenMove.MoveData.CanCopyMove() || targetMove.ChosenMove.MoveData.Name == "metal_burst" ||
if (!targetMove.ChosenMove.MoveData.CanCopyMove() ||
targetMove.ChosenMove.MoveData.Name == MoveNames.MetalBurst ||
battleData.Battle.Library.MiscLibrary.IsReplacementChoice(targetMove))
{
choice.Fail();

View File

@@ -5,12 +5,10 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "mean_look")]
public class MeanLook : Script, IScriptOnSecondaryEffect
{
private static StringKey GhostTypeName => new("ghost");
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (target.Types.Any(x => x.Name == GhostTypeName))
if (target.Types.Any(x => x.Name == TypeNames.Ghost))
return;
var targetEffect = target.Volatile.Add(new MeanLookEffectTarget());
if (targetEffect == null)

View File

@@ -8,7 +8,7 @@ public class MultiAttack : Script, IScriptChangeMoveType
/// <inheritdoc />
public void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier? moveType)
{
if (move.User.ActiveAbility?.Name == "klutz")
if (move.User.ActiveAbility?.Name == AbilityNames.Klutz)
return;
if (move.Battle.Volatile.Contains<MagicRoomEffect>())
return;

View File

@@ -26,24 +26,24 @@ public class NaturePower : Script, IScriptChangeMove
var environmentCategory = battle.GetEnvironmentCategory();
var moveName = environmentCategory switch
{
EnvironmentHelper.EnvironmentCategory.Electric when movesLibrary.TryGet("thunderbolt",
EnvironmentHelper.EnvironmentCategory.Electric when movesLibrary.TryGet(MoveNames.Thunderbolt,
out var thunderboltMove) => (StringKey?)thunderboltMove.Name,
EnvironmentHelper.EnvironmentCategory.Fairy when movesLibrary.TryGet("moonblast", out var moonblastMove) =>
moonblastMove.Name,
EnvironmentHelper.EnvironmentCategory.Grass when movesLibrary.TryGet("energy_ball", out var energyballMove)
=> energyballMove.Name,
EnvironmentHelper.EnvironmentCategory.Psychic when movesLibrary.TryGet("psychic", out var psychicMove) =>
psychicMove.Name,
EnvironmentHelper.EnvironmentCategory.Rock when movesLibrary.TryGet("power_gem", out var rockMove) =>
EnvironmentHelper.EnvironmentCategory.Fairy when movesLibrary.TryGet(MoveNames.Moonblast,
out var moonblastMove) => moonblastMove.Name,
EnvironmentHelper.EnvironmentCategory.Grass when movesLibrary.TryGet(MoveNames.EnergyBall,
out var energyballMove) => energyballMove.Name,
EnvironmentHelper.EnvironmentCategory.Psychic when movesLibrary.TryGet(MoveNames.Psychic,
out var psychicMove) => psychicMove.Name,
EnvironmentHelper.EnvironmentCategory.Rock when movesLibrary.TryGet(MoveNames.PowerGem, out var rockMove) =>
rockMove.Name,
EnvironmentHelper.EnvironmentCategory.Ground when movesLibrary.TryGet("earth_power", out var groundMove) =>
groundMove.Name,
EnvironmentHelper.EnvironmentCategory.Ice when movesLibrary.TryGet("ice_beam", out var iceMove) => iceMove
.Name,
EnvironmentHelper.EnvironmentCategory.Water when movesLibrary.TryGet("hydro_pump", out var waterMove) =>
waterMove.Name,
EnvironmentHelper.EnvironmentCategory.Normal when movesLibrary.TryGet("tri_attack", out var normalMove) =>
normalMove.Name,
EnvironmentHelper.EnvironmentCategory.Ground when movesLibrary.TryGet(MoveNames.EarthPower,
out var groundMove) => groundMove.Name,
EnvironmentHelper.EnvironmentCategory.Ice when movesLibrary.TryGet(MoveNames.IceBeam, out var iceMove) =>
iceMove.Name,
EnvironmentHelper.EnvironmentCategory.Water when movesLibrary.TryGet(MoveNames.HydroPump, out var waterMove)
=> waterMove.Name,
EnvironmentHelper.EnvironmentCategory.Normal when movesLibrary.TryGet(MoveNames.TriAttack,
out var normalMove) => normalMove.Name,
_ => null,
};
return moveName;

View File

@@ -1,23 +1,27 @@
using PkmnLib.Plugin.Gen7.Scripts.Status;
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "refresh")]
public class Refresh : Script, IScriptOnSecondaryEffect
{
private static readonly StringKey[] CurableStatuses =
[
ScriptUtils.ResolveName<Paralyzed>(), ScriptUtils.ResolveName<Burned>(),
ScriptUtils.ResolveName<Poisoned>(), ScriptUtils.ResolveName<BadlyPoisoned>(),
];
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var userStatus = move.User.StatusScript;
switch (userStatus.Script?.Name)
if (userStatus.Script is { } statusScript && CurableStatuses.Contains(statusScript.Name))
{
case "paralyzed":
case "burned":
case "poisoned":
case "badly_poisoned":
move.User.ClearStatus();
break;
default:
move.GetHitData(target, hit).Fail();
break;
move.User.ClearStatus();
}
else
{
move.GetHitData(target, hit).Fail();
}
}
}

View File

@@ -7,7 +7,7 @@ public class Rototiller : Script, IScriptOnSecondaryEffect
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var pokemon = move.Battle.Sides.SelectMany(x => x.Pokemon).WhereNotNull()
.Where(x => x.Types.Any(y => y.Name == "grass"));
.Where(x => x.Types.Any(y => y.Name == TypeNames.Grass));
EventBatchId batchId = new();
foreach (var pkmn in pokemon)
{

View File

@@ -14,8 +14,9 @@ public class Round : Script, IScriptOnAfterMove
return;
}
var otherRoundMoves = choiceQueue.Where(x => x is IMoveChoice mc && mc.ChosenMove.MoveData.Name == "round")
.Cast<IMoveChoice>().ToList();
var otherRoundMoves = choiceQueue
.Where(x => x is IMoveChoice mc && mc.ChosenMove.MoveData.Name == MoveNames.Round).Cast<IMoveChoice>()
.ToList();
// We reverse the order here, as we're constantly pushing the choices to the front of the queue.
// By reversing the order, we ensure that the first choice is the one that is up next.

View File

@@ -6,7 +6,7 @@ public class SimpleBeam : Script, IScriptOnSecondaryEffect
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (!move.Battle.Library.StaticLibrary.Abilities.TryGet("simple", out var simpleAbility))
if (!move.Battle.Library.StaticLibrary.Abilities.TryGet(AbilityNames.Simple, out var simpleAbility))
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -6,7 +6,7 @@ public class Soak : Script, IScriptOnSecondaryEffect
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
if (target.ActiveAbility?.Name == "multitype")
if (target.ActiveAbility?.Name == AbilityNames.Multitype)
{
move.GetHitData(target, hit).Fail();
return;
@@ -14,7 +14,7 @@ public class Soak : Script, IScriptOnSecondaryEffect
var typeLibrary = move.Battle.Library.StaticLibrary.Types;
// If water type is not found, we can't do anything.
if (!typeLibrary.TryGetTypeIdentifier("water", out var waterType))
if (!typeLibrary.TryGetTypeIdentifier(TypeNames.Water, out var waterType))
return;
target.SetTypes([waterType]);

View File

@@ -3,6 +3,14 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "techno_blast")]
public class TechnoBlast : Script, IScriptChangeMoveType
{
private static readonly Dictionary<StringKey, StringKey> DriveTypes = new()
{
{ ItemNames.BurnDrive, TypeNames.Fire },
{ ItemNames.ChillDrive, TypeNames.Ice },
{ ItemNames.DouseDrive, TypeNames.Water },
{ ItemNames.ShockDrive, TypeNames.Electric },
};
/// <inheritdoc />
public void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier? moveType)
{
@@ -11,13 +19,10 @@ public class TechnoBlast : Script, IScriptChangeMoveType
return;
var typeLibrary = target.Library.StaticLibrary.Types;
moveType = heldItem.Name.ToString().ToLowerInvariant() switch
if (DriveTypes.TryGetValue(heldItem.Name, out var typeName) &&
typeLibrary.TryGetTypeIdentifier(typeName, out var type))
{
"burn_drive" when typeLibrary.TryGetTypeIdentifier("fire", out var fire) => fire,
"chill_drive" when typeLibrary.TryGetTypeIdentifier("ice", out var ice) => ice,
"douse_drive" when typeLibrary.TryGetTypeIdentifier("water", out var water) => water,
"shock_drive" when typeLibrary.TryGetTypeIdentifier("electric", out var electric) => electric,
_ => moveType,
};
moveType = type;
}
}
}

View File

@@ -9,7 +9,7 @@ public class TrickOrTreat : Script, IScriptOnSecondaryEffect
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var library = move.Battle.Library.StaticLibrary.Types;
if (!library.TryGetTypeIdentifier("ghost", out var ghostType) || target.Types.Contains(ghostType))
if (!library.TryGetTypeIdentifier(TypeNames.Ghost, out var ghostType) || target.Types.Contains(ghostType))
{
move.GetHitData(target, hit).Fail();
return;

View File

@@ -16,18 +16,19 @@ public class WaterPledge : Script, IScriptStopBeforeMove
var pledgeMove = (IMoveChoice?)move.Battle.ChoiceQueue?.FirstOrDefault(x =>
x is IMoveChoice mc && mc.User.BattleData?.SideIndex == move.User.BattleData?.SideIndex &&
(mc.ChosenMove.MoveData.Name == "grass_pledge" || mc.ChosenMove.MoveData.Name == "fire_pledge"));
(mc.ChosenMove.MoveData.Name == MoveNames.GrassPledge ||
mc.ChosenMove.MoveData.Name == MoveNames.FirePledge));
if (pledgeMove is null)
return;
// If a pledge move is already queued, we stop the current move.
stop = true;
if (pledgeMove.ChosenMove.MoveData.Name == "grass_pledge")
if (pledgeMove.ChosenMove.MoveData.Name == MoveNames.GrassPledge)
{
pledgeMove.Volatile.Add(new GrassWaterPledgeMove());
}
else if (pledgeMove.ChosenMove.MoveData.Name == "fire_pledge")
else if (pledgeMove.ChosenMove.MoveData.Name == MoveNames.FirePledge)
{
pledgeMove.Volatile.Add(new FireWaterPledgeMove());
}

View File

@@ -21,16 +21,16 @@ public class WeatherBall : Script, IScriptChangeMoveType, IScriptChangeBasePower
return;
if (weather == ScriptUtils.ResolveName<Weather.HarshSunlight>() &&
typeLibrary.TryGetTypeIdentifier("fire", out var fireType))
typeLibrary.TryGetTypeIdentifier(TypeNames.Fire, out var fireType))
typeIdentifier = fireType;
else if (weather == ScriptUtils.ResolveName<Weather.Rain>() &&
typeLibrary.TryGetTypeIdentifier("water", out var waterType))
typeLibrary.TryGetTypeIdentifier(TypeNames.Water, out var waterType))
typeIdentifier = waterType;
else if (weather == ScriptUtils.ResolveName<Weather.Hail>() &&
typeLibrary.TryGetTypeIdentifier("ice", out var iceType))
typeLibrary.TryGetTypeIdentifier(TypeNames.Ice, out var iceType))
typeIdentifier = iceType;
else if (weather == ScriptUtils.ResolveName<Weather.Sandstorm>() &&
typeLibrary.TryGetTypeIdentifier("rock", out var rockType))
typeLibrary.TryGetTypeIdentifier(TypeNames.Rock, out var rockType))
typeIdentifier = rockType;
}
}

View File

@@ -7,7 +7,7 @@ public class WorrySeed : Script, IScriptOnSecondaryEffect
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var abilityLibrary = move.Battle.Library.StaticLibrary.Abilities;
if (!abilityLibrary.TryGet("insomnia", out var ability))
if (!abilityLibrary.TryGet(AbilityNames.Insomnia, out var ability))
{
// Edge case: if the ability is not found, we should not change the ability.
return;