Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep themed trainers #702

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
65 changes: 30 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions src/com/dabomstew/pkrandom/Randomizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 5 additions & 3 deletions src/com/dabomstew/pkrandom/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down
20 changes: 20 additions & 0 deletions src/com/dabomstew/pkrandom/constants/Gen1Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -337,6 +338,25 @@ public static void tagTrainersYellow(List<Trainer> trs) {
tbc(trs, 31, 9, "GYM8");
}

public static final HashMap<String, Type> gymAndEliteThemes = setupGymAndEliteThemes();

private static HashMap<String, Type> setupGymAndEliteThemes() {
HashMap<String, Type> 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<Trainer> allTrainers, int classNum, int number, String tag) {
int currnum = -1;
for (Trainer t : allTrainers) {
Expand Down
29 changes: 29 additions & 0 deletions src/com/dabomstew/pkrandom/constants/Gen2Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -415,6 +416,34 @@ public static void crystalTags(List<Trainer> allTrainers) {
tbc(allTrainers, 52, 10, "GYM14");
}

public static final HashMap<String, Type> gymAndEliteThemes = setupGymAndEliteThemes();

private static HashMap<String, Type> setupGymAndEliteThemes() {
HashMap<String, Type> 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<Trainer> allTrainers, int classNum, int number, String tag) {
int currnum = -1;
for (Trainer t : allTrainers) {
Expand Down
59 changes: 59 additions & 0 deletions src/com/dabomstew/pkrandom/constants/Gen3Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,65 @@ private static void tag(List<Trainer> allTrainers, String tag, int... numbers) {
}
}

public static final HashMap<String, Type> gymAndEliteThemesRS = setupGymAndEliteThemesRS();

private static HashMap<String, Type> setupGymAndEliteThemesRS() {
HashMap<String, Type> 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<String, Type> gymAndEliteThemesEm = setupGymAndEliteThemesEm();

private static HashMap<String, Type> setupGymAndEliteThemesEm() {
HashMap<String, Type> 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<String, Type> gymAndEliteThemesFRLG = setupGymAndEliteThemesFRLG();

private static HashMap<String, Type> setupGymAndEliteThemesFRLG() {
HashMap<String, Type> 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<Trainer> trs) {
// 25 + 569: Double Battle with Team Aqua Grunts on Mt. Pyre
// 105 + 237: Double Battle with Hex Maniac Patricia and Psychic Joshua
Expand Down
48 changes: 48 additions & 0 deletions src/com/dabomstew/pkrandom/constants/Gen4Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,54 @@ private static void tagFriendConsecutive2(List<Trainer> allTrainers, String tag,

}

public static final HashMap<String, Type> gymAndEliteThemesDPPt = setupGymAndEliteThemesDPPt();

private static HashMap<String, Type> setupGymAndEliteThemesDPPt() {
HashMap<String, Type> 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<String, Type> gymAndEliteThemesHGSS = setupGymAndEliteThemesHGSS();

private static HashMap<String, Type> setupGymAndEliteThemesHGSS() {
HashMap<String, Type> 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<Trainer> trs) {
// 407 + 528: Commander Mars and Commander Jupiter Multi Battle on Spear Pillar
// 414 + 415: Galactic Grunts in Jubilife City
Expand Down
45 changes: 45 additions & 0 deletions src/com/dabomstew/pkrandom/constants/Gen5Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,51 @@ private static void tag(List<Trainer> allTrainers, String tag, int... numbers) {
}
}

public static final HashMap<String, Type> gymAndEliteThemesBW = setupGymAndEliteThemesBW();

private static HashMap<String, Type> setupGymAndEliteThemesBW() {
HashMap<String, Type> 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<String, Type> gymAndEliteThemesBW2 = setupGymAndEliteThemesBW2();

private static HashMap<String, Type> setupGymAndEliteThemesBW2() {
HashMap<String, Type> 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<Trainer> trs) {
// 62 + 63: Multi Battle with Team Plasma Grunts in Wellspring Cave w/ Cheren
// 401 + 402: Double Battle with Preschooler Sarah and Preschooler Billy
Expand Down
Loading