Compare commits

..

3 Commits
v2 ... master

Author SHA1 Message Date
Kamron Batman
1448effa20
Fixes code formatting 2023-09-11 20:09:32 -07:00
Kamron Batman
7c78296637
Add missing configs 2023-09-11 20:06:34 -07:00
Kamron Batman
e88f242f11
Updates to .Net 7 AOT 2023-09-11 19:54:54 -07:00
3 changed files with 951 additions and 797 deletions

View File

@ -2,7 +2,14 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<PublishAot>true</PublishAot>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>full</TrimMode>
<OptimizationPreference>Speed</OptimizationPreference>
<Version>3.0.0</Version>
<Copyright>2023</Copyright>
<Company>ProjectPokemon.org</Company>
</PropertyGroup>
</Project>

View File

@ -3,11 +3,11 @@ using System.Linq;
using System.Globalization;
using System.Collections.Generic;
namespace Gen3EventLegality
namespace Gen3EventLegality;
public static class Program
{
public static class Program
{
private static string version = "2.0";
private const string Version = "3.0";
[Flags]
public enum Algo : ulong
@ -43,7 +43,8 @@ namespace Gen3EventLegality
UnknownOTG = 0x80000000,
}
public static Dictionary<string, Algo> EventOptions = new Dictionary<string, Algo> {
public static Dictionary<string, Algo> EventOptions = new()
{
{ "5th Anniv Eggs", Algo.PCJP2003 | Algo.BACDPIDIV | Algo.Offset },
{ "PCJP 2004/PCNY WISH Eggs", Algo.WCEggs },
{ "PokePark 2005 Eggs", Algo.PokeParkEggs | Algo.CanBeShiny },
@ -53,14 +54,36 @@ namespace Gen3EventLegality
{ "None", Algo.Unknown }
};
public static Dictionary<uint, Tuple<string, Algo>> EventsByID = new Dictionary<uint, Tuple<string, Algo>> {
{ 30719, Tuple.Create("Wishing Star Jirachi", Algo.BACDPIDIV | Algo.Offset | Algo.ForceAntiShiny | Algo.RandItem1 | Algo.MaleOTG) },
public static Dictionary<uint, Tuple<string, Algo>> EventsByID = new()
{
{
30719,
Tuple.Create(
"Wishing Star Jirachi",
Algo.BACDPIDIV | Algo.Offset | Algo.ForceAntiShiny | Algo.RandItem1 | Algo.MaleOTG
)
},
{ 20043, Tuple.Create("Wishmaker/METEOR Jirachi (20043)", Algo.BACDPIDIV | Algo.WSHMKR | Algo.RandItem1 | Algo.CanBeShiny) },
{
20043,
Tuple.Create("Wishmaker/METEOR Jirachi (20043)", Algo.BACDPIDIV | Algo.WSHMKR | Algo.RandItem1 | Algo.CanBeShiny)
},
{ 30317, Tuple.Create("English Berry Glitch Zigzagoon", Algo.BerryGlitch | Algo.BACDPIDIV | Algo.ForceShiny | Algo.LimitRange) },
{
30317,
Tuple.Create(
"English Berry Glitch Zigzagoon",
Algo.BerryGlitch | Algo.BACDPIDIV | Algo.ForceShiny | Algo.LimitRange
)
},
{ 21121, Tuple.Create("Japanese Berry Glitch Zigzagoon", Algo.BerryGlitch | Algo.BACDPIDIV | Algo.ForceShiny | Algo.LimitRange) },
{
21121,
Tuple.Create(
"Japanese Berry Glitch Zigzagoon",
Algo.BerryGlitch | Algo.BACDPIDIV | Algo.ForceShiny | Algo.LimitRange
)
},
{ 30821, Tuple.Create("Stamp", Algo.BACDPIDIV | Algo.RandItem1 | Algo.RandOTG1) },
@ -217,54 +240,58 @@ namespace Gen3EventLegality
public static void Main(string[] args)
{
Console.WriteLine("3rd Gen Legality Checker by Sabresite (v{0})", version);
Console.WriteLine("3rd Gen Legality Checker by Sabresite (v{0})", Version);
Console.WriteLine("If an egg event or PCNY, press enter");
Console.Write("TID:");
uint[] numbers = GetNumbers();
bool gotTID = numbers.Length > 0;
uint TID = gotTID ? numbers[0] : 9999;
var numbers = GetNumbers();
var gotTID = numbers.Length > 0;
var TID = gotTID ? numbers[0] : 9999;
bool foundEvent = EventsByID.TryGetValue(TID, out var option);
var foundEvent = EventsByID.TryGetValue(TID, out var option);
if (!foundEvent)
{
if (!gotTID)
{
Console.WriteLine("Could not find event by TID. Maybe it is an egg event or PCNY?");
}
int index;
Dictionary<string, Algo>.KeyCollection keys = EventOptions.Keys;
var keys = EventOptions.Keys;
do
{
int count = 0;
foreach (string eventName in keys)
var count = 0;
foreach (var eventName in keys)
Console.WriteLine("{0}. {1}", (++count).ToString().PadLeft(2), eventName);
Console.Write("----------\nChoose an event by number:");
} while (!int.TryParse(Console.ReadLine(), out index) || index < 0 || index > EventOptions.Keys.Count);
KeyValuePair<string, Algo> choice = EventOptions.ElementAt(index - 1);
var choice = EventOptions.ElementAt(index - 1);
if (choice.Value == Algo.Unknown)
{
return;
}
option = Tuple.Create(choice.Key, choice.Value);
}
Algo algo = option.Item2;
var algo = option.Item2;
bool forcedShiny = Has(algo, Algo.ForceShiny);
bool WCEggs = Has(algo, Algo.WCEggs);
bool hasOffset = Has(algo, Algo.Offset);
bool berryGlitch = Has(algo, Algo.BerryGlitch);
bool XDAlgo = Has(algo, Algo.DFABPIDIV);
bool Box = Has(algo, Algo.Box);
bool mystryMew = TID == 6930;
bool batchGen = Has(algo, Algo.BatchGen);
bool noIVs = Has(algo, Algo.NoIVs);
bool forceAntishiny = Has(algo, Algo.ForceAntiShiny);
var forcedShiny = Has(algo, Algo.ForceShiny);
var WCEggs = Has(algo, Algo.WCEggs);
var hasOffset = Has(algo, Algo.Offset);
var berryGlitch = Has(algo, Algo.BerryGlitch);
var XDAlgo = Has(algo, Algo.DFABPIDIV);
var Box = Has(algo, Algo.Box);
var mystryMew = TID == 6930;
var batchGen = Has(algo, Algo.BatchGen);
var noIVs = Has(algo, Algo.NoIVs);
var forceAntishiny = Has(algo, Algo.ForceAntiShiny);
List<Tuple<uint, uint, uint>> PIDTIDs = new List<Tuple<uint, uint, uint>>();
var PIDTIDs = new List<Tuple<uint, uint, uint>>();
bool finished;
/*
@ -281,20 +308,29 @@ namespace Gen3EventLegality
Console.Write("PID <TID> <SID>:");
numbers = GetNumbers();
finished = numbers.Length == 0;
if (!finished) PIDTIDs.Add(new Tuple<uint, uint, uint>(numbers[0], numbers.Length > 1 ? numbers[1] : TID, numbers.Length > 2 ? numbers[2] : 0));
if (!finished)
{
PIDTIDs.Add(
new Tuple<uint, uint, uint>(
numbers[0],
numbers.Length > 1 ? numbers[1] : TID,
numbers.Length > 2 ? numbers[2] : 0
)
);
}
} while (!finished);
Console.WriteLine("----------");
uint seedRange = Has(algo, Algo.LimitRange) ? 0x100u : 0x10000u;
var seedRange = Has(algo, Algo.LimitRange) ? 0x100u : 0x10000u;
for (int p = 0; p < PIDTIDs.Count; p++)
for (var p = 0; p < PIDTIDs.Count; p++)
{
uint PID = PIDTIDs[p].Item1;
var PID = PIDTIDs[p].Item1;
TID = PIDTIDs[p].Item2;
uint SID = PIDTIDs[p].Item3;
var SID = PIDTIDs[p].Item3;
bool found = false;
var found = false;
uint rand1;
uint rand2;
@ -303,7 +339,7 @@ namespace Gen3EventLegality
uint rand5;
if (XDAlgo)
{
bool another = false;
var another = false;
// XD - Do it backwards - DFAB
for (uint i = 0; XDAlgo && i < seedRange; i++)
@ -320,42 +356,55 @@ namespace Gen3EventLegality
pid = ((rand2 >> 0x10) << 0x10) | (rand1 >> 0x10);
seed = rand3;
} while (!noIVs && isShiny(pid, TID, SID));
if (pid == PID)
if (pid != PID)
{
continue;
}
if (another)
{
Console.WriteLine(" - ");
}
found = true;
rand4 = Prev(rand3, algo); // IV2
rand5 = Prev(rand4, algo); // IV1
Console.WriteLine("Found Seed: {0:X8} ({1:X8}) - {2}{3}", Prev(Prev(rand5, algo), algo), PID, option.Item1, noIVs ? " " + eReaderType(pid) : "");
Console.WriteLine(
"Found Seed: {0:X8} ({1:X8}) - {2}{3}",
Prev(Prev(rand5, algo), algo),
PID,
option.Item1,
noIVs ? $" {eReaderType(pid)}" : ""
);
Console.WriteLine("Nature: {0}", index2Nature(PID));
Console.WriteLine(Has(algo, Algo.CanBeShiny) ? "Shiny: Can be shiny" : "Shiny: Cannot be shiny");
var ivs = noIVs ? new uint[] { 0, 0, 0, 0, 0, 0 } : ParseStats((rand5 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
var ivs = noIVs
? new uint[] { 0, 0, 0, 0, 0, 0 }
: ParseStats((rand5 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
Console.WriteLine("IVs: {0}, {1}, {2}, {4}, {5}, {3}", ivs[0], ivs[1], ivs[2], ivs[3], ivs[4], ivs[5]);
if (TID == 31121) // Ageto/Colos
{
Console.WriteLine("OTG: Female (Ageto) - Male (Colos)");
}
another = true;
}
}
Console.WriteLine("----------");
}
if (WCEggs || Has(algo, Algo.PokeParkEggs))
{
bool another = false;
var another = false;
// Do it backwards, find a ABDE
for (uint i = 0; i < seedRange; i++)
@ -363,15 +412,22 @@ namespace Gen3EventLegality
rand1 = (((PID & 0xFFFF) << 0x10)) | i; // PIDL
rand2 = Next(rand1, algo); // PIDH
uint pid = ((rand2 >> 0x10) << 0x10) | (rand1 >> 0x10);
var pid = ((rand2 >> 0x10) << 0x10) | (rand1 >> 0x10);
if (pid == PID)
{
if (another)
{
Console.WriteLine(" - ");
}
found = true;
Console.WriteLine("Found Wondercard Seed: {0:X8} ({1:X8}) - {2}", Prev(rand1, algo), PID, option.Item1);
Console.WriteLine(
"Found Wondercard Seed: {0:X8} ({1:X8}) - {2}",
Prev(rand1, algo),
PID,
option.Item1
);
Console.WriteLine("Nature: {0}", index2Nature(PID % 25));
@ -381,20 +437,30 @@ namespace Gen3EventLegality
rand4 = Next(rand3, algo);
rand5 = Next(rand4, algo);
uint[] ivs = ParseStats((rand4 >> 0x10) & 0x7FFF, (rand5 >> 0x10) & 0x7FFF);
Console.WriteLine("IVs: {0}, {1}, {2}, {4}, {5}, {3}", ivs[0], ivs[1], ivs[2], ivs[3], ivs[4], ivs[5]);
var ivs = ParseStats((rand4 >> 0x10) & 0x7FFF, (rand5 >> 0x10) & 0x7FFF);
Console.WriteLine(
"IVs: {0}, {1}, {2}, {4}, {5}, {3}",
ivs[0],
ivs[1],
ivs[2],
ivs[3],
ivs[4],
ivs[5]
);
another = true;
}
}
if (WCEggs)
{
Console.WriteLine("----------");
}
}
if (Box)
{
bool another = false;
var another = false;
// Do it backwards, find a BACD
for (uint i = 0; i < seedRange; i++)
@ -402,12 +468,17 @@ namespace Gen3EventLegality
rand1 = (PID & 0xFFFF0000) | i;
rand2 = Next(rand1, algo);
uint pid = ((rand1 >> 0x10) << 0x10) | (rand2 >> 0x10);
var pid = ((rand1 >> 0x10) << 0x10) | (rand2 >> 0x10);
if (pid == PID)
if (pid != PID)
{
continue;
}
if (another)
{
Console.WriteLine(" - ");
}
found = true;
Console.WriteLine("Found Seed: {0:X8} ({1:X8}) - {2}", Prev(rand1, algo), PID, option.Item1);
@ -419,19 +490,18 @@ namespace Gen3EventLegality
rand3 = Next(rand2, algo);
rand4 = Next(rand3, algo);
uint[] ivs = ParseStats((rand3 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
var ivs = ParseStats((rand3 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
Console.WriteLine("IVs: {0}, {1}, {2}, {4}, {5}, {3}", ivs[0], ivs[1], ivs[2], ivs[3], ivs[4], ivs[5]);
another = true;
}
}
Console.WriteLine("----------");
}
if (forceAntishiny)
{
bool another = false;
var another = false;
for (uint i = 0; i < seedRange; i++)
{
@ -441,12 +511,17 @@ namespace Gen3EventLegality
rand4 = Next(rand3, algo);
rand5 = Next(rand4, algo);
if (((rand2 >> 0x10) ^ TID ^ SID ^ (rand1 >> 0x10)) == PID >> 0x10 && !isShiny(PID, TID, SID))
if (((rand2 >> 0x10) ^ TID ^ SID ^ (rand1 >> 0x10)) != PID >> 0x10 || isShiny(PID, TID, SID))
{
if (another)
Console.WriteLine(" - ");
continue;
}
uint seed = Prev(rand1, algo);
if (another)
{
Console.WriteLine(" - ");
}
var seed = Prev(rand1, algo);
found = true;
Console.WriteLine("Found Seed: {0:X8} ({1:X8}) - TID {2}", seed, PID, TID);
@ -455,28 +530,29 @@ namespace Gen3EventLegality
Console.WriteLine("Shiny: Cannot be shiny");
uint[] ivs = ParseStats((rand3 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
var ivs = ParseStats((rand3 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
Console.WriteLine("IVs: {0}, {1}, {2}, {4}, {5}, {3}", ivs[0], ivs[1], ivs[2], ivs[3], ivs[4], ivs[5]);
uint d = Prev(rand1, algo);
uint c = Prev(d, algo);
uint b = Prev(c, algo);
var d = Prev(rand1, algo);
var c = Prev(d, algo);
var b = Prev(c, algo);
another = true;
}
}
Console.WriteLine("----------");
}
if (!WCEggs && !Box && (Has(algo, Algo.BACDPIDIV) || Has(algo, Algo.PokeParkEggs)))
if (WCEggs || Box || (!Has(algo, Algo.BACDPIDIV) && !Has(algo, Algo.PokeParkEggs)))
{
continue;
}
for (uint i = 0; i < seedRange; i++)
{
uint rand1a;
uint rand1b;
uint seed = rand1a = rand1b = i;
uint originalSeed = seed;
var seed = rand1a = rand1b = i;
Tuple<string, string, uint, bool> entry = null;
uint TSV = 0;
@ -485,7 +561,7 @@ namespace Gen3EventLegality
rand1a = Next(seed, algo);
rand1b = Next(rand1a, algo);
uint tempPid = (rand1a & 0xFFFF0000) | (rand1b >> 0x10);
var tempPid = (rand1a & 0xFFFF0000) | (rand1b >> 0x10);
/* This never actually happens in seed range 0->FFFF
if (tempPid == 0)
@ -512,6 +588,7 @@ namespace Gen3EventLegality
originalPID = pid;
if (mystryMew)
{
while (isShiny(pid, TID, SID))
{
rand1 = Next(rand2, algo); // PIDH
@ -519,6 +596,7 @@ namespace Gen3EventLegality
pid = ((rand1 >> 0x10) << 0x10) | (rand2 >> 0x10);
}
}
if (Has(algo, Algo.PCJP2003) && PID - pid < 8)
{
@ -557,24 +635,33 @@ namespace Gen3EventLegality
itemRand = Has(algo, Algo.ItemFirst) ? rand5 : rand6;
otgRand = !Has(algo, Algo.ItemFirst) ? rand5 : rand6;
if (pid != PID)
// in case of antishiny, we have to go back.
rand1b = Next(Next(Next(Next(Next(rand1b, algo), algo), algo), algo), algo); // PID, IV, OTG -> next in batch.
if (pid != PID)
{
// PID, IV, OTG -> next in batch.
rand1b = Next(
Next(Next(Next(Next(rand1b, algo), algo), algo), algo),
algo
);
}
batchCount++;
} while (batchGen && pid != PID && batchCount <= 5);
if (batchCount > 6 || pid != PID)
{
continue;
}
found = true;
string knownSeed = "Found Seed";
var knownSeed = "Found Seed";
if (berryGlitch)
knownSeed = originalSeed >= 3 && originalSeed <= 180 ? "Known Seed" : "Unknown Seed";
{
knownSeed = seed >= 3 && seed <= 180 ? "Known Seed" : "Unknown Seed";
}
string mystryMewBatch = "";
var mystryMewBatch = "";
if (mystryMew)
{
@ -587,45 +674,75 @@ namespace Gen3EventLegality
$"{mewIndex}/{MystryMewSeeds.Length} {(mewIndex < 7 ? "Party" : "PC")} Slot {(mewIndex < 7 ? mewIndex : mewIndex - 6)}";
}
else
{
mystryMewBatch = $" ({batchCount} of 5)";
}
}
Console.WriteLine("{0}: {1:X8} - {2} {3}", knownSeed, i, option.Item1, mystryMewBatch);
Console.WriteLine("PID: {0:X8} ({1})", PID, index2Nature(PID % 25));
uint rtc = seed ^ (seed < 0x5A0u ? 0x10001u : 0x0u);
var rtc = seed ^ (seed < 0x5A0u ? 0x10001u : 0x0u);
if (hasOffset)
{
uint days = rtc / 1440;
uint hours = rtc % 1440 / 60;
uint mins = rtc % 60;
Console.WriteLine("RTC: {0} day{1}, {2} hour{3}, {4} minute{5}", days, days != 0 ? "s" : "", hours, hours != 0 ? "s" : "", mins, mins != 0 ? "s" : "");
var days = rtc / 1440;
var hours = rtc % 1440 / 60;
var mins = rtc % 60;
Console.WriteLine(
"RTC: {0} day{1}, {2} hour{3}, {4} minute{5}",
days,
days != 0 ? "s" : "",
hours,
hours != 0 ? "s" : "",
mins,
mins != 0 ? "s" : ""
);
if (Has(algo, Algo.PCJP2003))
{
Console.WriteLine("Species: {1}{0} {2}", entry.Item1, entry.Item4 ? "Forced Shiny " : pid - originalPID > 0 && pid - originalPID < 8 ? "Anti-Shiny " : "", entry.Item2);
Console.WriteLine(
"Species: {1}{0} {2}",
entry.Item1,
entry.Item4 ? "Forced Shiny " :
pid - originalPID > 0 && pid - originalPID < 8 ? "Anti-Shiny " : "",
entry.Item2
);
Console.WriteLine("TSV: {0:X4}", TSV);
}
}
if (Has(algo, Algo.PCJP2003) && !forcedShiny)
{
Console.WriteLine("Shiny: Cannot be shiny if hatched by original trainer");
}
else if (Has(algo, Algo.CanBeShiny))
{
Console.WriteLine("Shiny: Can be shiny");
}
else if (forcedShiny)
{
Console.WriteLine("Shiny: Must be shiny");
}
else
{
Console.WriteLine("Shiny: Cannot be shiny");
}
var ivs = Has(algo, Algo.NoIVs) ? new uint[] { 0, 0, 0, 0, 0, 0 } : ParseStats((rand3 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
var ivs = Has(algo, Algo.NoIVs)
? new uint[] { 0, 0, 0, 0, 0, 0 }
: ParseStats((rand3 >> 0x10) & 0x7FFF, (rand4 >> 0x10) & 0x7FFF);
Console.WriteLine("IVs: {0}, {1}, {2}, {4}, {5}, {3}", ivs[0], ivs[1], ivs[2], ivs[3], ivs[4], ivs[5]);
if (Has(algo, Algo.BerryGlitch))
{
Console.WriteLine("OTG: {0}", ((otgRand >> 0x10) / 3 & 1) == 1 ? "Female (RUBY)" : "Male (SAPHIRE)");
}
else if (Has(algo, Algo.RandOTG3))
{
Console.WriteLine("OTG: {0}", ((otgRand >> 0x17) / 1 & 1) == 0 ? "Female" : "Male");
}
else if (Has(algo, Algo.RandOTG2))
{
if (TID == 50701)
@ -634,41 +751,58 @@ namespace Gen3EventLegality
Console.WriteLine("Sapporo Pikachu OTG: Male (Always)");
}
else
{
Console.WriteLine("OTG: {0}", ((otgRand >> 0x13) / 1 & 1) == 1 ? "Female" : "Male");
}
}
else if (Has(algo, Algo.RandOTG1))
{
Console.WriteLine("OTG: {0}", ((otgRand >> 0x10) / 3 & 1) == 1 ? "Female" : "Male");
}
else if (Has(algo, Algo.MaleOTG))
{
Console.WriteLine("OTG: Male (Always)");
}
else if (Has(algo, Algo.FemaleOTG))
{
Console.WriteLine("OTG: Female (Always)");
}
if (Has(algo, Algo.RandItem3))
{
Console.WriteLine("Item: {0}", ((itemRand >> 0x17) & 1) == 0 ? "Salac Berry" : "Ganlon Berry");
}
else if (Has(algo, Algo.RandItem2))
{
Console.WriteLine("Item: {0}", ((itemRand >> 0x13) & 1) == 0 ? "Salac Berry" : "Ganlon Berry");
}
else if (Has(algo, Algo.RandItem1))
{
if (Has(algo, Algo.WSHMKR))
{
Console.WriteLine("Item: {0}", ((itemRand >> 0x10) / 3 & 1) == 0 ? "Salac Berry" : "Ganlon Berry");
}
else if (hasOffset)
{
string berry =
var berry =
$"Ganlon Berry ({((rtc & 0x1) == 0 ? "99.8%" : "0.2%")}), Salac Berry ({((rtc & 0x1) == 1 ? "99.8%" : "0.2%")})";
Console.WriteLine("Item: {0}", berry);
}
else
{
Console.WriteLine("Item: {0}", ((itemRand >> 0x10) / 3 & 1) == 0 ? "Petaya Berry" : "Apicot Berry");
}
}
}
if (!found)
{
Console.WriteLine("No seeds found for {0:X8}", PID);
}
Console.WriteLine("----------");
}
}
Console.WriteLine("Complete. Press enter to exit.");
Console.ReadLine();
@ -676,7 +810,8 @@ namespace Gen3EventLegality
public static bool isShiny(uint pid, uint tid, uint sid) => ((pid >> 16) ^ (pid & 0xFFFF) ^ tid ^ sid) < 8;
public static uint forceShinyPID(uint seed, uint shiny, uint tid, uint sid) => (seed << 0x10) | ((seed ^ tid ^ sid) & 0xFFF8) | (shiny & 7);
public static uint forceShinyPID(uint seed, uint shiny, uint tid, uint sid) =>
(seed << 0x10) | ((seed ^ tid ^ sid) & 0xFFF8) | (shiny & 7);
public static uint getTSVFromForceShiny(uint pid) => (pid >> 0x10) ^ (pid & 0xFFF8);
@ -686,21 +821,25 @@ namespace Gen3EventLegality
public static uint[] GetNumbers()
{
string[] lines = Console.ReadLine()?.Trim().Split(' ');
var lines = Console.ReadLine()?.Trim().Split(' ');
if (string.IsNullOrEmpty(lines?[0])) return new uint[]{};
List<uint> numbers = new List<uint>();
foreach (string str in lines)
if (string.IsNullOrEmpty(lines?[0]))
{
uint number;
bool success = str.StartsWith("0x") ?
uint.TryParse(str.Replace("0x", ""), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out number) :
uint.TryParse(str, out number);
return Array.Empty<uint>();
}
var numbers = new List<uint>();
foreach (var str in lines)
{
var success = str.StartsWith("0x")
? uint.TryParse(str.Replace("0x", ""), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var number)
: uint.TryParse(str, out number);
if (!success)
return new uint[] { };
{
return Array.Empty<uint>();
}
numbers.Add(number);
}
@ -710,9 +849,9 @@ namespace Gen3EventLegality
public static uint GetRandomEntry(uint randVal, uint max)
{
uint high = randVal >> 16;
uint first = ((high << 2) & 0xFFFF) + high;
uint second = ((randVal & 0xFFFF) << 1) + (first >> 16);
var high = randVal >> 16;
var first = ((high << 2) & 0xFFFF) + high;
var second = ((randVal & 0xFFFF) << 1) + (first >> 16);
second += high + (second >> 16);
@ -721,43 +860,48 @@ namespace Gen3EventLegality
public static Tuple<string, string, uint, bool> GetEggEntry(uint randVal, uint seed)
{
uint result = GetRandomEntry(randVal, 1000);
int count = 0;
var result = GetRandomEntry(randVal, 1000);
var count = 0;
while (true)
{
if (result < PCJP2003Types[count].Item3)
{
return PCJP2003Types[count];
}
result -= PCJP2003Types[count++].Item3;
}
}
public static Tuple<string, string, uint, bool>[] PCJP2003Types = new Tuple<string, string, uint, bool>[]
{
new Tuple<string,string,uint,bool>("Pichu","Teeter Dance",100, false),
new Tuple<string,string,uint,bool>("Pichu","Teeter Dance",25, true),
new Tuple<string,string,uint,bool>("Pichu","Wish",100, false),
new Tuple<string,string,uint,bool>("Pichu","Wish",25, true),
new Tuple<string,string,uint,bool>("Bagon","Iron Defense",125, false),
new Tuple<string,string,uint,bool>("Bagon","Wish",125, false),
new Tuple<string,string,uint,bool>("Absol","Spite",125, false),
new Tuple<string,string,uint,bool>("Absol","Wish",125, false),
new Tuple<string,string,uint,bool>("Ralts","Charm",125, false),
new Tuple<string,string,uint,bool>("Ralts","Wish",125, false),
public static Tuple<string, string, uint, bool>[] PCJP2003Types = {
new("Pichu", "Teeter Dance", 100, false),
new("Pichu", "Teeter Dance", 25, true),
new("Pichu", "Wish", 100, false),
new("Pichu", "Wish", 25, true),
new("Bagon", "Iron Defense", 125, false),
new("Bagon", "Wish", 125, false),
new("Absol", "Spite", 125, false),
new("Absol", "Wish", 125, false),
new("Ralts", "Charm", 125, false),
new("Ralts", "Wish", 125, false),
};
public static uint Prev(uint seed, Algo algo) =>
Has(algo, Algo.BACDPIDIV) ||
Has(algo, Algo.PokeParkEggs) ||
Has(algo, Algo.WCEggs) ||
Has(algo, Algo.ForceAntiShiny) ? PrevGBA(seed) : PrevXD(seed);
Has(algo, Algo.ForceAntiShiny)
? PrevGBA(seed)
: PrevXD(seed);
public static uint Next(uint seed, Algo algo) =>
Has(algo, Algo.BACDPIDIV) ||
Has(algo, Algo.PokeParkEggs) ||
Has(algo, Algo.WCEggs) ||
Has(algo, Algo.ForceAntiShiny) ? NextGBA(seed) : NextXD(seed);
Has(algo, Algo.ForceAntiShiny)
? NextGBA(seed)
: NextXD(seed);
public static uint PrevXD(uint seed) => seed * 0xB9B33155u + 0xA170F641u;
@ -769,16 +913,13 @@ namespace Gen3EventLegality
public static string eReaderType(uint pid)
{
uint nature = pid % 25;
if (nature == 16 && pid % 256 < 128) // Mareep
return "Mareep";
if (nature == 11 && pid % 256 >= 128) // Scizor
return "Scizor";
if (nature == 22 && pid % 256 < 32) // Togepi
return "Togepi";
return "HACKED";
return (pid % 25) switch
{
16 when pid % 256 < 128 => "Mareep",
11 when pid % 256 >= 128 => "Scizor",
22 when pid % 256 < 32 => "Togepi",
_ => "HACKED"
};
}
public static string index2Nature(uint nature) =>
@ -814,7 +955,7 @@ namespace Gen3EventLegality
public static uint[] ParseStats(uint first, uint second)
{
uint[] stats = new uint[6];
var stats = new uint[6];
stats[0] = first & 0x1F; //HP
stats[1] = (first & 0x3E0) >> 0x5; //Attack
@ -826,5 +967,4 @@ namespace Gen3EventLegality
return stats;
}
}
}

7
global.json Normal file
View File

@ -0,0 +1,7 @@
{
"sdk": {
"version": "7.0.0",
"rollForward": "latestMajor",
"allowPrerelease": true
}
}