diff --git a/PkmnLib.Dynamic/Models/Battle.cs b/PkmnLib.Dynamic/Models/Battle.cs index 23ea685..da563a9 100644 --- a/PkmnLib.Dynamic/Models/Battle.cs +++ b/PkmnLib.Dynamic/Models/Battle.cs @@ -236,7 +236,9 @@ public class BattleImpl : ScriptSource, IBattle // TODO: Hook to change number of PP needed. if (moveChoice.ChosenMove.CurrentPp < 1) return false; - // TODO: Validate target + if (!TargetResolver.IsValidTarget(moveChoice.TargetSide, moveChoice.TargetPosition, + moveChoice.ChosenMove.MoveData.Target, moveChoice.User)) + return false; } return true; diff --git a/PkmnLib.Dynamic/Models/BattleFlow/TargetResolver.cs b/PkmnLib.Dynamic/Models/BattleFlow/TargetResolver.cs index e13c45b..e77b0e7 100644 --- a/PkmnLib.Dynamic/Models/BattleFlow/TargetResolver.cs +++ b/PkmnLib.Dynamic/Models/BattleFlow/TargetResolver.cs @@ -26,6 +26,60 @@ public static class TargetResolver }; } + /// + /// Validates whether a given target is valid for a move choice. Returns true if the target is valid. + /// + public static bool IsValidTarget(byte side, byte position, MoveTarget target, IPokemon user) + { + var userBattleData = user.BattleData; + if (userBattleData == null) + throw new ArgumentNullException(nameof(user.BattleData)); + var userSide = userBattleData.SideIndex; + var userPosition = userBattleData.Position; + + switch (target) + { + case MoveTarget.Adjacent: + case MoveTarget.AllAdjacent: + { + var diff = Math.Abs(position - userPosition); + if (diff == 0) + return userSide == side; + return diff <= 1; + } + case MoveTarget.AdjacentAlly: + { + if (userSide != side) + return false; + return Math.Abs(position - userPosition) == 1; + } + case MoveTarget.AdjacentAllySelf: + { + if (userSide != side) + return false; + return Math.Abs(position - userPosition) <= 1; + } + case MoveTarget.AdjacentOpponent: + case MoveTarget.AllAdjacentOpponent: + { + if (userSide == side) + return false; + return Math.Abs(position - userPosition) <= 1; + } + case MoveTarget.All: + case MoveTarget.Any: + case MoveTarget.RandomOpponent: + return true; + case MoveTarget.AllAlly: + return userSide == side; + case MoveTarget.AllOpponent: + return userSide != side; + case MoveTarget.SelfUse: + return userSide == side && userPosition == position; + } + throw new ArgumentOutOfRangeException(nameof(target), target, null); + } + private static IReadOnlyList GetAllTargets(IBattle battle) => battle.Sides.SelectMany(x => x.Pokemon).ToList(); diff --git a/PkmnLib.Dynamic/StaticHelpers.cs b/PkmnLib.Dynamic/StaticHelpers.cs index ef24ba4..e0574aa 100644 --- a/PkmnLib.Dynamic/StaticHelpers.cs +++ b/PkmnLib.Dynamic/StaticHelpers.cs @@ -9,10 +9,10 @@ public static class StaticHelpers /// A function to get the current date and time. This can be replaced in cases where the date and time /// may not be the same as the system time. /// - public static Func DateTimeProvider { get; set; } = () => DateTime.Now; + public static Func DateTimeProvider { get; set; } = () => DateTimeOffset.Now; /// /// Get the current date and time. /// - public static DateTime GetCurrentDateTime() => DateTimeProvider(); + public static DateTimeOffset GetCurrentDateTime() => DateTimeProvider(); } \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7MiscLibrary.cs b/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7MiscLibrary.cs index b44c068..072a650 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7MiscLibrary.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7MiscLibrary.cs @@ -24,7 +24,7 @@ public class Gen7MiscLibrary : IMiscLibrary /// public TimeOfDay GetTimeOfDay() { - var time = StaticHelpers.GetCurrentDateTime(); + var time = StaticHelpers.GetCurrentDateTime().LocalDateTime; var hour = time.Hour; return hour switch {