diff --git a/README.md b/README.md index 3f92a3646..f7c8fb5cc 100755 --- a/README.md +++ b/README.md @@ -1,35 +1,30 @@ -Universal Pokemon Randomizer ZX by Ajarmar - -With significant contributions from darkeye, cleartonic - -Based on the Universal Pokemon Randomizer by Dabomstew - -# Info - -This fork was originally made to make some minor tweaks and fixes, but became a bit more ambitious since 2020. There are several new features and supported games (including 3DS games) compared to the original Universal Pokemon Randomizer. - -Have a look at the [release page](https://github.com/Ajarmar/universal-pokemon-randomizer-zx/releases) for changelogs and downloads. - -# Contributing - -If you want to contribute something to the codebase, we'd recommend creating an issue for it first (using the`Contribution Idea` template). This way, we can discuss whether or not it's a good fit for the randomizer before you put in the work to implement it. This is just to save you time in the event that we don't think it's something we want to accept. - -See [the Wiki Page](https://github.com/Ajarmar/universal-pokemon-randomizer-zx/wiki/Building-Universal-Pokemon-Randomizer-ZX) for setting up to build/test locally. - -### What is a good fit for the randomizer? - -In general, we try to make settings as universal as possible. This means that it preferably should work in as many games as possible, and also that it's something that many people will find useful. If the setting is very niche, it will mostly just bloat the GUI. - -If your idea is a change to an existing setting rather than a new setting, it needs to be well motivated. - -# Feature requests - -We do not take feature requests. - -# Bug reports - -If you encounter something that seems to be a bug, submit an issue using the `Bug Report` issue template. - -# Other problems - -If you have problems using the randomizer, it could be because of some problem with Java or your operating system. **If you have problems with starting the randomizer specifically, [read this page first before creating an issue.](https://github.com/Ajarmar/universal-pokemon-randomizer-zx/wiki/About-Java)** If that page does not solve your problem, submit an issue using the `Need Help` issue template. +FORK README (do not merge) + +A fork of the Universal Pokemon Randomizer intending to add the following features: + + * "Preserve Primary Type" (wild) + for wild pokemon, ensures the original pokemon's primary type is present in the randomized pokemon. This preserves most type theming, including "soft" theming like forests have Bug and Grass types, while still allowing variety. + + * "Preserve Type Themed Areas" (wild) + for wild pokemon. this is a fairly simple check: + if *all* wild pokemon in an area share a single type (whether primary, secondary, or mixed), then randomized pokemon will all have that type. + (for this purpose, "an area" means only a single type of encounter, so fishing, surfing, and tall grass would all be different areas.) + this would override "preserve primary type" if they are used together. + if they share a pair of types, chosen pokemon will have both (?). + *will* trigger if there is only one pokemon in the area. + usable with area 1-to-1, and maybe with random. + this is a checkbox that overrides other type theming. + + * "Preserve Primary Type" (trainer) + functions exactly the same as for wild pokemon + + * "Preserve Type Themed Trainers" (trainer) + functions the same as "Preserve Type Themed Areas", except the "area" is a single trainer. + also, if all the pokemon share a pair of types, it will choose the primary type of the trainer's first pokemon - unless it's Normal, in which case it chooses the secondary. + always triggers if the trainer has only one pokemon. + if the trainer is a gym or league trainer, they will be forced to their original theme even if they did not originally strictly follow it (e.g. Pryce using a Seel (Water-type) despite being an Ice trainer) + here, it's an option on the trainers dropdown. + + * "Local pokemon only" + restricts trainers to only using pokemon that can be caught in the wild, or their evolutionary relatives + can be used together with type restrictions diff --git a/src/com/dabomstew/pkrandom/Randomizer.java b/src/com/dabomstew/pkrandom/Randomizer.java index fe854c4c5..7ad80e32e 100644 --- a/src/com/dabomstew/pkrandom/Randomizer.java +++ b/src/com/dabomstew/pkrandom/Randomizer.java @@ -454,6 +454,7 @@ public int randomize(final String filename, final PrintStream log, long seed) { case MAINPLAYTHROUGH: case TYPE_THEMED: case TYPE_THEMED_ELITE4_GYMS: + case KEEP_THEMED: romHandler.randomizeTrainerPokes(settings); trainersChanged = true; break; diff --git a/src/com/dabomstew/pkrandom/Settings.java b/src/com/dabomstew/pkrandom/Settings.java index a8bd00f0c..d623d9c08 100644 --- a/src/com/dabomstew/pkrandom/Settings.java +++ b/src/com/dabomstew/pkrandom/Settings.java @@ -158,7 +158,7 @@ public enum MovesetsMod { private boolean evolutionMovesForAll; public enum TrainersMod { - UNCHANGED, RANDOM, DISTRIBUTED, MAINPLAYTHROUGH, TYPE_THEMED, TYPE_THEMED_ELITE4_GYMS + UNCHANGED, RANDOM, DISTRIBUTED, MAINPLAYTHROUGH, TYPE_THEMED, TYPE_THEMED_ELITE4_GYMS, KEEP_THEMED } private TrainersMod trainersMod = TrainersMod.UNCHANGED; @@ -408,7 +408,8 @@ public String toString() { trainersMod == TrainersMod.DISTRIBUTED, trainersMod == TrainersMod.MAINPLAYTHROUGH, trainersMod == TrainersMod.TYPE_THEMED, - trainersMod == TrainersMod.TYPE_THEMED_ELITE4_GYMS)); + trainersMod == TrainersMod.TYPE_THEMED_ELITE4_GYMS, + trainersMod == TrainersMod.KEEP_THEMED)); // 14 trainer pokemon force evolutions out.write((trainersForceFullyEvolved ? 0x80 : 0) | trainersForceFullyEvolvedLevel); @@ -678,7 +679,8 @@ public static Settings fromString(String settingsString) throws UnsupportedEncod 2, // DISTRIBUTED 3, // MAINPLAYTHROUGH 4, // TYPE_THEMED - 5 // TYPE_THEMED_ELITE4_GYMS + 5, // TYPE_THEMED_ELITE4_GYMS + 6 // KEEP_THEMED )); settings.setTrainersForceFullyEvolved(restoreState(data[14], 7)); diff --git a/src/com/dabomstew/pkrandom/constants/Gen1Constants.java b/src/com/dabomstew/pkrandom/constants/Gen1Constants.java index f84e4d13f..b06427f05 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen1Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen1Constants.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import com.dabomstew.pkrandom.pokemon.ItemList; @@ -337,6 +338,25 @@ public static void tagTrainersYellow(List trs) { tbc(trs, 31, 9, "GYM8"); } + public static final HashMap gymAndEliteThemes = setupGymAndEliteThemes(); + + private static HashMap setupGymAndEliteThemes() { + HashMap themeMap = new HashMap<>(); + themeMap.put("ELITE1", Type.ICE); //Lorelei + themeMap.put("ELITE2", Type.FIGHTING); //Bruno + themeMap.put("ELITE3", Type.GHOST); //Agatha + themeMap.put("ELITE4", Type.DRAGON); //Lance + themeMap.put("GYM1", Type.ROCK); //Brock + themeMap.put("GYM2", Type.WATER); //Misty + themeMap.put("GYM3", Type.ELECTRIC); //Lt. Surge + themeMap.put("GYM4", Type.GRASS); //Erika + themeMap.put("GYM5", Type.POISON); //Koga + themeMap.put("GYM6", Type.PSYCHIC); //Sabrina + themeMap.put("GYM7", Type.FIRE); //Blaine + themeMap.put("GYM8", Type.GROUND); //Giovanni + return themeMap; + } + private static void tbc(List allTrainers, int classNum, int number, String tag) { int currnum = -1; for (Trainer t : allTrainers) { diff --git a/src/com/dabomstew/pkrandom/constants/Gen2Constants.java b/src/com/dabomstew/pkrandom/constants/Gen2Constants.java index 86058ed9b..bdbd37ec4 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen2Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen2Constants.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import com.dabomstew.pkrandom.pokemon.ItemList; @@ -415,6 +416,34 @@ public static void crystalTags(List allTrainers) { tbc(allTrainers, 52, 10, "GYM14"); } + public static final HashMap gymAndEliteThemes = setupGymAndEliteThemes(); + + private static HashMap setupGymAndEliteThemes() { + HashMap themeMap = new HashMap<>(); + themeMap.put("CHAMPION", Type.DRAGON); //Lance + themeMap.put("ELITE1", Type.PSYCHIC); //Will + themeMap.put("ELITE2", Type.POISON); //Koga + themeMap.put("ELITE3", Type.FIGHTING); //Bruno + themeMap.put("ELITE4", Type.DARK); //Karen + themeMap.put("GYM1", Type.FLYING); //Falkner + themeMap.put("GYM2", Type.BUG); //Bugsy + themeMap.put("GYM3", Type.NORMAL); //Whitney + themeMap.put("GYM4", Type.GHOST); //Morty + themeMap.put("GYM5", Type.FIGHTING); //Chuck + themeMap.put("GYM6", Type.STEEL); //Jasmine + themeMap.put("GYM7", Type.ICE); //Pryce + themeMap.put("GYM8", Type.DRAGON); //Clair + themeMap.put("GYM9", Type.ROCK); //Brock + themeMap.put("GYM10", Type.WATER); //Misty + themeMap.put("GYM11", Type.ELECTRIC); //Lt. Surge + themeMap.put("GYM12", Type.GRASS); //Erika + themeMap.put("GYM13", Type.POISON); //Janine + themeMap.put("GYM14", Type.PSYCHIC); //Sabrina + themeMap.put("GYM15", Type.FIRE); //Blaine + //Blue has no specialty and thus is not included. + return themeMap; + } + private static void tbc(List allTrainers, int classNum, int number, String tag) { int currnum = -1; for (Trainer t : allTrainers) { diff --git a/src/com/dabomstew/pkrandom/constants/Gen3Constants.java b/src/com/dabomstew/pkrandom/constants/Gen3Constants.java index d390d19e2..bc8298ebd 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen3Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen3Constants.java @@ -814,6 +814,65 @@ private static void tag(List allTrainers, String tag, int... numbers) { } } + public static final HashMap gymAndEliteThemesRS = setupGymAndEliteThemesRS(); + + private static HashMap setupGymAndEliteThemesRS() { + HashMap themeMap = new HashMap<>(); + themeMap.put("CHAMPION", Type.STEEL); //Steven + themeMap.put("ELITE1", Type.DARK); //Sidney + themeMap.put("ELITE2", Type.GHOST); //Phoebe + themeMap.put("ELITE3", Type.ICE); //Glacia + themeMap.put("ELITE4", Type.DRAGON); //Drake + themeMap.put("GYM1", Type.ROCK); //Roxanne + themeMap.put("GYM2", Type.FIGHTING); //Brawly + themeMap.put("GYM3", Type.ELECTRIC); //Wattson + themeMap.put("GYM4", Type.FIRE); //Flannery + themeMap.put("GYM5", Type.NORMAL); //Norman + themeMap.put("GYM6", Type.FLYING); //Winona + themeMap.put("GYM7", Type.PSYCHIC); //Tate & Liza + themeMap.put("GYM8", Type.WATER); //Wallace + return themeMap; + } + + public static final HashMap gymAndEliteThemesEm = setupGymAndEliteThemesEm(); + + private static HashMap setupGymAndEliteThemesEm() { + HashMap themeMap = new HashMap<>(); + themeMap.put("CHAMPION", Type.WATER); //Wallace + themeMap.put("ELITE1", Type.DARK); //Sidney + themeMap.put("ELITE2", Type.GHOST); //Phoebe + themeMap.put("ELITE3", Type.ICE); //Glacia + themeMap.put("ELITE4", Type.DRAGON); //Drake + themeMap.put("GYM1", Type.ROCK); //Roxanne + themeMap.put("GYM2", Type.FIGHTING); //Brawly + themeMap.put("GYM3", Type.ELECTRIC); //Wattson + themeMap.put("GYM4", Type.FIRE); //Flannery + themeMap.put("GYM5", Type.NORMAL); //Norman + themeMap.put("GYM6", Type.FLYING); //Winona + themeMap.put("GYM7", Type.PSYCHIC); //Tate & Liza + themeMap.put("GYM8", Type.WATER); //Juan + return themeMap; + } + + public static final HashMap gymAndEliteThemesFRLG = setupGymAndEliteThemesFRLG(); + + private static HashMap setupGymAndEliteThemesFRLG() { + HashMap themeMap = new HashMap<>(); + themeMap.put("ELITE1", Type.ICE); //Lorelei + themeMap.put("ELITE2", Type.FIGHTING); //Bruno + themeMap.put("ELITE3", Type.GHOST); //Agatha + themeMap.put("ELITE4", Type.DRAGON); //Lance + themeMap.put("GYM1", Type.ROCK); //Brock + themeMap.put("GYM2", Type.WATER); //Misty + themeMap.put("GYM3", Type.ELECTRIC); //Lt. Surge + themeMap.put("GYM4", Type.GRASS); //Erika + themeMap.put("GYM5", Type.POISON); //Koga + themeMap.put("GYM6", Type.PSYCHIC); //Sabrina + themeMap.put("GYM7", Type.FIRE); //Blaine + themeMap.put("GYM8", Type.GROUND); //Giovanni + return themeMap; + } + public static void setMultiBattleStatusEm(List trs) { // 25 + 569: Double Battle with Team Aqua Grunts on Mt. Pyre // 105 + 237: Double Battle with Hex Maniac Patricia and Psychic Joshua diff --git a/src/com/dabomstew/pkrandom/constants/Gen4Constants.java b/src/com/dabomstew/pkrandom/constants/Gen4Constants.java index 59378959f..d03bdedcb 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen4Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen4Constants.java @@ -2004,6 +2004,54 @@ private static void tagFriendConsecutive2(List allTrainers, String tag, } + public static final HashMap gymAndEliteThemesDPPt = setupGymAndEliteThemesDPPt(); + + private static HashMap setupGymAndEliteThemesDPPt() { + HashMap themeMap = new HashMap<>(); + //no theme for Cynthia + themeMap.put("ELITE1", Type.BUG); //Aaron + themeMap.put("ELITE2", Type.GROUND); //Bertha + themeMap.put("ELITE3", Type.FIRE); //Flint + themeMap.put("ELITE4", Type.PSYCHIC); //Lucian + themeMap.put("GYM1", Type.ROCK); //Roark + themeMap.put("GYM2", Type.GRASS); //Gardenia + themeMap.put("GYM3", Type.FIGHTING); //Maylene + themeMap.put("GYM4", Type.WATER); //Wake + themeMap.put("GYM5", Type.GHOST); //Fantina + themeMap.put("GYM6", Type.STEEL); //Byron + themeMap.put("GYM7", Type.ICE); //Candice + themeMap.put("GYM8", Type.ELECTRIC); //Volkner + return themeMap; + } + + public static final HashMap gymAndEliteThemesHGSS = setupGymAndEliteThemesHGSS(); + + private static HashMap setupGymAndEliteThemesHGSS() { + HashMap themeMap = new HashMap<>(); + themeMap.put("CHAMPION", Type.DRAGON); //Lance + themeMap.put("ELITE1", Type.PSYCHIC); //Will + themeMap.put("ELITE2", Type.POISON); //Koga + themeMap.put("ELITE3", Type.FIGHTING); //Bruno + themeMap.put("ELITE4", Type.DARK); //Karen + themeMap.put("GYM1", Type.FLYING); //Falkner + themeMap.put("GYM2", Type.BUG); //Bugsy + themeMap.put("GYM3", Type.NORMAL); //Whitney + themeMap.put("GYM4", Type.GHOST); //Morty + themeMap.put("GYM5", Type.FIGHTING); //Chuck + themeMap.put("GYM6", Type.STEEL); //Jasmine + themeMap.put("GYM7", Type.ICE); //Pryce + themeMap.put("GYM8", Type.DRAGON); //Clair + themeMap.put("GYM9", Type.ROCK); //Brock + themeMap.put("GYM10", Type.WATER); //Misty + themeMap.put("GYM11", Type.ELECTRIC); //Lt. Surge + themeMap.put("GYM12", Type.GRASS); //Erika + themeMap.put("GYM13", Type.POISON); //Janine + themeMap.put("GYM14", Type.PSYCHIC); //Sabrina + themeMap.put("GYM15", Type.FIRE); //Blaine + //Blue has no specialty and thus is not included. + return themeMap; + } + public static void setMultiBattleStatusDP(List trs) { // 407 + 528: Commander Mars and Commander Jupiter Multi Battle on Spear Pillar // 414 + 415: Galactic Grunts in Jubilife City diff --git a/src/com/dabomstew/pkrandom/constants/Gen5Constants.java b/src/com/dabomstew/pkrandom/constants/Gen5Constants.java index 04fd53964..9068f4473 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen5Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen5Constants.java @@ -1895,6 +1895,51 @@ private static void tag(List allTrainers, String tag, int... numbers) { } } + public static final HashMap gymAndEliteThemesBW = setupGymAndEliteThemesBW(); + + private static HashMap setupGymAndEliteThemesBW() { + HashMap themeMap = new HashMap<>(); + //Alder has no theme + themeMap.put("ELITE1", Type.GHOST); //Shauntal + themeMap.put("ELITE2", Type.DARK); //Grimsley + themeMap.put("ELITE3", Type.PSYCHIC); //Caitlin + themeMap.put("ELITE4", Type.FIGHTING); //Marshal + themeMap.put("GYM1", Type.GRASS); //Cilan + themeMap.put("GYM2", Type.NORMAL); //Lenora + themeMap.put("GYM3", Type.BUG); //Burgh + themeMap.put("GYM4", Type.ELECTRIC); //Elesa + themeMap.put("GYM5", Type.GROUND); //Clay + themeMap.put("GYM6", Type.FLYING); //Skyla + themeMap.put("GYM7", Type.ICE); //Brycen + themeMap.put("GYM8", Type.DRAGON); //Iris + themeMap.put("GYM9", Type.FIRE); //Chili + themeMap.put("GYM10", Type.WATER); //Cress + themeMap.put("GYM11", Type.NORMAL); //Trio gym trainers + return themeMap; + } + + public static final HashMap gymAndEliteThemesBW2 = setupGymAndEliteThemesBW2(); + + private static HashMap setupGymAndEliteThemesBW2() { + HashMap themeMap = new HashMap<>(); + themeMap.put("CHAMPION", Type.DRAGON); //Iris + themeMap.put("ELITE1", Type.GHOST); //Shauntal + themeMap.put("ELITE2", Type.DARK); //Grimsley + themeMap.put("ELITE3", Type.PSYCHIC); //Caitlin + themeMap.put("ELITE4", Type.FIGHTING); //Marshal + themeMap.put("GYM1", Type.NORMAL); //Cheren + themeMap.put("GYM2", Type.POISON); //Roxie + themeMap.put("GYM3", Type.BUG); //Burgh + themeMap.put("GYM4", Type.ELECTRIC); //Elesa + themeMap.put("GYM5", Type.GROUND); //Clay + themeMap.put("GYM6", Type.FLYING); //Skyla + themeMap.put("GYM7", Type.DRAGON); //Drayden + themeMap.put("GYM8", Type.WATER); //Marlon + //The trio gym is no longer an official League gym, so I'm not including it. + //(Besides, their theming works as-is.) + return themeMap; + } + public static void setMultiBattleStatusBW(List trs) { // 62 + 63: Multi Battle with Team Plasma Grunts in Wellspring Cave w/ Cheren // 401 + 402: Double Battle with Preschooler Sarah and Preschooler Billy diff --git a/src/com/dabomstew/pkrandom/constants/Gen6Constants.java b/src/com/dabomstew/pkrandom/constants/Gen6Constants.java index 9416c4dd2..fe23338a7 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen6Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen6Constants.java @@ -1216,6 +1216,47 @@ private static void tag(List allTrainers, String tag, int... numbers) { } } + public static final HashMap gymAndEliteThemesXY = setupGymAndEliteThemesXY(); + + private static HashMap setupGymAndEliteThemesXY() { + HashMap themeMap = new HashMap<>(); + //Diantha has no theme + themeMap.put("ELITE1", Type.FIRE); //Malva + themeMap.put("ELITE2", Type.WATER); //Siebold + themeMap.put("ELITE3", Type.STEEL); //Wikstrom + themeMap.put("ELITE4", Type.DRAGON); //Drasna + themeMap.put("GYM1", Type.BUG); //Viola + themeMap.put("GYM2", Type.ROCK); //Grant + themeMap.put("GYM3", Type.FIGHTING); //Korrina + themeMap.put("GYM4", Type.GRASS); //Ramos + themeMap.put("GYM5", Type.ELECTRIC); //Clemont + themeMap.put("GYM6", Type.FAIRY); //Valerie + themeMap.put("GYM7", Type.PSYCHIC); //Olympia + themeMap.put("GYM8", Type.ICE); //Wulfric + return themeMap; + + } + + public static final HashMap gymAndEliteThemesORAS = setupGymAndEliteThemesORAS(); + + private static HashMap setupGymAndEliteThemesORAS() { + HashMap themeMap = new HashMap<>(); + themeMap.put("CHAMPION", Type.STEEL); //Steven + themeMap.put("ELITE1", Type.DARK); //Sidney + themeMap.put("ELITE2", Type.GHOST); //Phoebe + themeMap.put("ELITE3", Type.ICE); //Glacia + themeMap.put("ELITE4", Type.DRAGON); //Drake + themeMap.put("GYM1", Type.ROCK); //Roxanne + themeMap.put("GYM2", Type.FIGHTING); //Brawly + themeMap.put("GYM3", Type.ELECTRIC); //Wattson + themeMap.put("GYM4", Type.FIRE); //Flannery + themeMap.put("GYM5", Type.NORMAL); //Norman + themeMap.put("GYM6", Type.FLYING); //Winona + themeMap.put("GYM7", Type.PSYCHIC); //Tate & Liza + themeMap.put("GYM8", Type.WATER); //Wallace + return themeMap; + } + public static void setMultiBattleStatusXY(List trs) { // 108 + 111: Team Flare Grunts in Glittering Cave // 348 + 350: Team Flare Celosia and Bryony fight in Poké Ball Factory diff --git a/src/com/dabomstew/pkrandom/constants/Gen7Constants.java b/src/com/dabomstew/pkrandom/constants/Gen7Constants.java index b42237e79..af6cef839 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen7Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen7Constants.java @@ -1190,6 +1190,33 @@ private static void tag(List allTrainers, String tag, int... numbers) { } } + public static final HashMap gymAndEliteThemesSM = setupGymAndEliteThemesSM(); + + private static HashMap setupGymAndEliteThemesSM() { + HashMap themeMap = new HashMap<>(); + themeMap.put("ELITE1", Type.FIGHTING); //Hala + themeMap.put("ELITE2", Type.ROCK); //Olivia + themeMap.put("ELITE3", Type.DARK); //Nanu + themeMap.put("ELITE4", Type.GROUND); //Hapu + themeMap.put("ELITE5", Type.GHOST); //Acerola + themeMap.put("ELITE6", Type.FLYING); //Kahili + return themeMap; + } + + public static final HashMap gymAndEliteThemesUSUM = setupGymAndEliteThemesUSUM(); + + private static HashMap setupGymAndEliteThemesUSUM() { + HashMap themeMap = new HashMap<>(); + themeMap.put("ELITE1", Type.FIGHTING); //Hala + themeMap.put("ELITE2", Type.ROCK); //Olivia + themeMap.put("ELITE3", Type.DARK); //Nanu + themeMap.put("ELITE4", Type.GROUND); //Hapu + themeMap.put("ELITE5", Type.STEEL); //Molayne + themeMap.put("ELITE6", Type.GHOST); //Acerola + themeMap.put("ELITE7", Type.FLYING); //Kahili + return themeMap; + } + public static void setMultiBattleStatusSM(List trs) { // All Double Battles in Gen 7 are internally treated as a Multi Battle // 92 + 93: Rising Star Duo Justin and Lauren diff --git a/src/com/dabomstew/pkrandom/newgui/Bundle.properties b/src/com/dabomstew/pkrandom/newgui/Bundle.properties index 430241dec..0839b32e3 100644 --- a/src/com/dabomstew/pkrandom/newgui/Bundle.properties +++ b/src/com/dabomstew/pkrandom/newgui/Bundle.properties @@ -190,6 +190,8 @@ GUI.tpTypeThemedRadioButton.toolTipText=Pick a type for each trainer and g GUI.tpTypeThemedRadioButton.text=Type Themed GUI.tpMain5TypeThemedEliteFourGyms.toolTipText=Pick a type for each trainer and give them random Pokemon in that type.
Certain groups of trainers, such as the trainers in each gym, will all be given the same (random) type.
Only applies to Elite Four and Gym Trainers/Leaders. GUI.tpMain5TypeThemedEliteFourGyms.text=Type Themed (Elite Four/Gyms Only) +GUI.tpMain6KeepThemed.toolTipText=If a trainer originally had only Pokemon of a certain type, randomly chooses new pokemon of that type.
(Trainers with only one Pokemon are considered themed.)
All other trainers will have random Pokemon. +GUI.tpMain6KeepThemed.text=Keep Type Themed Trainers' Themes GUI.tpRivalCarriesStarterCheckBox.toolTipText=If this is selected, the rival will have their starter in every team they battle you with, evolved if it is far enough through.
The rest of their team will be chosen in the same way as every other trainer. GUI.tpRivalCarriesStarterCheckBox.text=Rival Carries Starter Through Game GUI.tpSimilarStrengthCheckBox.toolTipText=If this is checked, the random Pokemon that replaces each Pokemon will be of similar power to the original.
However, preserving other rules such as type theming has precedence over this, so weaker or stronger Pokemon will be chosen if there are no other Pokemon available. diff --git a/src/com/dabomstew/pkrandom/newgui/NewRandomizerGUI.java b/src/com/dabomstew/pkrandom/newgui/NewRandomizerGUI.java index 55af889b7..0c3886796 100644 --- a/src/com/dabomstew/pkrandom/newgui/NewRandomizerGUI.java +++ b/src/com/dabomstew/pkrandom/newgui/NewRandomizerGUI.java @@ -342,7 +342,7 @@ public class NewRandomizerGUI { private List trainerSettings = new ArrayList<>(); private List trainerSettingToolTips = new ArrayList<>(); private final int TRAINER_UNCHANGED = 0, TRAINER_RANDOM = 1, TRAINER_RANDOM_EVEN = 2, TRAINER_RANDOM_EVEN_MAIN = 3, - TRAINER_TYPE_THEMED = 4, TRAINER_TYPE_THEMED_ELITE4_GYMS = 5; + TRAINER_TYPE_THEMED = 4, TRAINER_TYPE_THEMED_ELITE4_GYMS = 5, TRAINER_KEEP_THEMED = 6; private BatchRandomizationSettings batchRandomizationSettings; @@ -1779,7 +1779,8 @@ private Settings createSettingsFromState(CustomNamesSet customNames) { settings.setTrainersMod(isTrainerSetting(TRAINER_UNCHANGED), isTrainerSetting(TRAINER_RANDOM), isTrainerSetting(TRAINER_RANDOM_EVEN), isTrainerSetting(TRAINER_RANDOM_EVEN_MAIN), - isTrainerSetting(TRAINER_TYPE_THEMED), isTrainerSetting(TRAINER_TYPE_THEMED_ELITE4_GYMS)); + isTrainerSetting(TRAINER_TYPE_THEMED), isTrainerSetting(TRAINER_TYPE_THEMED_ELITE4_GYMS), + isTrainerSetting(TRAINER_KEEP_THEMED)); settings.setTrainersUsePokemonOfSimilarStrength(tpSimilarStrengthCheckBox.isSelected()); settings.setRivalCarriesStarterThroughout(tpRivalCarriesStarterCheckBox.isSelected()); settings.setTrainersMatchTypingDistribution(tpWeightTypesCheckBox.isSelected()); diff --git a/src/com/dabomstew/pkrandom/pokemon/Pokemon.java b/src/com/dabomstew/pkrandom/pokemon/Pokemon.java index f29061ed9..580e208f0 100755 --- a/src/com/dabomstew/pkrandom/pokemon/Pokemon.java +++ b/src/com/dabomstew/pkrandom/pokemon/Pokemon.java @@ -47,6 +47,7 @@ public class Pokemon implements Comparable { public List realCosmeticFormNumbers = new ArrayList<>(); public Type primaryType, secondaryType; + public Type originalPrimaryType, originalSecondaryType; public int hp, attack, defense, spatk, spdef, speed, special; diff --git a/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java index b423a05cc..6cba093f9 100755 --- a/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java @@ -162,6 +162,10 @@ public void setPokemonPool(Settings settings) { } } for (Pokemon p : mainPokemonListInclFormes) { + //ok. that should ACTUALLY do all of them. + //...kinda sus though. am tempted to hit it on AllPokemonList. + p.originalPrimaryType = p.primaryType; + p.originalSecondaryType = p.secondaryType; if (p.isLegendary()) { onlyLegendaryListInclFormes.add(p); } else if (!ultraBeastList.contains(p)) { @@ -1662,6 +1666,7 @@ public void randomizeTrainerPokes(Settings settings) { int levelModifier = settings.isTrainersLevelModified() ? settings.getTrainersLevelModifier() : 0; boolean isTypeThemed = settings.getTrainersMod() == Settings.TrainersMod.TYPE_THEMED; boolean isTypeThemedEliteFourGymOnly = settings.getTrainersMod() == Settings.TrainersMod.TYPE_THEMED_ELITE4_GYMS; + boolean keepTypeThemes = settings.getTrainersMod() == Settings.TrainersMod.KEEP_THEMED; boolean distributionSetting = settings.getTrainersMod() == Settings.TrainersMod.DISTRIBUTED; boolean mainPlaythroughSetting = settings.getTrainersMod() == Settings.TrainersMod.MAINPLAYTHROUGH; boolean includeFormes = settings.isAllowTrainerAlternateFormes(); @@ -1709,7 +1714,7 @@ public void randomizeTrainerPokes(Settings settings) { // Type Themed related Map trainerTypes = new TreeMap<>(); Set usedUberTypes = new TreeSet<>(); - if (isTypeThemed || isTypeThemedEliteFourGymOnly) { + if (isTypeThemed || isTypeThemedEliteFourGymOnly || keepTypeThemes) { typeWeightings = new TreeMap<>(); totalTypeWeighting = 0; // Construct groupings for types @@ -1741,34 +1746,63 @@ public void randomizeTrainerPokes(Settings settings) { } } - // Give a type to each group - // Gym & elite types have to be unique - // So do uber types, including the type we pick for champion - Set usedGymTypes = new TreeSet<>(); - Set usedEliteTypes = new TreeSet<>(); - for (String group : groups.keySet()) { - List trainersInGroup = groups.get(group); - // Shuffle ordering within group to promote randomness - Collections.shuffle(trainersInGroup, random); - Type typeForGroup = pickType(weightByFrequency, noLegendaries, includeFormes); - if (group.startsWith("GYM")) { - while (usedGymTypes.contains(typeForGroup)) { - typeForGroup = pickType(weightByFrequency, noLegendaries, includeFormes); + + if(keepTypeThemes) { + Map originalThemes = getGymAndEliteTypeThemes(); + + //TODO: remove spading block + if(originalThemes == null) { + for (String group : groups.keySet()) { + logStream.print(group + ": "); + + List trainersInGroup = groups.get(group); + for(Trainer t : trainersInGroup) { + logStream.print(t.fullDisplayName + ", "); + } + logStream.println(); } - usedGymTypes.add(typeForGroup); - } - if (group.startsWith("ELITE")) { - while (usedEliteTypes.contains(typeForGroup)) { - typeForGroup = pickType(weightByFrequency, noLegendaries, includeFormes); + } else { + for (String group : groups.keySet()) { + if (!originalThemes.containsKey(group)) { + continue; + } + Type groupType = originalThemes.get(group); + List trainersInGroup = groups.get(group); + for (Trainer t : trainersInGroup) { + trainerTypes.put(t, groupType); + } } - usedEliteTypes.add(typeForGroup); - } - if (group.equals("CHAMPION")) { - usedUberTypes.add(typeForGroup); } + } else { + // Give a random type to each group + // Gym & elite types have to be unique + // So do uber types, including the type we pick for champion + Set usedGymTypes = new TreeSet<>(); + Set usedEliteTypes = new TreeSet<>(); + for (String group : groups.keySet()) { + List trainersInGroup = groups.get(group); + // Shuffle ordering within group to promote randomness + Collections.shuffle(trainersInGroup, random); + Type typeForGroup = pickType(weightByFrequency, noLegendaries, includeFormes); + if (group.startsWith("GYM")) { + while (usedGymTypes.contains(typeForGroup)) { + typeForGroup = pickType(weightByFrequency, noLegendaries, includeFormes); + } + usedGymTypes.add(typeForGroup); + } + if (group.startsWith("ELITE")) { + while (usedEliteTypes.contains(typeForGroup)) { + typeForGroup = pickType(weightByFrequency, noLegendaries, includeFormes); + } + usedEliteTypes.add(typeForGroup); + } + if (group.equals("CHAMPION")) { + usedUberTypes.add(typeForGroup); + } - for (Trainer t : trainersInGroup) { - trainerTypes.put(t, typeForGroup); + for (Trainer t : trainersInGroup) { + trainerTypes.put(t, typeForGroup); + } } } } @@ -1863,6 +1897,38 @@ public void randomizeTrainerPokes(Settings settings) { } } + if (keepTypeThemes) { + //determine if this trainer has a type theme + Pokemon poke = trainerPokemonList.get(0).pokemon; + Type primary = poke.originalPrimaryType; + Type secondary = poke.originalSecondaryType; + for (int i = 1; i < trainerPokemonList.size(); i++) { + poke = trainerPokemonList.get(i).pokemon; + if(secondary != null) { + if (secondary != poke.originalPrimaryType && secondary != poke.originalSecondaryType) { + secondary = null; + } + } + if (primary != poke.originalPrimaryType && primary != poke.originalSecondaryType) { + primary = secondary; + secondary = null; + } + if (primary == null) { + break; //no type is shared, no need to look at the remaining pokemon + } + } + if (primary != null) { + //we have a type theme! + if(primary == Type.NORMAL && secondary != null) { + //Bird override + //(Normal is less significant than other types, for example, Flying) + typeForTrainer = secondary; + } else { + typeForTrainer = primary; + } + } + } + for (TrainerPokemon tp : trainerPokemonList) { boolean swapThisMegaEvo = swapMegaEvos && tp.canMegaEvolve(); boolean wgAllowed = (!noEarlyWonderGuard) || tp.level >= 20; @@ -1957,6 +2023,8 @@ public void randomizeTrainerPokes(Settings settings) { this.setTrainers(currentTrainers, false); } + abstract protected Map getGymAndEliteTypeThemes(); + @Override public void randomizeTrainerHeldItems(Settings settings) { boolean giveToBossPokemon = settings.isRandomizeHeldItemsForBossTrainerPokemon(); diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen1RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen1RomHandler.java index d7c491cb6..dd564f393 100755 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen1RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen1RomHandler.java @@ -1336,6 +1336,11 @@ public List getEliteFourTrainers(boolean isChallengeMode) { return new ArrayList<>(); } + @Override + protected Map getGymAndEliteTypeThemes() { + return Gen1Constants.gymAndEliteThemes; + } + public void setTrainers(List trainerData, boolean doubleBattleMode) { int traineroffset = romEntry.getValue("TrainerDataTableOffset"); int traineramount = Gen1Constants.trainerClassCount; diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen2RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen2RomHandler.java index d9e3a935c..e311ea836 100755 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen2RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen2RomHandler.java @@ -1223,6 +1223,11 @@ public List getEliteFourTrainers(boolean isChallengeMode) { return new ArrayList<>(); } + @Override + protected Map getGymAndEliteTypeThemes() { + return Gen2Constants.gymAndEliteThemes; + } + @Override public void setTrainers(List trainerData, boolean doubleBattleMode) { int traineroffset = romEntry.getValue("TrainerDataTableOffset"); diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java index 2de235433..1df8a4f66 100755 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java @@ -1949,6 +1949,16 @@ public List getEliteFourTrainers(boolean isChallengeMode) { return Arrays.stream(romEntry.arrayEntries.get("EliteFourIndices")).boxed().collect(Collectors.toList()); } + @Override + protected Map getGymAndEliteTypeThemes() { + if(romEntry.romType == Gen3Constants.RomType_FRLG) { + return Gen3Constants.gymAndEliteThemesFRLG; + } else if(romEntry.romType == Gen3Constants.RomType_Em) { + return Gen3Constants.gymAndEliteThemesEm; + } else { + return Gen3Constants.gymAndEliteThemesRS; + } + } @Override public void setTrainers(List trainerData, boolean doubleBattleMode) { diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java index f1605a49f..6dd2aa67e 100755 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java @@ -2900,6 +2900,15 @@ public List getEliteFourTrainers(boolean isChallengeMode) { return Arrays.stream(romEntry.arrayEntries.get("EliteFourIndices")).boxed().collect(Collectors.toList()); } + @Override + protected Map getGymAndEliteTypeThemes() { + if(romEntry.romType == Gen4Constants.Type_HGSS) { + return Gen4Constants.gymAndEliteThemesHGSS; + } else { + return Gen4Constants.gymAndEliteThemesDPPt; + } + } + @Override public List getEvolutionItems() { return Gen4Constants.evolutionItems; diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java index dc06d2114..535b97a76 100755 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java @@ -1507,6 +1507,14 @@ public List getEliteFourTrainers(boolean isChallengeMode) { } } + @Override + protected Map getGymAndEliteTypeThemes() { + if(romEntry.romType == Gen5Constants.Type_BW) { + return Gen5Constants.gymAndEliteThemesBW; + } else { + return Gen5Constants.gymAndEliteThemesBW2; + } + } @Override public List getEvolutionItems() { diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java index 8e11df707..ec86accb5 100644 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java @@ -2001,6 +2001,15 @@ public List getEliteFourTrainers(boolean isChallengeMode) { return Arrays.stream(romEntry.arrayEntries.get("EliteFourIndices")).boxed().collect(Collectors.toList()); } + @Override + protected Map getGymAndEliteTypeThemes() { + if(romEntry.romType == Gen6Constants.Type_XY) { + return Gen6Constants.gymAndEliteThemesXY; + } else { + return Gen6Constants.gymAndEliteThemesORAS; + } + } + @Override public List getEvolutionItems() { return Gen6Constants.evolutionItems; diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java index 42aa02c40..89af7b6a8 100644 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java @@ -1714,6 +1714,15 @@ public List getEliteFourTrainers(boolean isChallengeMode) { return Arrays.stream(romEntry.arrayEntries.get("EliteFourIndices")).boxed().collect(Collectors.toList()); } + @Override + protected Map getGymAndEliteTypeThemes() { + if(romEntry.romType == Gen7Constants.Type_SM) { + return Gen7Constants.gymAndEliteThemesSM; + } else { + return Gen7Constants.gymAndEliteThemesUSUM; + } + } + @Override public void setTrainers(List trainerData, boolean doubleBattleMode) { Iterator allTrainers = trainerData.iterator();