diff --git a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/SaveWriterTest.cs b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/SaveWriterTest.cs index 59fda37..cd06a4e 100644 --- a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/SaveWriterTest.cs +++ b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/SaveWriterTest.cs @@ -113,8 +113,31 @@ public void TestShinyCorrect() Assert.IsTrue(isShiny); + } + [TestMethod] + public void TestNotShinyCorrect() + { + SaveWriter sw = new SaveWriter(testConstants.JOHTO_PLUS_SOUL_SILVER_SAVE); + + EggCreator ec = EggCreator.decodeJSON(testConstants.BLANK_GEN4_MAREEP_VALID, true); + + sw.addEgg(ec, 1); + + // get egg at box index 1 + IList boxData = sw.getBox(); + + bool isShiny = boxData[1].IsShiny; + + Assert.IsFalse(isShiny); + + + } + + + + } } \ No newline at end of file diff --git a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/LegendaryTrio.json b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/LegendaryTrio.json index 0ca5c31..1733ea3 100644 --- a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/LegendaryTrio.json +++ b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/LegendaryTrio.json @@ -13,7 +13,8 @@ "EV": [ 252, 252, 0, 0, 0, 0 ], "moves": [ 425, 262 ], "movespp": [ 30, 40 ], - "isShiny": true + "isShiny": true, + "generation": 4 }, { "dexNumber": 484, @@ -29,7 +30,8 @@ "EV": [ 252, 252, 0, 0, 0, 0 ], "moves": [ 425, 262 ], "movespp": [ 30, 40 ], - "isShiny": true + "isShiny": true, + "generation": 4 }, { "dexNumber": 487, @@ -45,6 +47,7 @@ "EV": [ 252, 252, 0, 0, 0, 0 ], "moves": [ 425, 262 ], "movespp": [ 30, 40 ], - "isShiny": true + "isShiny": true, + "generation": 4 } ] \ No newline at end of file diff --git a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/Mareep.json b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/Mareep.json index 9594ba2..87d8a98 100644 --- a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/Mareep.json +++ b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/Mareep.json @@ -12,5 +12,6 @@ "moves": [ 344, 1, 124, 26 ], "movespp": [ 0, 0, 0, 0 ], "heldItem": 135, - "isShiny": false + "isShiny": false, + "generation": 4 } \ No newline at end of file diff --git a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/MareepShiny.json b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/MareepShiny.json index 70fa354..264d1fc 100644 --- a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/MareepShiny.json +++ b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/testSources/MareepShiny.json @@ -12,5 +12,6 @@ "moves": [ 344, 1, 124, 26 ], "movespp": [ 0, 0, 0, 0 ], "heldItem": 135, - "isShiny": true + "isShiny": true, + "generation": 4 } \ No newline at end of file diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs index 6dae9be..97fbede 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs @@ -10,6 +10,7 @@ using PKHeX.Core; using Newtonsoft.Json; using System.Text.RegularExpressions; +using System.Security.Cryptography; namespace pkhexEgglocke { @@ -20,71 +21,175 @@ namespace pkhexEgglocke // Parameters // These parameters mostly allow you to set rules around what user submissions you'd like to include (ex. allow user-supplied IVs) - + internal class EggCreator { // TODO: refactor to get/set - protected bool allowUserIVs => true; - protected bool allowUserShiny => true; - protected bool allowUser => true; + protected bool allowUserIVs { get; set; } = true; + protected bool allowUserShiny { get; set; } = true; + protected bool allowUser { get; set; } = true; + + public int generation { get; set; } = 4; + // Egg Parameters that are always true - public bool IsEgg = true; - public ushort EggLocationDP = Locations.Daycare4; - public byte MetLevel = 0; + public bool IsEgg { get; set; } = true; + public ushort EggLocationDP { get; set; } = Locations.Daycare4; + public byte MetLevel { get; set; } = 0; //Other constant fields - public int language = (int)LanguageID.English; + public int language { get; set; } = (int)LanguageID.English; // Mutable fields - public byte ball = (int)Ball.Dive; + public byte ball { get; set; } = (int)Ball.Dive; - public ushort dexNumber = 1; - public int Language = 1; - public int Ability = 2; - public Nature Nature = Nature.Adamant; - public int heldItem = 0; + public ushort dexNumber { get; set; } = 1; + public int Language { get; set; } = 1; + public int Ability { get; set; } = 2; + public Nature Nature { get; set; } = Nature.Adamant; + public int heldItem { get; set; } = 0; //Misc creator stuff - public string OT = "Default"; - public byte OTGender = (int)Gender.Female; - public string nickname = "Hello"; + public string OT { get; set; } = "Default"; + public byte OTGender { get; set; } = (int)Gender.Female; + public string nickname { get; set; } = "Hello"; - public int[] IV = [31, 31, 31, 31, 31, 31]; - public int[] EV = [0, 0, 0, 0, 0, 0]; + public int[] IV { get; set; } = new int[] { 31, 31, 31, 31, 31, 31 }; + public int[] EV { get; set; } = new int[] { 0, 0, 0, 0, 0, 0 }; - public ushort [] moves = {425, 262 }; - public ushort[] movespp = { 30, 40 }; + public ushort[] moves { get; set; } = new ushort[] { 425, 262 }; + public ushort[] movespp { get; set; } = new ushort[] { 30, 40 }; - public bool isShiny = true; + public bool isShiny { get; set; } = true; - public EggCreator(byte ball, ushort dexNumber, int language, int ability, Nature Nature, string OT, byte OTGender, string nickname, int[] IV, int[] EV, ushort[] moves, ushort[] movespp, int HeldItem, bool isShiny) { - - this.ball = ball; - this.dexNumber = dexNumber; - this.language = language; - this.Ability = ability; - this.Nature = Nature; - this.OT = OT; - this.OTGender = OTGender; - this.nickname = nickname; - this.IV = IV; - this.EV = EV; - this.moves = moves; - this.movespp = movespp; - this.heldItem = HeldItem; - this.isShiny = isShiny; + public EggCreator() + { } + internal void MakeShiny(PK4 pokemon) + { + // Get IDs + ushort trainer_id = pokemon.TID16; + ushort secret_id = pokemon.SID16; + uint pid = ShinyUtil.GetShinyPID(trainer_id, secret_id, pokemon.PID, 0); + + pokemon.PID = pid; + + + } + + public PK4 exportPK4(uint trainerID, uint secretID) { + + // create default + PK4 mew = new PK4 + { + TrainerTID7 = trainerID, + TrainerSID7 = secretID, + IsEgg = true, + MetLevel = 1, + Ball = 4, + Species = 1, + Nickname = "Egg", + Language = 1, + OriginalTrainerName = "PKHeX", + OriginalTrainerGender = 0, + HeldItem = 0, + Ability = 0, + Nature = 0, + Move1 = 0, + Move1_PP = 0, + Move2 = 0, + Move2_PP = 0, + Move3 = 0, + Move3_PP = 0, + Move4 = 0, + Move4_PP = 0, + IVs = new int[] { 31, 31, 31, 31, 31, 31 } + }; + + // Set the trainer ID according to the save file + mew.TrainerTID7 = trainerID; + mew.TrainerSID7 = secretID; + + // Standard Egg attributes + mew.IsEgg = this.IsEgg; + mew.EggLocationDP = this.EggLocationDP; + mew.MetLevel = this.MetLevel; + mew.Ball = this.ball; + + + // Pokemon Info + mew.Species = this.dexNumber; + mew.Nickname = this.nickname; + mew.Language = this.language; + mew.OriginalTrainerName = this.OT; + mew.OriginalTrainerGender = this.OTGender; + + mew.HeldItem = this.heldItem; + mew.Version = GameVersion.HG; + + + + mew.Ability = this.Ability; + + Console.WriteLine(this.moves); + // Moveset + + // Based on number of moves, set the moves + for (int i = 0; i < this.moves.Length; i++) + { + mew.SetMove(i, this.moves[i]); + } + + mew.IVs = this.IV; + + + + // Logic to confirm that the PID matches the nature and shininess + for (; !((Nature)(mew.PID % 25) == this.Nature) && (this.isShiny == this.isShiny);) + { + // Attempt to set the nature + mew.SetPIDNature(this.Nature); + + if (this.isShiny) + { + MakeShiny(mew); + } + + } - public static EggCreator decodeJSON(string filepath, bool is_filepath) { + Console.WriteLine("Nature after setting"); + Console.WriteLine(mew.Nature); + +#if DEBUG + // Check legality of the pokemon + LegalityAnalysis legalitychecker = new LegalityAnalysis(mew); + + if (legalitychecker.Valid) + { + Console.WriteLine("Legal Egg created!"); + } + else + { + Console.WriteLine("Illegal Egg Created!"); + } +#endif + + return mew; + + } + + + + public static EggCreator decodeJSON(string filepath, bool is_filepath) + { /// /// decodeJSON: Decodes a JSON object into a PokemonCreator object /// @@ -98,23 +203,26 @@ public static EggCreator decodeJSON(string filepath, bool is_filepath) { { json = File.ReadAllText(filepath); } - else { + else + { json = filepath; } - - + + dynamic newObject = JsonConvert.DeserializeObject(json); Console.WriteLine("Successfully deserialized JSON!"); Console.WriteLine("Nature: "); - Console.WriteLine((byte) newObject.nature.Value); + Console.WriteLine((byte)newObject.nature.Value); - Nature nature = natureEnumGrab((byte) newObject.nature.Value); + Nature nature = natureEnumGrab((byte)newObject.nature.Value); Console.WriteLine(nature); + int generation = (int)newObject.generation; + int[] IV = newObject.IV.ToObject(); int[] EV = newObject.EV.ToObject(); @@ -123,37 +231,38 @@ public static EggCreator decodeJSON(string filepath, bool is_filepath) { bool isShiny = newObject.isShiny; - byte ball = (byte) newObject.ball; - ushort dexNumber = (ushort) newObject.dexNumber; - int language = (int) newObject.language; - int ability = (int) newObject.ability; - int heldItem = (int) newObject.heldItem; + byte ball = (byte)newObject.ball; + ushort dexNumber = (ushort)newObject.dexNumber; + int language = (int)newObject.language; + int ability = (int)newObject.ability; + int heldItem = (int)newObject.heldItem; string OT = newObject.OT; - byte OTGender = (byte) newObject.OTGender; + byte OTGender = (byte)newObject.OTGender; string nickname = newObject.nickname; // Print EggCreator args - return new EggCreator( - ball, - dexNumber, - language, - ability, - nature, - OT, - OTGender, - nickname, - IV, - EV, - convertIntArrayViaCast(moves), - convertIntArrayViaCast(movespp), - heldItem, - isShiny - - ); - + return new EggCreator() + { + ball = ball, + dexNumber = dexNumber, + language = language, + Ability = ability, + Nature = nature, + OT = OT, + OTGender = OTGender, + nickname = nickname, + IV = IV, + EV = EV, + moves = convertIntArrayViaCast(moves), + movespp = convertIntArrayViaCast(movespp), + heldItem = heldItem, + isShiny = isShiny, + generation = generation + }; + } public static Nature natureEnumGrab(byte value) @@ -173,7 +282,7 @@ public static ushort[] convertIntArrayViaCast(int[] array) ushort[] result = new ushort[array.Length]; for (int i = 0; i < result.Length; i++) { - result[i] = (ushort) array[i]; + result[i] = (ushort)array[i]; } return result; diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs index ff4c27e..57eca59 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs @@ -50,6 +50,13 @@ public string getGameSavPath(uint gamecode) { return @"support/Blank_Pearl.sav"; case 12: return @"support/Blank_Platinum.sav"; + case 20: + return @"support/Blank_White.sav"; + case 21: + return @"support/Blank_Black.sav"; + case 23: + return @"support/Blank_Black2.sav"; + default: throw new Exception("Invalid game code"); diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs index 0268ec6..e24fb58 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs @@ -69,17 +69,6 @@ public void massAddEggs(string JSONPath) { } - } - - internal void MakeShiny(PK4 pokemon) { - // Get IDs - ushort trainer_id = pokemon.TID16; - ushort secret_id = pokemon.SID16; - uint pid = ShinyUtil.GetShinyPID(trainer_id, secret_id, pokemon.PID, 0); - - pokemon.PID = pid; - - } internal static bool IsShinyPID(uint pid, uint trainer_id, uint secret_id) { @@ -130,87 +119,90 @@ private static PK4 createDefaultEgg(uint tid, uint sid) { } - public void addEgg( EggCreator pokemon, int boxIndex) { - - - - // hacky start - hardcoded to gen 4 pokemon - PK4 mew = createDefaultEgg(this.currentSave.TrainerTID7, this.currentSave.TrainerSID7); + private PK5 gen5Conversions(EggCreator pokemon, int originGeneration) { - // Set the trainer ID according to the save file - mew.TrainerTID7 = this.currentSave.TrainerTID7; - mew.TrainerSID7 = this.currentSave.TrainerSID7; + switch (originGeneration) + { + case 4: + PK4 pk4 = pokemon.exportPK4(this.currentSave.TrainerTID7, this.currentSave.TrainerSID7); + return pk4.ConvertToPK5(); - // Standard Egg attributes - mew.IsEgg = pokemon.IsEgg; - mew.EggLocationDP = pokemon.EggLocationDP; - mew.MetLevel = pokemon.MetLevel; - mew.Ball = pokemon.ball; + default: + throw new Exception("Unsupported origin generation (" + originGeneration + ")"); + } - - // Pokemon Info - mew.Species = pokemon.dexNumber; - mew.Nickname = pokemon.nickname; - mew.Language = pokemon.language; - mew.OriginalTrainerName = pokemon.OT; - mew.OriginalTrainerGender = pokemon.OTGender; - - mew.HeldItem = pokemon.heldItem; - mew.Version = GameVersion.HG; - + } + private PK6 gen6Conversions(EggCreator pokemon, int originGeneration) { - mew.Ability = pokemon.Ability; + switch (originGeneration) + { - Console.WriteLine(pokemon.moves); - // Moveset + //case 3: + // PK3 pk3 = pokemon.exportPK3(this.currentSave.TrainerTID7, this.currentSave.TrainerSID7); + // PK4 pk4 = pk3.ConvertToPK4(); + // return pk4.ConvertToPK5().ConvertToPK6(); + + case 4: + PK4 gen4_pk4 = pokemon.exportPK4(this.currentSave.TrainerTID7, this.currentSave.TrainerSID7); + PK5 gen4_pk5 = gen4_pk4.ConvertToPK5(); + return gen4_pk5.ConvertToPK6(); + //case 5: + // PK5 gen5_pk5 = pokemon.exportPK5(this.currentSave.TrainerTID7, this.currentSave.TrainerSID7); + // return gen5_pk5.ConvertToPK6(); + default: + throw new Exception("Unsupported origin generation (" + originGeneration + ")"); - // Based on number of moves, set the moves - for (int i = 0; i < pokemon.moves.Length; i++) { - mew.SetMove(i, pokemon.moves[i]); } - mew.IVs = pokemon.IV; - - var box = this.currentSave.BoxData; + } - // Logic to confirm that the PID matches the nature and shininess - for (; !( (Nature)(mew.PID % 25) == pokemon.Nature) && (pokemon.isShiny == pokemon.isShiny); ) - { - // Attempt to set the nature - mew.SetPIDNature(pokemon.Nature); - MakeShiny(mew); - } + public void addEgg( EggCreator pokemon, int boxIndex) { + var box = this.currentSave.BoxData; + // check game version + byte saveFileGeneration = this.currentSave.Generation; - Console.WriteLine("Nature after setting"); - Console.WriteLine(mew.Nature); -#if DEBUG - // Check legality of the pokemon - LegalityAnalysis legalitychecker = new LegalityAnalysis(mew); - - if (legalitychecker.Valid) - { - Console.WriteLine("Legal Egg created!"); - } - else + if (pokemon.generation != saveFileGeneration) { - Console.WriteLine("Illegal Egg Created!"); + // run conversion scripts here for non-native pokemon + Console.WriteLine("Converting from generation " + pokemon.generation + " to generation " + saveFileGeneration); + PKM convertedPokemon; + switch(saveFileGeneration) { + case 5: + convertedPokemon = gen5Conversions(pokemon, pokemon.generation); + break; + + case 6: + convertedPokemon = gen6Conversions(pokemon, pokemon.generation); + break; + default: + throw new Exception("Unsupported save file generation (Generation " + saveFileGeneration + ")"); + } + + box[boxIndex] = convertedPokemon; } -#endif + else { + // Native pokemon generation - box[boxIndex] = mew; + switch (saveFileGeneration) { + case 4: + box[boxIndex] = pokemon.exportPK4(this.currentSave.TrainerTID7, this.currentSave.TrainerSID7); + break; + default: + throw new Exception("Unsupported save file generation (Generation " + saveFileGeneration + ")"); - // update box - this.currentSave.BoxData = box; + } + + } - // this.currentSave.AddBoxData( , 1, 1 ); + this.currentSave.BoxData = box; diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj b/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj index 109a0bd..0640dac 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj @@ -20,6 +20,9 @@ + + Always + Always diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/support/Blank_Black2.sav b/pkhex/pkhex-egglocke/pkhex-egglocke/support/Blank_Black2.sav new file mode 100644 index 0000000..38496c6 Binary files /dev/null and b/pkhex/pkhex-egglocke/pkhex-egglocke/support/Blank_Black2.sav differ diff --git a/server/pokepoll/views.py b/server/pokepoll/views.py index fcaa10a..e545276 100644 --- a/server/pokepoll/views.py +++ b/server/pokepoll/views.py @@ -27,6 +27,7 @@ "Pokemon Diamond": 10, "Pokemon Pearl": 11, "Pokemon Platinum": 12, + "Pokemon Black 2": 23, } @require_GET @@ -200,6 +201,7 @@ def saveGenView(request): "movespp": [0] * len(egg.pokemon_moves), "heldItem": egg.pokemon_held_item, "isShiny": egg.pokemon_is_shiny, + "generation": 4, })