Compare commits

..

No commits in common. "master" and "v2" have entirely different histories.
master ... v2

3 changed files with 797 additions and 951 deletions

View File

@ -2,14 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>netcoreapp3.1</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> </PropertyGroup>
</Project> </Project>

View File

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

View File

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