|
3 | 3 | using System.Linq;
|
4 | 4 | using static PKHeX.Core.Ball;
|
5 | 5 |
|
6 |
| -namespace PKHeX.Core |
| 6 | +namespace PKHeX.Core; |
| 7 | + |
| 8 | +/// <summary> |
| 9 | +/// Contains logic to apply a new <see cref="Ball"/> value to a <see cref="PKM"/>. |
| 10 | +/// </summary> |
| 11 | +public static class BallApplicator |
7 | 12 | {
|
8 | 13 | /// <summary>
|
9 |
| - /// Contains logic to apply a new <see cref="Ball"/> value to a <see cref="PKM"/>. |
| 14 | + /// Gets all balls that are legal for the input <see cref="PKM"/>. |
10 | 15 | /// </summary>
|
11 |
| - public static class BallApplicator |
| 16 | + /// <remarks> |
| 17 | + /// Requires checking the <see cref="LegalityAnalysis"/> for every <see cref="Ball"/> that is tried. |
| 18 | + /// </remarks> |
| 19 | + /// <param name="pk">Pokémon to retrieve a list of valid balls for.</param> |
| 20 | + /// <returns>Enumerable list of <see cref="Ball"/> values that the <see cref="PKM"/> is legal with.</returns> |
| 21 | + public static IEnumerable<Ball> GetLegalBalls(PKM pk) |
12 | 22 | {
|
13 |
| - /// <summary> |
14 |
| - /// Gets all balls that are legal for the input <see cref="PKM"/>. |
15 |
| - /// </summary> |
16 |
| - /// <remarks> |
17 |
| - /// Requires checking the <see cref="LegalityAnalysis"/> for every <see cref="Ball"/> that is tried. |
18 |
| - /// </remarks> |
19 |
| - /// <param name="pkm">Pokémon to retrieve a list of valid balls for.</param> |
20 |
| - /// <returns>Enumerable list of <see cref="Ball"/> values that the <see cref="PKM"/> is legal with.</returns> |
21 |
| - public static IEnumerable<Ball> GetLegalBalls(PKM pkm) |
| 23 | + var clone = pk.Clone(); |
| 24 | + foreach (var b in BallList) |
22 | 25 | {
|
23 |
| - var clone = pkm.Clone(); |
24 |
| - foreach (var b in BallList) |
25 |
| - { |
26 |
| - clone.Ball = (int)b; |
27 |
| - if (new LegalityAnalysis(clone).Valid) |
28 |
| - yield return b; |
29 |
| - } |
| 26 | + clone.Ball = (int)b; |
| 27 | + if (new LegalityAnalysis(clone).Valid) |
| 28 | + yield return b; |
30 | 29 | }
|
| 30 | + } |
31 | 31 |
|
32 |
| - /// <summary> |
33 |
| - /// Applies a random legal ball value if any exist. |
34 |
| - /// </summary> |
35 |
| - /// <remarks> |
36 |
| - /// Requires checking the <see cref="LegalityAnalysis"/> for every <see cref="Ball"/> that is tried. |
37 |
| - /// </remarks> |
38 |
| - /// <param name="pkm">Pokémon to modify.</param> |
39 |
| - public static int ApplyBallLegalRandom(PKM pkm) |
40 |
| - { |
41 |
| - var balls = GetBallListFromColor(pkm).ToArray(); |
42 |
| - Util.Shuffle(balls.AsSpan()); |
43 |
| - return ApplyFirstLegalBall(pkm, balls); |
44 |
| - } |
| 32 | + /// <summary> |
| 33 | + /// Applies a random legal ball value if any exist. |
| 34 | + /// </summary> |
| 35 | + /// <remarks> |
| 36 | + /// Requires checking the <see cref="LegalityAnalysis"/> for every <see cref="Ball"/> that is tried. |
| 37 | + /// </remarks> |
| 38 | + /// <param name="pk">Pokémon to modify.</param> |
| 39 | + public static int ApplyBallLegalRandom(PKM pk) |
| 40 | + { |
| 41 | + var balls = GetBallListFromColor(pk).ToArray(); |
| 42 | + Util.Shuffle(balls.AsSpan()); |
| 43 | + return ApplyFirstLegalBall(pk, balls); |
| 44 | + } |
45 | 45 |
|
46 |
| - /// <summary> |
47 |
| - /// Applies a legal ball value if any exist, ordered by color. |
48 |
| - /// </summary> |
49 |
| - /// <remarks> |
50 |
| - /// Requires checking the <see cref="LegalityAnalysis"/> for every <see cref="Ball"/> that is tried. |
51 |
| - /// </remarks> |
52 |
| - /// <param name="pkm">Pokémon to modify.</param> |
53 |
| - public static int ApplyBallLegalByColor(PKM pkm) |
54 |
| - { |
55 |
| - var balls = GetBallListFromColor(pkm); |
56 |
| - return ApplyFirstLegalBall(pkm, balls); |
57 |
| - } |
| 46 | + /// <summary> |
| 47 | + /// Applies a legal ball value if any exist, ordered by color. |
| 48 | + /// </summary> |
| 49 | + /// <remarks> |
| 50 | + /// Requires checking the <see cref="LegalityAnalysis"/> for every <see cref="Ball"/> that is tried. |
| 51 | + /// </remarks> |
| 52 | + /// <param name="pk">Pokémon to modify.</param> |
| 53 | + public static int ApplyBallLegalByColor(PKM pk) |
| 54 | + { |
| 55 | + var balls = GetBallListFromColor(pk); |
| 56 | + return ApplyFirstLegalBall(pk, balls); |
| 57 | + } |
58 | 58 |
|
59 |
| - /// <summary> |
60 |
| - /// Applies a random ball value in a cyclical manner. |
61 |
| - /// </summary> |
62 |
| - /// <param name="pkm">Pokémon to modify.</param> |
63 |
| - public static int ApplyBallNext(PKM pkm) |
64 |
| - { |
65 |
| - var balls = GetBallList(pkm.Ball); |
66 |
| - var next = balls.First(); |
67 |
| - return pkm.Ball = (int)next; |
68 |
| - } |
| 59 | + /// <summary> |
| 60 | + /// Applies a random ball value in a cyclical manner. |
| 61 | + /// </summary> |
| 62 | + /// <param name="pk">Pokémon to modify.</param> |
| 63 | + public static int ApplyBallNext(PKM pk) |
| 64 | + { |
| 65 | + var balls = GetBallList(pk.Ball); |
| 66 | + var next = balls.First(); |
| 67 | + return pk.Ball = (int)next; |
| 68 | + } |
69 | 69 |
|
70 |
| - private static int ApplyFirstLegalBall(PKM pkm, IEnumerable<Ball> balls) |
| 70 | + private static int ApplyFirstLegalBall(PKM pk, IEnumerable<Ball> balls) |
| 71 | + { |
| 72 | + foreach (var b in balls) |
71 | 73 | {
|
72 |
| - foreach (var b in balls) |
73 |
| - { |
74 |
| - pkm.Ball = (int)b; |
75 |
| - if (new LegalityAnalysis(pkm).Valid) |
76 |
| - break; |
77 |
| - } |
78 |
| - return pkm.Ball; |
| 74 | + pk.Ball = (int)b; |
| 75 | + if (new LegalityAnalysis(pk).Valid) |
| 76 | + break; |
79 | 77 | }
|
| 78 | + return pk.Ball; |
| 79 | + } |
80 | 80 |
|
81 |
| - private static IEnumerable<Ball> GetBallList(int ball) |
82 |
| - { |
83 |
| - var balls = BallList; |
84 |
| - var currentBall = (Ball)ball; |
85 |
| - return GetCircularOnce(balls, currentBall); |
86 |
| - } |
| 81 | + private static IEnumerable<Ball> GetBallList(int ball) |
| 82 | + { |
| 83 | + var balls = BallList; |
| 84 | + var currentBall = (Ball)ball; |
| 85 | + return GetCircularOnce(balls, currentBall); |
| 86 | + } |
87 | 87 |
|
88 |
| - private static IEnumerable<Ball> GetBallListFromColor(PKM pkm) |
89 |
| - { |
90 |
| - // Gen1/2 don't store color in personal info |
91 |
| - var pi = pkm.Format >= 3 ? pkm.PersonalInfo : PersonalTable.USUM.GetFormEntry(pkm.Species, 0); |
92 |
| - var color = (PersonalColor)pi.Color; |
93 |
| - var balls = BallColors[color]; |
94 |
| - var currentBall = (Ball)pkm.Ball; |
95 |
| - return GetCircularOnce(balls, currentBall); |
96 |
| - } |
| 88 | + private static IEnumerable<Ball> GetBallListFromColor(PKM pk) |
| 89 | + { |
| 90 | + // Gen1/2 don't store color in personal info |
| 91 | + var pi = pk.Format >= 3 ? pk.PersonalInfo : PersonalTable.USUM.GetFormEntry(pk.Species, 0); |
| 92 | + var color = (PersonalColor)pi.Color; |
| 93 | + var balls = BallColors[color]; |
| 94 | + var currentBall = (Ball)pk.Ball; |
| 95 | + return GetCircularOnce(balls, currentBall); |
| 96 | + } |
97 | 97 |
|
98 |
| - private static IEnumerable<T> GetCircularOnce<T>(T[] items, T current) |
99 |
| - { |
100 |
| - var currentIndex = Array.IndexOf(items, current); |
101 |
| - if (currentIndex < 0) |
102 |
| - currentIndex = items.Length - 2; |
103 |
| - for (int i = currentIndex + 1; i < items.Length; i++) |
104 |
| - yield return items[i]; |
105 |
| - for (int i = 0; i <= currentIndex; i++) |
106 |
| - yield return items[i]; |
107 |
| - } |
| 98 | + private static IEnumerable<T> GetCircularOnce<T>(T[] items, T current) |
| 99 | + { |
| 100 | + var currentIndex = Array.IndexOf(items, current); |
| 101 | + if (currentIndex < 0) |
| 102 | + currentIndex = items.Length - 2; |
| 103 | + for (int i = currentIndex + 1; i < items.Length; i++) |
| 104 | + yield return items[i]; |
| 105 | + for (int i = 0; i <= currentIndex; i++) |
| 106 | + yield return items[i]; |
| 107 | + } |
108 | 108 |
|
109 |
| - private static readonly Ball[] BallList = (Ball[]) Enum.GetValues(typeof(Ball)); |
| 109 | + private static readonly Ball[] BallList = (Ball[]) Enum.GetValues(typeof(Ball)); |
110 | 110 |
|
111 |
| - static BallApplicator() |
| 111 | + static BallApplicator() |
| 112 | + { |
| 113 | + var exclude = new[] {None, Poke}; |
| 114 | + var end = new[] {Poke}; |
| 115 | + var allBalls = BallList.Except(exclude).ToArray(); |
| 116 | + var colors = (PersonalColor[])Enum.GetValues(typeof(PersonalColor)); |
| 117 | + foreach (var c in colors) |
112 | 118 | {
|
113 |
| - var exclude = new[] {None, Poke}; |
114 |
| - var end = new[] {Poke}; |
115 |
| - var allBalls = BallList.Except(exclude).ToArray(); |
116 |
| - var colors = (PersonalColor[])Enum.GetValues(typeof(PersonalColor)); |
117 |
| - foreach (var c in colors) |
118 |
| - { |
119 |
| - var matchingColors = BallColors[c]; |
120 |
| - var extra = allBalls.Except(matchingColors).ToArray(); |
121 |
| - Util.Shuffle(extra.AsSpan()); |
122 |
| - BallColors[c] = ArrayUtil.ConcatAll(matchingColors, extra, end); |
123 |
| - } |
| 119 | + var matchingColors = BallColors[c]; |
| 120 | + var extra = allBalls.Except(matchingColors).ToArray(); |
| 121 | + Util.Shuffle(extra.AsSpan()); |
| 122 | + BallColors[c] = ArrayUtil.ConcatAll(matchingColors, extra, end); |
124 | 123 | }
|
| 124 | + } |
125 | 125 |
|
126 |
| - /// <summary> |
127 |
| - /// Priority Match ball IDs that match the color ID in descending order |
128 |
| - /// </summary> |
129 |
| - private static readonly Dictionary<PersonalColor, Ball[]> BallColors = new() |
130 |
| - { |
131 |
| - [PersonalColor.Red] = new[] { Cherish, Repeat, Fast, Heal, Great, Dream, Lure }, |
132 |
| - [PersonalColor.Blue] = new[] { Dive, Net, Great, Beast, Lure }, |
133 |
| - [PersonalColor.Yellow] = new[] { Level, Ultra, Repeat, Quick, Moon }, |
134 |
| - [PersonalColor.Green] = new[] { Safari, Friend, Nest, Dusk }, |
135 |
| - [PersonalColor.Black] = new[] { Luxury, Heavy, Ultra, Moon, Net, Beast }, |
| 126 | + /// <summary> |
| 127 | + /// Priority Match ball IDs that match the color ID in descending order |
| 128 | + /// </summary> |
| 129 | + private static readonly Dictionary<PersonalColor, Ball[]> BallColors = new() |
| 130 | + { |
| 131 | + [PersonalColor.Red] = new[] { Cherish, Repeat, Fast, Heal, Great, Dream, Lure }, |
| 132 | + [PersonalColor.Blue] = new[] { Dive, Net, Great, Beast, Lure }, |
| 133 | + [PersonalColor.Yellow] = new[] { Level, Ultra, Repeat, Quick, Moon }, |
| 134 | + [PersonalColor.Green] = new[] { Safari, Friend, Nest, Dusk }, |
| 135 | + [PersonalColor.Black] = new[] { Luxury, Heavy, Ultra, Moon, Net, Beast }, |
136 | 136 |
|
137 |
| - [PersonalColor.Brown] = new[] { Level, Heavy }, |
138 |
| - [PersonalColor.Purple] = new[] { Master, Love, Dream, Heal }, |
139 |
| - [PersonalColor.Gray] = new[] { Heavy, Premier, Luxury }, |
140 |
| - [PersonalColor.White] = new[] { Premier, Timer, Luxury, Ultra }, |
141 |
| - [PersonalColor.Pink] = new[] { Love, Dream, Heal }, |
142 |
| - }; |
| 137 | + [PersonalColor.Brown] = new[] { Level, Heavy }, |
| 138 | + [PersonalColor.Purple] = new[] { Master, Love, Dream, Heal }, |
| 139 | + [PersonalColor.Gray] = new[] { Heavy, Premier, Luxury }, |
| 140 | + [PersonalColor.White] = new[] { Premier, Timer, Luxury, Ultra }, |
| 141 | + [PersonalColor.Pink] = new[] { Love, Dream, Heal }, |
| 142 | + }; |
143 | 143 |
|
144 |
| - /// <summary> |
145 |
| - /// Personal Data color IDs |
146 |
| - /// </summary> |
147 |
| - private enum PersonalColor : byte |
148 |
| - { |
149 |
| - Red, |
150 |
| - Blue, |
151 |
| - Yellow, |
152 |
| - Green, |
153 |
| - Black, |
| 144 | + /// <summary> |
| 145 | + /// Personal Data color IDs |
| 146 | + /// </summary> |
| 147 | + private enum PersonalColor : byte |
| 148 | + { |
| 149 | + Red, |
| 150 | + Blue, |
| 151 | + Yellow, |
| 152 | + Green, |
| 153 | + Black, |
154 | 154 |
|
155 |
| - Brown, |
156 |
| - Purple, |
157 |
| - Gray, |
158 |
| - White, |
159 |
| - Pink, |
160 |
| - } |
| 155 | + Brown, |
| 156 | + Purple, |
| 157 | + Gray, |
| 158 | + White, |
| 159 | + Pink, |
161 | 160 | }
|
162 | 161 | }
|
0 commit comments