This commit is contained in:
@@ -19,7 +19,7 @@ public static class MoveTurnExecutor
|
||||
var useMove = chosenMove.MoveData;
|
||||
|
||||
var moveDataName = useMove.Name;
|
||||
moveChoice.RunScriptHookInterface<IScriptChangeMove>(x => x.ChangeMove(moveChoice, ref moveDataName));
|
||||
moveChoice.RunScriptHook<IScriptChangeMove>(x => x.ChangeMove(moveChoice, ref moveDataName));
|
||||
if (useMove.Name != moveDataName)
|
||||
{
|
||||
if (!battle.Library.StaticLibrary.Moves.TryGet(moveDataName, out useMove))
|
||||
@@ -46,12 +46,12 @@ public static class MoveTurnExecutor
|
||||
moveChoice.Script.Clear();
|
||||
}
|
||||
}
|
||||
moveChoice.RunScriptHook(x => x.OnBeforeMoveChoice(moveChoice));
|
||||
moveChoice.RunScriptHook<IScriptOnBeforeMoveChoice>(x => x.OnBeforeMoveChoice(moveChoice));
|
||||
|
||||
var targetType = useMove.Target;
|
||||
var targets =
|
||||
TargetResolver.ResolveTargets(battle, moveChoice.TargetSide, moveChoice.TargetPosition, targetType);
|
||||
moveChoice.RunScriptHookInterface<IScriptChangeTargets>(x => x.ChangeTargets(moveChoice, ref targets));
|
||||
moveChoice.RunScriptHook<IScriptChangeTargets>(x => x.ChangeTargets(moveChoice, ref targets));
|
||||
if (targets.Count == 0)
|
||||
{
|
||||
moveChoice.Fail();
|
||||
@@ -60,13 +60,11 @@ public static class MoveTurnExecutor
|
||||
|
||||
foreach (var target in targets.WhereNotNull())
|
||||
{
|
||||
target.RunScriptHookInterface<IScriptChangeIncomingTargets>(x =>
|
||||
x.ChangeIncomingTargets(moveChoice, ref targets));
|
||||
target.RunScriptHook<IScriptChangeIncomingTargets>(x => x.ChangeIncomingTargets(moveChoice, ref targets));
|
||||
}
|
||||
|
||||
byte numberOfHits = 1;
|
||||
moveChoice.RunScriptHookInterface<IScriptChangeNumberOfHits>(x =>
|
||||
x.ChangeNumberOfHits(moveChoice, ref numberOfHits));
|
||||
moveChoice.RunScriptHook<IScriptChangeNumberOfHits>(x => x.ChangeNumberOfHits(moveChoice, ref numberOfHits));
|
||||
if (numberOfHits == 0)
|
||||
{
|
||||
return;
|
||||
@@ -77,18 +75,20 @@ public static class MoveTurnExecutor
|
||||
battle.EventHook.Invoke(new MoveUseEvent(executingMove));
|
||||
|
||||
var prevented = false;
|
||||
executingMove.RunScriptHookInterface<IScriptPreventMove>(x => x.PreventMove(executingMove, ref prevented));
|
||||
executingMove.RunScriptHook<IScriptPreventMove>(x => x.PreventMove(executingMove, ref prevented));
|
||||
if (prevented)
|
||||
return;
|
||||
|
||||
byte ppUsed = 1;
|
||||
executingMove.RunScriptHook(x => x.ModifyPPUsed(executingMove, ref ppUsed));
|
||||
targets.WhereNotNull().RunScriptHook(x => x.ModifyPPUsedForIncomingMove(executingMove, ref ppUsed));
|
||||
executingMove.RunScriptHook<IScriptModifyPPUsed>(x => x.ModifyPPUsed(executingMove, ref ppUsed));
|
||||
targets.WhereNotNull()
|
||||
.RunScriptHook<IScriptModifyPPUsedForIncomingMove>(x =>
|
||||
x.ModifyPPUsedForIncomingMove(executingMove, ref ppUsed));
|
||||
if (!executingMove.ChosenMove.TryUse(ppUsed))
|
||||
return;
|
||||
|
||||
var failed = false;
|
||||
executingMove.RunScriptHookInterface<IScriptFailMove>(x => x.FailMove(executingMove, ref failed));
|
||||
executingMove.RunScriptHook<IScriptFailMove>(x => x.FailMove(executingMove, ref failed));
|
||||
if (failed)
|
||||
{
|
||||
// TODO: fail handling
|
||||
@@ -111,16 +111,16 @@ public static class MoveTurnExecutor
|
||||
public static void ExecuteMove(IExecutingMove executingMove)
|
||||
{
|
||||
var stopped = false;
|
||||
executingMove.RunScriptHookInterface<IScriptStopBeforeMove>(x => x.StopBeforeMove(executingMove, ref stopped));
|
||||
executingMove.RunScriptHook<IScriptStopBeforeMove>(x => x.StopBeforeMove(executingMove, ref stopped));
|
||||
if (stopped)
|
||||
return;
|
||||
|
||||
executingMove.RunScriptHookInterface<IScriptOnBeforeMove>(x => x.OnBeforeMove(executingMove));
|
||||
executingMove.RunScriptHook<IScriptOnBeforeMove>(x => x.OnBeforeMove(executingMove));
|
||||
foreach (var target in executingMove.Targets.WhereNotNull())
|
||||
{
|
||||
ExecuteMoveChoiceForTarget(executingMove.Battle, executingMove, target);
|
||||
}
|
||||
executingMove.RunScriptHookInterface<IScriptOnAfterMove>(x => x.OnAfterMove(executingMove));
|
||||
executingMove.RunScriptHook<IScriptOnAfterMove>(x => x.OnAfterMove(executingMove));
|
||||
}
|
||||
|
||||
private static readonly ThreadLocal<List<TypeIdentifier>> TypeListCache = new(() => []);
|
||||
@@ -128,8 +128,7 @@ public static class MoveTurnExecutor
|
||||
private static void ExecuteMoveChoiceForTarget(IBattle battle, IExecutingMove executingMove, IPokemon target)
|
||||
{
|
||||
var failed = false;
|
||||
target.RunScriptHookInterface<IScriptFailIncomingMove>(x =>
|
||||
x.FailIncomingMove(executingMove, target, ref failed));
|
||||
target.RunScriptHook<IScriptFailIncomingMove>(x => x.FailIncomingMove(executingMove, target, ref failed));
|
||||
if (failed)
|
||||
{
|
||||
// TODO: fail handling
|
||||
@@ -137,7 +136,7 @@ public static class MoveTurnExecutor
|
||||
}
|
||||
|
||||
var isInvulnerable = false;
|
||||
target.RunScriptHookInterface<IScriptIsInvulnerableToMove>(x =>
|
||||
target.RunScriptHook<IScriptIsInvulnerableToMove>(x =>
|
||||
x.IsInvulnerableToMove(executingMove, target, ref isInvulnerable));
|
||||
if (isInvulnerable)
|
||||
{
|
||||
@@ -158,7 +157,7 @@ public static class MoveTurnExecutor
|
||||
break;
|
||||
|
||||
var hitIndex = i;
|
||||
executingMove.RunScriptHook(x => x.OnBeforeHit(executingMove, target, hitIndex));
|
||||
executingMove.RunScriptHook<IScriptOnBeforeHit>(x => x.OnBeforeHit(executingMove, target, hitIndex));
|
||||
var hitData = (HitData)executingMove.GetDataFromRawIndex(targetHitStat + i);
|
||||
if (hitData.HasFailed)
|
||||
break;
|
||||
@@ -166,11 +165,12 @@ public static class MoveTurnExecutor
|
||||
var useMove = executingMove.UseMove;
|
||||
|
||||
var isContact = useMove.HasFlag("contact");
|
||||
executingMove.RunScriptHook(x => x.ModifyIsContact(executingMove, target, hitIndex, ref isContact));
|
||||
executingMove.RunScriptHook<IScriptModifyIsContact>(x =>
|
||||
x.ModifyIsContact(executingMove, target, hitIndex, ref isContact));
|
||||
hitData.IsContact = isContact;
|
||||
|
||||
var hitType = (TypeIdentifier?)useMove.MoveType;
|
||||
executingMove.RunScriptHookInterface<IScriptChangeMoveType>(x =>
|
||||
executingMove.RunScriptHook<IScriptChangeMoveType>(x =>
|
||||
x.ChangeMoveType(executingMove, target, hitIndex, ref hitType));
|
||||
|
||||
hitData.Type = hitType;
|
||||
@@ -180,22 +180,24 @@ public static class MoveTurnExecutor
|
||||
types.Clear();
|
||||
types.AddRange(target.Types);
|
||||
|
||||
executingMove.RunScriptHook(x => x.ChangeTypesForMove(executingMove, target, hitIndex, types));
|
||||
target.RunScriptHook(x => x.ChangeTypesForIncomingMove(executingMove, target, hitIndex, types));
|
||||
executingMove.RunScriptHook<IScriptChangeTypesForMove>(x =>
|
||||
x.ChangeTypesForMove(executingMove, target, hitIndex, types));
|
||||
target.RunScriptHook<IScriptChangeTypesForIncomingMove>(x =>
|
||||
x.ChangeTypesForIncomingMove(executingMove, target, hitIndex, types));
|
||||
|
||||
var effectiveness = hitType == null
|
||||
? 1
|
||||
: battle.Library.StaticLibrary.Types.GetEffectiveness(hitType.Value, types);
|
||||
executingMove.RunScriptHookInterface<IScriptChangeEffectiveness>(x =>
|
||||
executingMove.RunScriptHook<IScriptChangeEffectiveness>(x =>
|
||||
x.ChangeEffectiveness(executingMove, target, hitIndex, ref effectiveness));
|
||||
target.RunScriptHookInterface<IScriptChangeIncomingEffectiveness>(x =>
|
||||
target.RunScriptHook<IScriptChangeIncomingEffectiveness>(x =>
|
||||
x.ChangeIncomingEffectiveness(executingMove, target, hitIndex, ref effectiveness));
|
||||
hitData.Effectiveness = effectiveness;
|
||||
|
||||
var blockCritical = false;
|
||||
executingMove.RunScriptHookInterface<IScriptBlockCriticalHit>(x =>
|
||||
executingMove.RunScriptHook<IScriptBlockCriticalHit>(x =>
|
||||
x.BlockCriticalHit(executingMove, target, hitIndex, ref blockCritical));
|
||||
target.RunScriptHookInterface<IScriptBlockIncomingCriticalHit>(x =>
|
||||
target.RunScriptHook<IScriptBlockIncomingCriticalHit>(x =>
|
||||
x.BlockIncomingCriticalHit(executingMove, target, hitIndex, ref blockCritical));
|
||||
if (!blockCritical)
|
||||
{
|
||||
@@ -220,22 +222,23 @@ public static class MoveTurnExecutor
|
||||
|
||||
if (accuracy < 100 && battle.Random.GetInt(100) >= accuracy)
|
||||
{
|
||||
executingMove.RunScriptHookInterface<IScriptOnMoveMiss>(x => x.OnMoveMiss(executingMove, target));
|
||||
executingMove.RunScriptHook<IScriptOnMoveMiss>(x => x.OnMoveMiss(executingMove, target));
|
||||
battle.EventHook.Invoke(new MoveMissEvent(executingMove));
|
||||
break;
|
||||
}
|
||||
|
||||
var blockIncomingHit = false;
|
||||
target.RunScriptHookInterface<IScriptBlockIncomingHit>(x =>
|
||||
target.RunScriptHook<IScriptBlockIncomingHit>(x =>
|
||||
x.BlockIncomingHit(executingMove, target, hitIndex, ref blockIncomingHit));
|
||||
executingMove.RunScriptHookInterface<IScriptBlockOutgoingHit>(x =>
|
||||
executingMove.RunScriptHook<IScriptBlockOutgoingHit>(x =>
|
||||
x.BlockOutgoingHit(executingMove, target, hitIndex, ref blockIncomingHit));
|
||||
if (blockIncomingHit)
|
||||
break;
|
||||
if (executingMove.GetHitData(target, hitIndex).HasFailed)
|
||||
break;
|
||||
var category = useMove.Category;
|
||||
executingMove.RunScriptHook(x => x.ChangeCategory(executingMove, target, hitIndex, ref category));
|
||||
executingMove.RunScriptHook<IScriptChangeCategory>(x =>
|
||||
x.ChangeCategory(executingMove, target, hitIndex, ref category));
|
||||
if (category == MoveCategory.Status)
|
||||
{
|
||||
var secondaryEffect = useMove.SecondaryEffect;
|
||||
@@ -244,7 +247,7 @@ public static class MoveTurnExecutor
|
||||
var chance = secondaryEffect.Chance;
|
||||
if (chance < 0 || battle.Random.EffectChance(chance, executingMove, target, hitIndex))
|
||||
{
|
||||
executingMove.RunScriptHookInterface<IScriptOnSecondaryEffect>(x =>
|
||||
executingMove.RunScriptHook<IScriptOnSecondaryEffect>(x =>
|
||||
x.OnSecondaryEffect(executingMove, target, hitIndex));
|
||||
}
|
||||
}
|
||||
@@ -268,12 +271,12 @@ public static class MoveTurnExecutor
|
||||
target.Damage(damage, DamageSource.MoveDamage, hitEventBatch);
|
||||
if (!target.IsFainted)
|
||||
{
|
||||
target.RunScriptHookInterface<IScriptOnIncomingHit>(x =>
|
||||
target.RunScriptHook<IScriptOnIncomingHit>(x =>
|
||||
x.OnIncomingHit(executingMove, target, hitIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
executingMove.RunScriptHookInterface<IScriptOnOpponentFaints>(x =>
|
||||
executingMove.RunScriptHook<IScriptOnOpponentFaints>(x =>
|
||||
x.OnOpponentFaints(executingMove, target, hitIndex));
|
||||
}
|
||||
|
||||
@@ -283,9 +286,9 @@ public static class MoveTurnExecutor
|
||||
if (secondaryEffect != null)
|
||||
{
|
||||
var preventSecondary = false;
|
||||
executingMove.RunScriptHookInterface<IScriptPreventSecondaryEffect>(x =>
|
||||
executingMove.RunScriptHook<IScriptPreventSecondaryEffect>(x =>
|
||||
x.PreventSecondaryEffect(executingMove, target, hitIndex, ref preventSecondary));
|
||||
target.RunScriptHookInterface<IScriptPreventIncomingSecondaryEffect>(x =>
|
||||
target.RunScriptHook<IScriptPreventIncomingSecondaryEffect>(x =>
|
||||
x.PreventIncomingSecondaryEffect(executingMove, target, hitIndex,
|
||||
ref preventSecondary));
|
||||
|
||||
@@ -294,14 +297,14 @@ public static class MoveTurnExecutor
|
||||
var chance = secondaryEffect.Chance;
|
||||
if (chance < 0 || battle.Random.EffectChance(chance, executingMove, target, hitIndex))
|
||||
{
|
||||
executingMove.RunScriptHookInterface<IScriptOnSecondaryEffect>(x =>
|
||||
executingMove.RunScriptHook<IScriptOnSecondaryEffect>(x =>
|
||||
x.OnSecondaryEffect(executingMove, target, hitIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (target.IsFainted)
|
||||
{
|
||||
executingMove.RunScriptHookInterface<IScriptOnOpponentFaints>(x =>
|
||||
executingMove.RunScriptHook<IScriptOnOpponentFaints>(x =>
|
||||
x.OnOpponentFaints(executingMove, target, hitIndex));
|
||||
}
|
||||
}
|
||||
@@ -311,13 +314,13 @@ public static class MoveTurnExecutor
|
||||
|
||||
if (numberOfHits == 0)
|
||||
{
|
||||
target.RunScriptHookInterface<IScriptOnMoveMiss>(x => x.OnMoveMiss(executingMove, target));
|
||||
target.RunScriptHook<IScriptOnMoveMiss>(x => x.OnMoveMiss(executingMove, target));
|
||||
battle.EventHook.Invoke(new MoveMissEvent(executingMove));
|
||||
}
|
||||
|
||||
if (!executingMove.User.IsFainted)
|
||||
{
|
||||
executingMove.RunScriptHookInterface<IScriptOnAfterHits>(x => x.OnAfterHits(executingMove, target));
|
||||
executingMove.RunScriptHook<IScriptOnAfterHits>(x => x.OnAfterHits(executingMove, target));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public static class TurnRunner
|
||||
// they can then know this later on.)
|
||||
foreach (var choice in queue.GetChoices().WhereNotNull())
|
||||
{
|
||||
choice.RunScriptHookInterface<IScriptOnBeforeTurnStart>(script => script.OnBeforeTurnStart(choice));
|
||||
choice.RunScriptHook<IScriptOnBeforeTurnStart>(script => script.OnBeforeTurnStart(choice));
|
||||
}
|
||||
|
||||
// Now we can properly begin executing choices.
|
||||
@@ -60,15 +60,15 @@ public static class TurnRunner
|
||||
{
|
||||
scripts.Clear();
|
||||
pokemon.GetOwnScripts(scripts);
|
||||
scripts.RunScriptHookInterface<IScriptOnEndTurn>(x => x.OnEndTurn(pokemon, battle));
|
||||
scripts.RunScriptHook<IScriptOnEndTurn>(x => x.OnEndTurn(pokemon, battle));
|
||||
}
|
||||
scripts.Clear();
|
||||
side.GetOwnScripts(scripts);
|
||||
scripts.RunScriptHookInterface<IScriptOnEndTurn>(x => x.OnEndTurn(side, battle));
|
||||
scripts.RunScriptHook<IScriptOnEndTurn>(x => x.OnEndTurn(side, battle));
|
||||
}
|
||||
scripts.Clear();
|
||||
battle.GetOwnScripts(scripts);
|
||||
scripts.RunScriptHookInterface<IScriptOnEndTurn>(x => x.OnEndTurn(battle, battle));
|
||||
scripts.RunScriptHook<IScriptOnEndTurn>(x => x.OnEndTurn(battle, battle));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public static class TurnRunner
|
||||
/// </summary>
|
||||
public static void ExecuteChoice(IBattle battle, ITurnChoice choice)
|
||||
{
|
||||
choice.RunScriptHook(x => x.ChangeTurnChoice(ref choice));
|
||||
choice.RunScriptHook<IScriptChangeTurnChoice>(x => x.ChangeTurnChoice(ref choice));
|
||||
if (choice is IPassChoice)
|
||||
return;
|
||||
if (battle.HasEnded)
|
||||
@@ -90,7 +90,7 @@ public static class TurnRunner
|
||||
{
|
||||
case IMoveChoice moveChoice:
|
||||
MoveTurnExecutor.ExecuteMoveChoice(battle, moveChoice);
|
||||
moveChoice.RunScriptHook(script => script.OnAfterMoveChoice(moveChoice));
|
||||
moveChoice.RunScriptHook<IScriptOnAfterMoveChoice>(script => script.OnAfterMoveChoice(moveChoice));
|
||||
break;
|
||||
case ISwitchChoice switchChoice:
|
||||
ExecuteSwitchChoice(battle, switchChoice);
|
||||
@@ -111,7 +111,7 @@ public static class TurnRunner
|
||||
if (battleData == null)
|
||||
return;
|
||||
var preventSwitch = false;
|
||||
fleeChoice.RunScriptHookInterface<IScriptPreventSelfSwitch>(script =>
|
||||
fleeChoice.RunScriptHook<IScriptPreventSelfSwitch>(script =>
|
||||
script.PreventSelfSwitch(fleeChoice, ref preventSwitch));
|
||||
if (preventSwitch)
|
||||
return;
|
||||
@@ -121,7 +121,7 @@ public static class TurnRunner
|
||||
continue;
|
||||
foreach (var pokemon in side.Pokemon.WhereNotNull())
|
||||
{
|
||||
pokemon.RunScriptHookInterface<IScriptPreventOpponentSwitch>(script =>
|
||||
pokemon.RunScriptHook<IScriptPreventOpponentSwitch>(script =>
|
||||
script.PreventOpponentSwitch(fleeChoice, ref preventSwitch));
|
||||
if (preventSwitch)
|
||||
return;
|
||||
@@ -142,7 +142,7 @@ public static class TurnRunner
|
||||
return;
|
||||
|
||||
var preventFlee = false;
|
||||
fleeChoice.RunScriptHookInterface<IScriptPreventSelfRunAway>(script =>
|
||||
fleeChoice.RunScriptHook<IScriptPreventSelfRunAway>(script =>
|
||||
script.PreventSelfRunAway(fleeChoice, ref preventFlee));
|
||||
if (preventFlee)
|
||||
return;
|
||||
@@ -153,7 +153,7 @@ public static class TurnRunner
|
||||
continue;
|
||||
foreach (var pokemon in side.Pokemon.WhereNotNull())
|
||||
{
|
||||
pokemon.RunScriptHookInterface<IScriptPreventOpponentRunAway>(script =>
|
||||
pokemon.RunScriptHook<IScriptPreventOpponentRunAway>(script =>
|
||||
script.PreventOpponentRunAway(fleeChoice, ref preventFlee));
|
||||
if (preventFlee)
|
||||
return;
|
||||
|
||||
@@ -311,7 +311,7 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
}
|
||||
|
||||
ITurnChoice? forcedChoice = null;
|
||||
pokemon.RunScriptHookInterface<IScriptForceTurnSelection>(script =>
|
||||
pokemon.RunScriptHook<IScriptForceTurnSelection>(script =>
|
||||
script.ForceTurnSelection(this, battleData.SideIndex, battleData.Position, ref forcedChoice));
|
||||
choice = forcedChoice;
|
||||
return choice != null;
|
||||
@@ -336,7 +336,7 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
moveChoice.ChosenMove.MoveData.Target, moveChoice.User))
|
||||
return false;
|
||||
var preventMove = false;
|
||||
choice.RunScriptHookInterface<IScriptPreventMoveSelection>(script =>
|
||||
choice.RunScriptHook<IScriptPreventMoveSelection>(script =>
|
||||
script.PreventMoveSelection(moveChoice, ref preventMove));
|
||||
if (preventMove)
|
||||
return false;
|
||||
@@ -394,13 +394,13 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
if (choice is IMoveChoice moveChoice)
|
||||
{
|
||||
var priority = moveChoice.ChosenMove.MoveData.Priority;
|
||||
choice.RunScriptHookInterface<IScriptChangePriority>(script =>
|
||||
choice.RunScriptHook<IScriptChangePriority>(script =>
|
||||
script.ChangePriority(moveChoice, ref priority));
|
||||
moveChoice.Priority = priority;
|
||||
}
|
||||
|
||||
var speed = choice.User.BoostedStats.Speed;
|
||||
choice.RunScriptHookInterface<IScriptChangeSpeed>(script => script.ChangeSpeed(choice, ref speed));
|
||||
choice.RunScriptHook<IScriptChangeSpeed>(script => script.ChangeSpeed(choice, ref speed));
|
||||
choice.Speed = speed;
|
||||
|
||||
choice.RandomValue = (uint)Random.GetInt();
|
||||
@@ -434,7 +434,8 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
public bool SetWeather(StringKey? weatherName, int duration, EventBatchId batchId = default)
|
||||
{
|
||||
var preventWeatherChange = false;
|
||||
this.RunScriptHook(x => x.PreventWeatherChange(weatherName, ref preventWeatherChange));
|
||||
this.RunScriptHook<IScriptPreventWeatherChange>(x =>
|
||||
x.PreventWeatherChange(weatherName, ref preventWeatherChange));
|
||||
if (preventWeatherChange)
|
||||
return false;
|
||||
|
||||
@@ -446,7 +447,8 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
// Extend duration of existing weather
|
||||
if (_weatherScript.Script is ILimitedTurnsScript existingWeatherScript)
|
||||
{
|
||||
this.RunScriptHook(x => x.ChangeWeatherDuration(weatherName.Value, ref duration));
|
||||
this.RunScriptHook<IScriptChangeWeatherDuration>(x =>
|
||||
x.ChangeWeatherDuration(weatherName.Value, ref duration));
|
||||
if (duration < existingWeatherScript.TurnsRemaining)
|
||||
return true;
|
||||
existingWeatherScript.SetTurns(duration);
|
||||
@@ -458,7 +460,8 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
|
||||
if (script is ILimitedTurnsScript weatherScript)
|
||||
{
|
||||
this.RunScriptHook(x => x.ChangeWeatherDuration(weatherName.Value, ref duration));
|
||||
this.RunScriptHook<IScriptChangeWeatherDuration>(x =>
|
||||
x.ChangeWeatherDuration(weatherName.Value, ref duration));
|
||||
weatherScript.SetTurns(duration);
|
||||
}
|
||||
|
||||
@@ -474,7 +477,7 @@ public class BattleImpl : ScriptSource, IBattle
|
||||
BatchId = batchId,
|
||||
});
|
||||
Sides.SelectMany(x => x.Pokemon).WhereNotNull()
|
||||
.RunScriptHook(x => x.OnWeatherChange(this, weatherName, oldWeatherName));
|
||||
.RunScriptHook<IScriptOnWeatherChange>(x => x.OnWeatherChange(this, weatherName, oldWeatherName));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class BattleChoiceQueue : IDeepCloneable
|
||||
continue;
|
||||
// Ensure that the speed is up to date
|
||||
var speed = choice.User.BoostedStats.Speed;
|
||||
choice.User.RunScriptHookInterface<IScriptChangeSpeed>(script => script.ChangeSpeed(choice, ref speed));
|
||||
choice.User.RunScriptHook<IScriptChangeSpeed>(script => script.ChangeSpeed(choice, ref speed));
|
||||
choice.Speed = speed;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ public class BattleRandomImpl : RandomImpl, IBattleRandom
|
||||
/// <inheritdoc />
|
||||
public bool EffectChance(float chance, IExecutingMove executingMove, IPokemon target, byte hitNumber)
|
||||
{
|
||||
executingMove.RunScriptHookInterface<IScriptChangeEffectChance>(script =>
|
||||
executingMove.RunScriptHook<IScriptChangeEffectChance>(script =>
|
||||
script.ChangeEffectChance(executingMove, target, hitNumber, ref chance));
|
||||
target.RunScriptHookInterface<IScriptChangeIncomingEffectChance>(script =>
|
||||
target.RunScriptHook<IScriptChangeIncomingEffectChance>(script =>
|
||||
script.ChangeIncomingEffectChance(executingMove, target, hitNumber, ref chance));
|
||||
if (chance > 100.0)
|
||||
return true;
|
||||
|
||||
@@ -248,7 +248,7 @@ public class BattleSideImpl : ScriptSource, IBattleSide
|
||||
var pokemon = _pokemon[index];
|
||||
if (pokemon is not null)
|
||||
{
|
||||
pokemon.RunScriptHook(script => script.OnRemove());
|
||||
pokemon.RunScriptHook<IScriptOnRemove>(script => script.OnRemove());
|
||||
pokemon.SetOnBattlefield(false);
|
||||
}
|
||||
|
||||
@@ -261,8 +261,8 @@ public class BattleSideImpl : ScriptSource, IBattleSide
|
||||
var oldPokemon = _pokemon[position];
|
||||
if (oldPokemon is not null)
|
||||
{
|
||||
oldPokemon.RunScriptHookInterface<IScriptOnSwitchOut>(script => script.OnSwitchOut(oldPokemon, position));
|
||||
oldPokemon.RunScriptHook(script => script.OnRemove());
|
||||
oldPokemon.RunScriptHook<IScriptOnSwitchOut>(script => script.OnSwitchOut(oldPokemon, position));
|
||||
oldPokemon.RunScriptHook<IScriptOnRemove>(script => script.OnRemove());
|
||||
oldPokemon.SetOnBattlefield(false);
|
||||
}
|
||||
_pokemon[position] = pokemon;
|
||||
@@ -272,7 +272,7 @@ public class BattleSideImpl : ScriptSource, IBattleSide
|
||||
pokemon.SetOnBattlefield(true);
|
||||
pokemon.SetBattleSidePosition(position);
|
||||
Battle.EventHook.Invoke(new SwitchEvent(Index, position, pokemon));
|
||||
pokemon.RunScriptHookInterface<IScriptOnSwitchIn>(script => script.OnSwitchIn(pokemon, position));
|
||||
pokemon.RunScriptHook<IScriptOnSwitchIn>(script => script.OnSwitchIn(pokemon, position));
|
||||
|
||||
foreach (var side in Battle.Sides)
|
||||
{
|
||||
@@ -286,11 +286,10 @@ public class BattleSideImpl : ScriptSource, IBattleSide
|
||||
|
||||
scripts.Clear();
|
||||
opponent.GetOwnScripts(scripts);
|
||||
opponent.RunScriptHookInterface<IScriptOnOpponentSwitchIn>(script =>
|
||||
opponent.RunScriptHook<IScriptOnOpponentSwitchIn>(script =>
|
||||
script.OnOpponentSwitchIn(pokemon, position));
|
||||
}
|
||||
side.RunScriptHookInterface<IScriptOnOpponentSwitchIn>(script =>
|
||||
script.OnOpponentSwitchIn(pokemon, position));
|
||||
side.RunScriptHook<IScriptOnOpponentSwitchIn>(script => script.OnOpponentSwitchIn(pokemon, position));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -684,7 +684,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
var weight = Form.Weight;
|
||||
if (BattleData is not null)
|
||||
// ReSharper disable once AccessToModifiedClosure
|
||||
this.RunScriptHook(script => script.ModifyWeight(ref weight));
|
||||
this.RunScriptHook<IScriptModifyWeight>(script => script.ModifyWeight(ref weight));
|
||||
if (weight < 0.1f)
|
||||
weight = 0.1f;
|
||||
return weight;
|
||||
@@ -793,7 +793,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
{
|
||||
var previous = HeldItem;
|
||||
HeldItem = item;
|
||||
this.RunScriptHook(x => x.OnAfterHeldItemChange(this, previous, item));
|
||||
this.RunScriptHook<IScriptOnAfterHeldItemChange>(x => x.OnAfterHeldItemChange(this, previous, item));
|
||||
return previous;
|
||||
}
|
||||
|
||||
@@ -809,7 +809,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
}
|
||||
var previous = HeldItem;
|
||||
HeldItem = null;
|
||||
this.RunScriptHook(x => x.OnAfterHeldItemChange(this, previous, null));
|
||||
this.RunScriptHook<IScriptOnAfterHeldItemChange>(x => x.OnAfterHeldItemChange(this, previous, null));
|
||||
return previous;
|
||||
}
|
||||
|
||||
@@ -833,7 +833,8 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
return false;
|
||||
}
|
||||
var prevent = false;
|
||||
this.RunScriptHook(script => script.PreventHeldItemSteal(this, HeldItem, ref prevent));
|
||||
this.RunScriptHook<IScriptPreventHeldItemSteal>(script =>
|
||||
script.PreventHeldItemSteal(this, HeldItem, ref prevent));
|
||||
if (prevent)
|
||||
{
|
||||
item = null;
|
||||
@@ -861,7 +862,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
if (BattleData != null)
|
||||
{
|
||||
var prevented = false;
|
||||
this.RunScriptHookInterface<IScriptPreventHeldItemConsume>(script =>
|
||||
this.RunScriptHook<IScriptPreventHeldItemConsume>(script =>
|
||||
script.PreventHeldItemConsume(this, HeldItem, ref prevented));
|
||||
if (prevented)
|
||||
return false;
|
||||
@@ -880,7 +881,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
{
|
||||
// TODO: actually consume the item
|
||||
|
||||
this.RunScriptHookInterface<IScriptOnAfterItemConsume>(x => x.OnAfterItemConsume(this, item));
|
||||
this.RunScriptHook<IScriptOnAfterItemConsume>(x => x.OnAfterItemConsume(this, item));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -890,11 +891,11 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
if (!force)
|
||||
{
|
||||
var prevented = false;
|
||||
this.RunScriptHookInterface<IScriptPreventStatBoostChange>(script =>
|
||||
this.RunScriptHook<IScriptPreventStatBoostChange>(script =>
|
||||
script.PreventStatBoostChange(this, stat, change, selfInflicted, ref prevented));
|
||||
if (prevented)
|
||||
return false;
|
||||
this.RunScriptHookInterface<IScriptChangeStatBoostChange>(script =>
|
||||
this.RunScriptHook<IScriptChangeStatBoostChange>(script =>
|
||||
script.ChangeStatBoostChange(this, stat, selfInflicted, ref change));
|
||||
if (change == 0)
|
||||
return false;
|
||||
@@ -919,7 +920,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
}
|
||||
|
||||
RecalculateBoostedStats();
|
||||
this.RunScriptHookInterface<IScriptOnAfterStatBoostChange>(script =>
|
||||
this.RunScriptHook<IScriptOnAfterStatBoostChange>(script =>
|
||||
script.OnAfterStatBoostChange(this, stat, selfInflicted, change));
|
||||
return true;
|
||||
}
|
||||
@@ -1075,7 +1076,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
if (BattleData is not null && !forceDamage)
|
||||
{
|
||||
var dmg = damage;
|
||||
this.RunScriptHookInterface<IScriptChangeIncomingDamage>(script =>
|
||||
this.RunScriptHook<IScriptChangeIncomingDamage>(script =>
|
||||
script.ChangeIncomingDamage(this, source, ref dmg));
|
||||
damage = dmg;
|
||||
}
|
||||
@@ -1096,8 +1097,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
BatchId = batchId,
|
||||
});
|
||||
// And allow scripts to execute.
|
||||
this.RunScriptHookInterface<IScriptOnDamage>(script =>
|
||||
script.OnDamage(this, source, CurrentHealth, newHealth));
|
||||
this.RunScriptHook<IScriptOnDamage>(script => script.OnDamage(this, source, CurrentHealth, newHealth));
|
||||
}
|
||||
|
||||
CurrentHealth = newHealth;
|
||||
@@ -1126,14 +1126,14 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
BattleData.Battle.EventHook.Invoke(new FaintEvent(this));
|
||||
|
||||
// Allow scripts to trigger based on the faint.
|
||||
this.RunScriptHookInterface<IScriptOnFaint>(script => script.OnFaint(this, source));
|
||||
this.RunScriptHook<IScriptOnFaint>(script => script.OnFaint(this, source));
|
||||
foreach (var ally in BattleData.BattleSide.Pokemon.WhereNotNull().Where(x => x != this))
|
||||
{
|
||||
ally.RunScriptHookInterface<IScriptOnAllyFaint>(script => script.OnAllyFaint(ally, this));
|
||||
ally.RunScriptHook<IScriptOnAllyFaint>(script => script.OnAllyFaint(ally, this));
|
||||
}
|
||||
|
||||
// Make sure the OnRemove script is run.
|
||||
this.RunScriptHook(script => script.OnRemove());
|
||||
this.RunScriptHook<IScriptOnRemove>(script => script.OnRemove());
|
||||
|
||||
// Mark the position as unfillable if it can't be filled by any party.
|
||||
if (!BattleData.Battle.CanSlotBeFilled(BattleData.SideIndex, BattleData.Position))
|
||||
@@ -1162,7 +1162,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
if (!forceHeal)
|
||||
{
|
||||
var prevented = false;
|
||||
this.RunScriptHook(x => x.PreventHeal(this, heal, allowRevive, ref prevented));
|
||||
this.RunScriptHook<IScriptPreventHeal>(x => x.PreventHeal(this, heal, allowRevive, ref prevented));
|
||||
if (prevented)
|
||||
return false;
|
||||
}
|
||||
@@ -1226,7 +1226,8 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
var selfInflicted = originPokemon == this;
|
||||
|
||||
var preventStatus = false;
|
||||
this.RunScriptHook(script => script.PreventStatusChange(this, status, selfInflicted, ref preventStatus));
|
||||
this.RunScriptHook<IScriptPreventStatusChange>(script =>
|
||||
script.PreventStatusChange(this, status, selfInflicted, ref preventStatus));
|
||||
if (preventStatus)
|
||||
return false;
|
||||
|
||||
@@ -1236,7 +1237,8 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
{
|
||||
BatchId = batchId,
|
||||
});
|
||||
this.RunScriptHook(script => script.OnAfterStatusChange(this, status, originPokemon));
|
||||
this.RunScriptHook<IScriptOnAfterStatusChange>(script =>
|
||||
script.OnAfterStatusChange(this, status, originPokemon));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1375,7 +1377,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
get
|
||||
{
|
||||
var isFloating = Types.Any(x => x.Name == "flying");
|
||||
this.RunScriptHook(x => x.IsFloating(this, ref isFloating));
|
||||
this.RunScriptHook<IScriptIsFloating>(x => x.IsFloating(this, ref isFloating));
|
||||
return isFloating;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace PkmnLib.Dynamic.ScriptHandling;
|
||||
/// developer might require.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{Category} - {Name}")]
|
||||
public abstract class Script : IDeepCloneable
|
||||
public abstract class Script : IDeepCloneable, IScriptOnRemove
|
||||
{
|
||||
internal event Action<Script>? OnRemoveEvent;
|
||||
|
||||
@@ -52,239 +52,17 @@ public abstract class Script : IDeepCloneable
|
||||
public virtual void OnAddedToParent(IScriptSource source)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface is used to allow scripts to run when they are removed from their owner.
|
||||
/// </summary>
|
||||
public interface IScriptOnRemove
|
||||
{
|
||||
/// <summary>
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||
/// and allows for changing this amount of experience.
|
||||
/// This function is ran when this script stops being in effect, and is removed from its owner.
|
||||
/// </summary>
|
||||
public virtual void ChangeExperienceGained(IPokemon faintedPokemon, IPokemon winningPokemon, ref uint amount)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||
/// and allows for making the experience be shared across multiple Pokemon.
|
||||
/// Amount is the modifier for how much experience is shared, with 1 being the default amount.
|
||||
/// </summary>
|
||||
public virtual void ShareExperience(IPokemon faintedPokemon, IPokemon winningPokemon, ref bool share,
|
||||
ref float amount)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is triggered on a battle and its parents when something attempts to change the
|
||||
/// weather, and allows for blocking the weather change.
|
||||
/// </summary>
|
||||
public virtual void BlockWeatherChange(IBattle battle, ref bool block)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when a Pokeball is thrown at a Pokemon, and allows modifying the catch
|
||||
/// rate of this attempt. Pokeball modifier effects should be implemented here, as well as for
|
||||
/// example status effects that change capture rates.
|
||||
/// </summary>
|
||||
public virtual void ChangeCatchRateBonus(IPokemon pokemon, IItem pokeball, ref byte modifier)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom triggers for scripts. This allows scripts to run custom events that are not part of the
|
||||
/// standard battle flow.
|
||||
/// </summary>
|
||||
/// <param name="eventName">
|
||||
/// The name of the event that is triggered. This should be unique for each different event. Overriding scripts
|
||||
/// should validate the event name is one they should handle.
|
||||
/// </param>
|
||||
/// <param name="args">
|
||||
/// The parameters that are passed to the event.
|
||||
/// </param>
|
||||
public virtual void CustomTrigger(StringKey eventName, ICustomTriggerArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to change the accuracy of a move used. The value for accuracy is in percentage.
|
||||
/// A custom case goes when 255 is returned, in which case the entire accuracy check is skipped, and the move
|
||||
/// will always hit.
|
||||
/// </summary>
|
||||
/// <param name="executingMove"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="hitIndex"></param>
|
||||
/// <param name="modifiedAccuracy"></param>
|
||||
public virtual void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex,
|
||||
ref int modifiedAccuracy)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to change the accuracy of a move that is incoming. The value for accuracy is in percentage.
|
||||
/// A custom case goes when 255 is returned, in which case the entire accuracy check is skipped, and the move
|
||||
/// will always hit.
|
||||
/// </summary>
|
||||
public virtual void ChangeIncomingAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex,
|
||||
ref int modifiedAccuracy)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to change the weather duration of a weather effect.
|
||||
/// </summary>
|
||||
public virtual void ChangeWeatherDuration(StringKey weatherName, ref int duration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a Pokemon from being healed.
|
||||
/// </summary>
|
||||
public virtual void PreventHeal(IPokemon pokemon, uint heal, bool allowRevive, ref bool prevented)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to change the types a target has. Multiple types can be set, and will be used
|
||||
/// for the effectiveness calculation.
|
||||
/// </summary>
|
||||
public virtual void ChangeTypesForMove(IExecutingMove executingMove, IPokemon target, byte hitIndex,
|
||||
IList<TypeIdentifier> types)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to change the types a Pokemon has for a move that's incoming. Multiple types can
|
||||
/// be set, and will be used for the effectiveness calculation.
|
||||
/// </summary>
|
||||
public virtual void ChangeTypesForIncomingMove(IExecutingMove executingMove, IPokemon target, byte hitIndex,
|
||||
IList<TypeIdentifier> types)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to change the handling of the move category. This is used for moves that
|
||||
/// are sometimes a status move, and sometimes a damaging move, such as pollen puff.
|
||||
/// </summary>
|
||||
public virtual void ChangeCategory(IExecutingMove move, IPokemon target, byte hitIndex, ref MoveCategory category)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers first when we're about to hit a target.
|
||||
/// </summary>
|
||||
public virtual void OnBeforeHit(IExecutingMove move, IPokemon target, byte hitIndex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a Pokemon from being affected by a status condition.
|
||||
/// </summary>
|
||||
public virtual void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted,
|
||||
ref bool preventStatus)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function triggers after a status condition has been applied to a Pokemon.
|
||||
/// </summary>
|
||||
public virtual void OnAfterStatusChange(IPokemon pokemon, StringKey status, IPokemon? originPokemon)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a Pokémon from being affected by a volatile status condition.
|
||||
/// </summary>
|
||||
public virtual void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to make the Pokémon it is attached to float. This is used for moves
|
||||
/// such as levitate, and allows for moves such as earthquake to not hit the Pokémon.
|
||||
/// </summary>
|
||||
/// <param name="pokemon"></param>
|
||||
/// <param name="isFloating"></param>
|
||||
public virtual void IsFloating(IPokemon pokemon, ref bool isFloating)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent the weather from changing. This is used for abilities such as
|
||||
/// Delta Stream, which prevent the weather from changing to anything other than strong winds.
|
||||
/// </summary>
|
||||
public virtual void PreventWeatherChange(StringKey? weatherName, ref bool preventWeatherChange)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function triggers when the weather changes.
|
||||
/// </summary>
|
||||
public virtual void OnWeatherChange(IBattle battle, StringKey? weatherName, StringKey? oldWeatherName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the weight of a Pokemon.
|
||||
/// </summary>
|
||||
/// <param name="weight">The weight in kilograms</param>
|
||||
public virtual void ModifyWeight(ref float weight)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modifies whether a move is a contact move or not. This is used for abilities such as Long Reach.
|
||||
/// </summary>
|
||||
public virtual void ModifyIsContact(IExecutingMove executingMove, IPokemon target, byte hitIndex,
|
||||
ref bool isContact)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a held item from being stolen by an effect such as Thief or Covet.
|
||||
/// </summary>
|
||||
public virtual void PreventHeldItemSteal(IPokemon pokemon, IItem heldItem, ref bool prevent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to run after a held item has changed.
|
||||
/// </summary>
|
||||
public virtual void OnAfterHeldItemChange(IPokemon pokemon, IItem? previous, IItem? item)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to modify the PP used by a move.
|
||||
/// </summary>
|
||||
public virtual void ModifyPPUsed(IExecutingMove executingMove, ref byte ppUsed)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to modify the PP used by an incoming move. This is used for abilities such as Pressure.
|
||||
/// </summary>
|
||||
public virtual void ModifyPPUsedForIncomingMove(IExecutingMove executingMove, ref byte ppUsed)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function triggers just before a move choice is executed.
|
||||
/// </summary>
|
||||
public virtual void OnBeforeMoveChoice(IMoveChoice moveChoice)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function triggers after a move choice has been executed in its entirety.
|
||||
/// </summary>
|
||||
public virtual void OnAfterMoveChoice(IMoveChoice moveChoice)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows a script to change the turn choice that is made by a Pokemon.
|
||||
/// </summary>
|
||||
public virtual void ChangeTurnChoice(ref ITurnChoice choice)
|
||||
{
|
||||
}
|
||||
void OnRemove();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1102,4 +880,328 @@ public interface IScriptChangeIncomingDamage
|
||||
/// This function allows a script to change any kind of damage that is incoming.
|
||||
/// </summary>
|
||||
void ChangeIncomingDamage(IPokemon pokemon, DamageSource source, ref uint damage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the weather duration of a weather effect.
|
||||
/// </summary>
|
||||
public interface IScriptChangeWeatherDuration
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to change the weather duration of a weather effect.
|
||||
/// </summary>
|
||||
void ChangeWeatherDuration(StringKey weatherName, ref int duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to prevent a Pokemon from being healed.
|
||||
/// </summary>
|
||||
public interface IScriptPreventHeal
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a Pokemon from being healed.
|
||||
/// </summary>
|
||||
void PreventHeal(IPokemon pokemon, uint heal, bool allowRevive, ref bool prevented);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the types a target has for effectiveness calculation.
|
||||
/// </summary>
|
||||
public interface IScriptChangeTypesForMove
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to change the types a target has. Multiple types can be set, and will be used
|
||||
/// for the effectiveness calculation.
|
||||
/// </summary>
|
||||
void ChangeTypesForMove(IExecutingMove executingMove, IPokemon target, byte hitIndex, IList<TypeIdentifier> types);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the types a Pokemon has for incoming moves.
|
||||
/// </summary>
|
||||
public interface IScriptChangeTypesForIncomingMove
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to change the types a Pokemon has for a move that's incoming. Multiple types can
|
||||
/// be set, and will be used for the effectiveness calculation.
|
||||
/// </summary>
|
||||
void ChangeTypesForIncomingMove(IExecutingMove executingMove, IPokemon target, byte hitIndex,
|
||||
IList<TypeIdentifier> types);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the handling of the move category.
|
||||
/// </summary>
|
||||
public interface IScriptChangeCategory
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to change the handling of the move category. This is used for moves that
|
||||
/// are sometimes a status move, and sometimes a damaging move, such as pollen puff.
|
||||
/// </summary>
|
||||
void ChangeCategory(IExecutingMove move, IPokemon target, byte hitIndex, ref MoveCategory category);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to trigger when about to hit a target.
|
||||
/// </summary>
|
||||
public interface IScriptOnBeforeHit
|
||||
{
|
||||
/// <summary>
|
||||
/// Triggers first when we're about to hit a target.
|
||||
/// </summary>
|
||||
void OnBeforeHit(IExecutingMove move, IPokemon target, byte hitIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to prevent a Pokemon from being affected by a status condition.
|
||||
/// </summary>
|
||||
public interface IScriptPreventStatusChange
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a Pokemon from being affected by a status condition.
|
||||
/// </summary>
|
||||
void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to trigger after a status condition has been applied.
|
||||
/// </summary>
|
||||
public interface IScriptOnAfterStatusChange
|
||||
{
|
||||
/// <summary>
|
||||
/// This function triggers after a status condition has been applied to a Pokemon.
|
||||
/// </summary>
|
||||
void OnAfterStatusChange(IPokemon pokemon, StringKey status, IPokemon? originPokemon);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to prevent a Pokemon from being affected by a volatile status condition.
|
||||
/// </summary>
|
||||
public interface IScriptPreventVolatileAdd
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a Pokémon from being affected by a volatile status condition.
|
||||
/// </summary>
|
||||
void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to make the Pokemon float.
|
||||
/// </summary>
|
||||
public interface IScriptIsFloating
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to make the Pokémon it is attached to float. This is used for moves
|
||||
/// such as levitate, and allows for moves such as earthquake to not hit the Pokémon.
|
||||
/// </summary>
|
||||
void IsFloating(IPokemon pokemon, ref bool isFloating);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to prevent weather from changing.
|
||||
/// </summary>
|
||||
public interface IScriptPreventWeatherChange
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent the weather from changing. This is used for abilities such as
|
||||
/// Delta Stream, which prevent the weather from changing to anything other than strong winds.
|
||||
/// </summary>
|
||||
void PreventWeatherChange(StringKey? weatherName, ref bool preventWeatherChange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to trigger when the weather changes.
|
||||
/// </summary>
|
||||
public interface IScriptOnWeatherChange
|
||||
{
|
||||
/// <summary>
|
||||
/// This function triggers when the weather changes.
|
||||
/// </summary>
|
||||
void OnWeatherChange(IBattle battle, StringKey? weatherName, StringKey? oldWeatherName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to modify the weight of a Pokemon.
|
||||
/// </summary>
|
||||
public interface IScriptModifyWeight
|
||||
{
|
||||
/// <summary>
|
||||
/// Modifies the weight of a Pokemon.
|
||||
/// </summary>
|
||||
void ModifyWeight(ref float weight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to modify whether a move makes contact.
|
||||
/// </summary>
|
||||
public interface IScriptModifyIsContact
|
||||
{
|
||||
/// <summary>
|
||||
/// Modifies whether a move is a contact move or not. This is used for abilities such as Long Reach.
|
||||
/// </summary>
|
||||
void ModifyIsContact(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool isContact);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to prevent held item theft.
|
||||
/// </summary>
|
||||
public interface IScriptPreventHeldItemSteal
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to prevent a held item from being stolen by an effect such as Thief or Covet.
|
||||
/// </summary>
|
||||
void PreventHeldItemSteal(IPokemon pokemon, IItem heldItem, ref bool prevent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to trigger after held item changes.
|
||||
/// </summary>
|
||||
public interface IScriptOnAfterHeldItemChange
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to run after a held item has changed.
|
||||
/// </summary>
|
||||
void OnAfterHeldItemChange(IPokemon pokemon, IItem? previous, IItem? item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to modify the PP used by a move.
|
||||
/// </summary>
|
||||
public interface IScriptModifyPPUsed
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to modify the PP used by a move.
|
||||
/// </summary>
|
||||
void ModifyPPUsed(IExecutingMove executingMove, ref byte ppUsed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to modify the PP used by an incoming move.
|
||||
/// </summary>
|
||||
public interface IScriptModifyPPUsedForIncomingMove
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to modify the PP used by an incoming move. This is used for abilities such as Pressure.
|
||||
/// </summary>
|
||||
void ModifyPPUsedForIncomingMove(IExecutingMove executingMove, ref byte ppUsed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to trigger just before a move choice is executed.
|
||||
/// </summary>
|
||||
public interface IScriptOnBeforeMoveChoice
|
||||
{
|
||||
/// <summary>
|
||||
/// This function triggers just before a move choice is executed.
|
||||
/// </summary>
|
||||
void OnBeforeMoveChoice(IMoveChoice moveChoice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to trigger after a move choice has been executed.
|
||||
/// </summary>
|
||||
public interface IScriptOnAfterMoveChoice
|
||||
{
|
||||
/// <summary>
|
||||
/// This function triggers after a move choice has been executed in its entirety.
|
||||
/// </summary>
|
||||
void OnAfterMoveChoice(IMoveChoice moveChoice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the turn choice that is made by a Pokemon.
|
||||
/// </summary>
|
||||
public interface IScriptChangeTurnChoice
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to change the turn choice that is made by a Pokemon.
|
||||
/// </summary>
|
||||
void ChangeTurnChoice(ref ITurnChoice choice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the experience gained when a Pokemon faints.
|
||||
/// </summary>
|
||||
public interface IScriptChangeExperienceGained
|
||||
{
|
||||
/// <summary>
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||
/// and allows for changing this amount of experience.
|
||||
/// </summary>
|
||||
void ChangeExperienceGained(IPokemon faintedPokemon, IPokemon winningPokemon, ref uint amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to share experience across multiple Pokemon.
|
||||
/// </summary>
|
||||
public interface IScriptShareExperience
|
||||
{
|
||||
/// <summary>
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||
/// and allows for making the experience be shared across multiple Pokemon.
|
||||
/// Amount is the modifier for how much experience is shared, with 1 being the default amount.
|
||||
/// </summary>
|
||||
void ShareExperience(IPokemon faintedPokemon, IPokemon winningPokemon, ref bool share, ref float amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to block weather changes.
|
||||
/// </summary>
|
||||
public interface IScriptBlockWeatherChange
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to block weather changes.
|
||||
/// </summary>
|
||||
void BlockWeatherChange(IBattle battle, ref bool block);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the catch rate bonus when a Pokeball is thrown.
|
||||
/// </summary>
|
||||
public interface IScriptChangeCatchRateBonus
|
||||
{
|
||||
/// <summary>
|
||||
/// This function is called when a Pokeball is thrown at a Pokemon, and allows modifying the catch
|
||||
/// rate of this attempt. Pokeball modifier effects should be implemented here, as well as for
|
||||
/// example status effects that change capture rates.
|
||||
/// </summary>
|
||||
void ChangeCatchRateBonus(IPokemon pokemon, IItem pokeball, ref byte modifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to handle custom trigger events.
|
||||
/// </summary>
|
||||
public interface IScriptCustomTrigger
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom triggers for scripts. This allows scripts to run custom events that are not part of the
|
||||
/// standard battle flow.
|
||||
/// </summary>
|
||||
void CustomTrigger(StringKey eventName, ICustomTriggerArgs args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the accuracy of a move.
|
||||
/// </summary>
|
||||
public interface IScriptChangeAccuracy
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to change the accuracy of a move used. The value for accuracy is in percentage.
|
||||
/// A custom case goes when 255 is returned, in which case the entire accuracy check is skipped, and the move
|
||||
/// will always hit.
|
||||
/// </summary>
|
||||
void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref int modifiedAccuracy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface allows scripts to change the accuracy of an incoming move.
|
||||
/// </summary>
|
||||
public interface IScriptChangeIncomingAccuracy
|
||||
{
|
||||
/// <summary>
|
||||
/// This function allows a script to change the accuracy of a move that is incoming. The value for accuracy is in percentage.
|
||||
/// A custom case goes when 255 is returned, in which case the entire accuracy check is skipped, and the move
|
||||
/// will always hit.
|
||||
/// </summary>
|
||||
void ChangeIncomingAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref int modifiedAccuracy);
|
||||
}
|
||||
@@ -13,33 +13,7 @@ public static class ScriptExecution
|
||||
/// <summary>
|
||||
/// Executes a hook on all scripts in a source.
|
||||
/// </summary>
|
||||
public static void RunScriptHook(this IScriptSource source, Action<Script> hook)
|
||||
{
|
||||
var iterator = source.GetScripts();
|
||||
List<ScriptCategory>? suppressedCategories = null;
|
||||
foreach (var container in iterator)
|
||||
{
|
||||
if (container.IsEmpty)
|
||||
continue;
|
||||
var script = container.Script;
|
||||
if (script is IScriptOnBeforeAnyHookInvoked onBeforeAnyHookInvoked)
|
||||
onBeforeAnyHookInvoked.OnBeforeAnyHookInvoked(ref suppressedCategories);
|
||||
}
|
||||
foreach (var container in iterator)
|
||||
{
|
||||
if (container.IsEmpty)
|
||||
continue;
|
||||
var script = container.Script;
|
||||
if (suppressedCategories != null && suppressedCategories.Contains(script.Category))
|
||||
continue;
|
||||
hook(script);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a hook on all scripts in a source.
|
||||
/// </summary>
|
||||
public static void RunScriptHookInterface<TScriptHook>(this IScriptSource source, Action<TScriptHook> hook)
|
||||
public static void RunScriptHook<TScriptHook>(this IScriptSource source, Action<TScriptHook> hook)
|
||||
{
|
||||
var iterator = source.GetScripts();
|
||||
List<ScriptCategory>? suppressedCategories = null;
|
||||
@@ -68,35 +42,7 @@ public static class ScriptExecution
|
||||
/// Executes a hook on all scripts in a source.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void RunScriptHook(this IEnumerable<IScriptSource> sources, Action<Script> hook)
|
||||
{
|
||||
var iterator = sources.Distinct().SelectMany(x => x.GetScripts()).ToArray();
|
||||
List<ScriptCategory>? suppressedCategories = null;
|
||||
foreach (var container in iterator)
|
||||
{
|
||||
if (container.IsEmpty)
|
||||
continue;
|
||||
var script = container.Script;
|
||||
if (script is IScriptOnBeforeAnyHookInvoked onBeforeAnyHookInvoked)
|
||||
onBeforeAnyHookInvoked.OnBeforeAnyHookInvoked(ref suppressedCategories);
|
||||
}
|
||||
foreach (var container in iterator)
|
||||
{
|
||||
if (container.IsEmpty)
|
||||
continue;
|
||||
var script = container.Script;
|
||||
if (suppressedCategories != null && suppressedCategories.Contains(script.Category))
|
||||
continue;
|
||||
hook(script);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a hook on all scripts in a source.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void RunScriptHookInterface<TScriptHook>(this IEnumerable<IScriptSource> sources,
|
||||
Action<TScriptHook> hook)
|
||||
public static void RunScriptHook<TScriptHook>(this IEnumerable<IScriptSource> sources, Action<TScriptHook> hook)
|
||||
{
|
||||
var iterator = sources.Distinct().SelectMany(x => x.GetScripts()).ToArray();
|
||||
List<ScriptCategory>? suppressedCategories = null;
|
||||
@@ -125,33 +71,7 @@ public static class ScriptExecution
|
||||
/// Executes a hook on all scripts in a list of sources. Note that this does not walk through the parents of the
|
||||
/// sources, but only the sources themselves.
|
||||
/// </summary>
|
||||
public static void RunScriptHook(this IReadOnlyList<IEnumerable<ScriptContainer>> source, Action<Script> hook)
|
||||
{
|
||||
List<ScriptCategory>? suppressedCategories = null;
|
||||
foreach (var container in source.SelectMany(x => x))
|
||||
{
|
||||
if (container.IsEmpty)
|
||||
continue;
|
||||
var script = container.Script;
|
||||
if (script is IScriptOnBeforeAnyHookInvoked onBeforeAnyHookInvoked)
|
||||
onBeforeAnyHookInvoked.OnBeforeAnyHookInvoked(ref suppressedCategories);
|
||||
}
|
||||
foreach (var container in source.SelectMany(x => x))
|
||||
{
|
||||
if (container.IsEmpty)
|
||||
continue;
|
||||
var script = container.Script;
|
||||
if (suppressedCategories != null && suppressedCategories.Contains(script.Category))
|
||||
continue;
|
||||
hook(script);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a hook on all scripts in a list of sources. Note that this does not walk through the parents of the
|
||||
/// sources, but only the sources themselves.
|
||||
/// </summary>
|
||||
public static void RunScriptHookInterface<TScriptHook>(this IReadOnlyList<IEnumerable<ScriptContainer>> source,
|
||||
public static void RunScriptHook<TScriptHook>(this IReadOnlyList<IEnumerable<ScriptContainer>> source,
|
||||
Action<TScriptHook> hook)
|
||||
{
|
||||
List<ScriptCategory>? suppressedCategories = null;
|
||||
|
||||
@@ -108,7 +108,8 @@ public class ScriptSet : IScriptSet
|
||||
if (!forceAdd)
|
||||
{
|
||||
var preventVolatileAdd = false;
|
||||
_source.RunScriptHook(x => x.PreventVolatileAdd(_source, script, ref preventVolatileAdd));
|
||||
_source.RunScriptHook<IScriptPreventVolatileAdd>(x =>
|
||||
x.PreventVolatileAdd(_source, script, ref preventVolatileAdd));
|
||||
if (preventVolatileAdd)
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user