summaryrefslogtreecommitdiff
path: root/src/com/sneed
diff options
context:
space:
mode:
authortom-overton <tom.overton@outlook.com>2022-06-03 23:14:41 -0700
committerrafa_99 <raroma09@gmail.com>2022-06-09 15:58:46 +0100
commit810b9dc324f0069c4db4e2d5866976b5a92bae5c (patch)
tree9f7afc9c4f231a48d192394027f66304bf689fa0 /src/com/sneed
parent5047d3453c0dfafe9fd1ce90ede935413c6d6a68 (diff)
Fix issue where Type-Themed Trainers and Force Fully Evolved could cause Pokemon of the wrong type to appear
Diffstat (limited to 'src/com/sneed')
-rw-r--r--src/com/sneed/pkrandom/Randomizer.java8
-rw-r--r--src/com/sneed/pkrandom/constants/GlobalConstants.java2
-rwxr-xr-xsrc/com/sneed/pkrandom/pokemon/Trainer.java11
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/AbstractRomHandler.java33
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen1RomHandler.java3
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen2RomHandler.java3
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen3RomHandler.java1
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java4
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java2
-rw-r--r--src/com/sneed/pkrandom/romhandlers/Gen6RomHandler.java2
-rw-r--r--src/com/sneed/pkrandom/romhandlers/Gen7RomHandler.java2
11 files changed, 49 insertions, 22 deletions
diff --git a/src/com/sneed/pkrandom/Randomizer.java b/src/com/sneed/pkrandom/Randomizer.java
index 98ff249..41dc933 100644
--- a/src/com/sneed/pkrandom/Randomizer.java
+++ b/src/com/sneed/pkrandom/Randomizer.java
@@ -1120,11 +1120,9 @@ public class Randomizer {
log.println("--Trainers Pokemon--");
List<Trainer> trainers = romHandler.getTrainers();
- int idx = 0;
for (Trainer t : trainers) {
- idx++;
- log.print("#" + idx + " ");
- String originalTrainerName = originalTrainerNames.get(idx);
+ log.print("#" + t.index + " ");
+ String originalTrainerName = originalTrainerNames.get(t.index);
String currentTrainerName = "";
if (t.fullDisplayName != null) {
currentTrainerName = t.fullDisplayName;
@@ -1138,7 +1136,7 @@ public class Randomizer {
log.printf("(%s)", currentTrainerName);
}
}
- if (t.offset != idx && t.offset != 0) {
+ if (t.offset != 0) {
log.printf("@%X", t.offset);
}
log.print(" - ");
diff --git a/src/com/sneed/pkrandom/constants/GlobalConstants.java b/src/com/sneed/pkrandom/constants/GlobalConstants.java
index 1ac0b90..b1506be 100644
--- a/src/com/sneed/pkrandom/constants/GlobalConstants.java
+++ b/src/com/sneed/pkrandom/constants/GlobalConstants.java
@@ -221,4 +221,6 @@ public class GlobalConstants {
public static final int HIGHEST_POKEMON_GEN = 8;
+ // Eevee has 8 potential evolutions
+ public static final int LARGEST_NUMBER_OF_SPLIT_EVOS = 8;
}
diff --git a/src/com/sneed/pkrandom/pokemon/Trainer.java b/src/com/sneed/pkrandom/pokemon/Trainer.java
index 286e5e9..a6a6a8a 100755
--- a/src/com/sneed/pkrandom/pokemon/Trainer.java
+++ b/src/com/sneed/pkrandom/pokemon/Trainer.java
@@ -29,6 +29,7 @@ import java.util.List;
public class Trainer implements Comparable<Trainer> {
public int offset;
+ public int index;
public List<TrainerPokemon> pokemon = new ArrayList<>();
public String tag;
public boolean importantTrainer;
@@ -50,7 +51,9 @@ public class Trainer implements Comparable<Trainer> {
if (trainerclass != 0) {
sb.append("(").append(trainerclass).append(") - ");
}
- sb.append(String.format("%x", offset));
+ if (offset > 0) {
+ sb.append(String.format("%x", offset));
+ }
sb.append(" => ");
boolean first = true;
for (TrainerPokemon p : pokemon) {
@@ -71,7 +74,7 @@ public class Trainer implements Comparable<Trainer> {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + offset;
+ result = prime * result + index;
return result;
}
@@ -84,12 +87,12 @@ public class Trainer implements Comparable<Trainer> {
if (getClass() != obj.getClass())
return false;
Trainer other = (Trainer) obj;
- return offset == other.offset;
+ return index == other.index;
}
@Override
public int compareTo(Trainer o) {
- return offset - o.offset;
+ return index - o.index;
}
public boolean isBoss() {
diff --git a/src/com/sneed/pkrandom/romhandlers/AbstractRomHandler.java b/src/com/sneed/pkrandom/romhandlers/AbstractRomHandler.java
index a263f56..4f289e9 100755
--- a/src/com/sneed/pkrandom/romhandlers/AbstractRomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/AbstractRomHandler.java
@@ -54,6 +54,7 @@ public abstract class AbstractRomHandler implements RomHandler {
private List<Pokemon> alreadyPicked = new ArrayList<>();
private Map<Pokemon, Integer> placementHistory = new HashMap<>();
private Map<Integer, Integer> itemPlacementHistory = new HashMap<>();
+ private int fullyEvolvedRandomSeed;
boolean isORAS = false;
boolean isSM = false;
int perfectAccuracy = 100;
@@ -63,6 +64,7 @@ public abstract class AbstractRomHandler implements RomHandler {
public AbstractRomHandler(Random random, PrintStream logStream) {
this.random = random;
this.cosmeticRandom = RandomSource.cosmeticInstance();
+ this.fullyEvolvedRandomSeed = random.nextInt(GlobalConstants.LARGEST_NUMBER_OF_SPLIT_EVOS);
this.logStream = logStream;
}
@@ -1797,14 +1799,23 @@ public abstract class AbstractRomHandler implements RomHandler {
}
}
- int trainerIndex = currentTrainers.indexOf(t) + 1;
+ List<Pokemon> evolvesIntoTheWrongType = new ArrayList<>();
+ if (typeForTrainer != null) {
+ List<Pokemon> pokemonOfType = includeFormes ? pokemonOfTypeInclFormes(typeForTrainer, noLegendaries) :
+ pokemonOfType(typeForTrainer, noLegendaries);
+ for (Pokemon pk : pokemonOfType) {
+ if (!pokemonOfType.contains(fullyEvolve(pk, t.index))) {
+ evolvesIntoTheWrongType.add(pk);
+ }
+ }
+ }
List<TrainerPokemon> trainerPokemonList = new ArrayList<>(t.pokemon);
// Elite Four Unique Pokemon related
boolean eliteFourTrackPokemon = false;
boolean eliteFourRival = false;
- if (eliteFourUniquePokemon && eliteFourIndices.contains(trainerIndex)) {
+ if (eliteFourUniquePokemon && eliteFourIndices.contains(t.index)) {
eliteFourTrackPokemon = true;
// Sort Pokemon list back to front, and then put highest level Pokemon first
@@ -1836,6 +1847,9 @@ public abstract class AbstractRomHandler implements RomHandler {
if (eliteFourSetUniquePokemon) {
bannedList.addAll(bannedFromUniqueList);
}
+ if (willForceEvolve) {
+ bannedList.addAll(evolvesIntoTheWrongType);
+ }
Pokemon newPK = pickTrainerPokeReplacement(
oldPK,
@@ -1843,7 +1857,7 @@ public abstract class AbstractRomHandler implements RomHandler {
typeForTrainer,
noLegendaries,
wgAllowed,
- distributionSetting || (mainPlaythroughSetting && mainPlaythroughTrainers.contains(t.offset)),
+ distributionSetting || (mainPlaythroughSetting && mainPlaythroughTrainers.contains(t.index)),
swapThisMegaEvo,
abilitiesAreRandomized,
includeFormes,
@@ -1851,7 +1865,7 @@ public abstract class AbstractRomHandler implements RomHandler {
);
// Chosen Pokemon is locked in past here
- if (distributionSetting || (mainPlaythroughSetting && mainPlaythroughTrainers.contains(t.offset))) {
+ if (distributionSetting || (mainPlaythroughSetting && mainPlaythroughTrainers.contains(t.index))) {
setPlacementHistory(newPK);
}
tp.absolutePokeNumber = newPK.number;
@@ -1998,7 +2012,7 @@ public abstract class AbstractRomHandler implements RomHandler {
for (Trainer t : currentTrainers) {
for (TrainerPokemon tp : t.pokemon) {
if (tp.level >= minLevel) {
- Pokemon newPokemon = fullyEvolve(tp.pokemon);
+ Pokemon newPokemon = fullyEvolve(tp.pokemon, t.index);
if (newPokemon != tp.pokemon) {
tp.pokemon = newPokemon;
tp.absolutePokeNumber = newPokemon.number;
@@ -5984,7 +5998,7 @@ public abstract class AbstractRomHandler implements RomHandler {
}
}
- private Pokemon fullyEvolve(Pokemon pokemon) {
+ private Pokemon fullyEvolve(Pokemon pokemon, int trainerIndex) {
Set<Pokemon> seenMons = new HashSet<>();
seenMons.add(pokemon);
@@ -6008,8 +6022,11 @@ public abstract class AbstractRomHandler implements RomHandler {
break;
}
- // pick a random evolution to continue from
- pokemon = pokemon.evolutionsFrom.get(random.nextInt(pokemon.evolutionsFrom.size())).to;
+ // We want to make split evolutions deterministic, but still random on a seed-to-seed basis.
+ // Therefore, we take a random value (which is generated once per seed) and add it to the trainer's
+ // index to get a pseudorandom number that can be used to decide which split to take.
+ int evolutionIndex = (this.fullyEvolvedRandomSeed + trainerIndex) % pokemon.evolutionsFrom.size();
+ pokemon = pokemon.evolutionsFrom.get(evolutionIndex).to;
seenMons.add(pokemon);
}
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen1RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen1RomHandler.java
index 33845c5..7074073 100755
--- a/src/com/sneed/pkrandom/romhandlers/Gen1RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen1RomHandler.java
@@ -1274,13 +1274,16 @@ public class Gen1RomHandler extends AbstractGBCRomHandler {
List<String> tcnames = getTrainerClassesForText();
List<Trainer> allTrainers = new ArrayList<>();
+ int index = 0;
for (int i = 1; i <= traineramount; i++) {
int offs = pointers[i];
int limit = trainerclasslimits[i];
String tcname = tcnames.get(i - 1);
for (int trnum = 0; trnum < limit; trnum++) {
+ index++;
Trainer tr = new Trainer();
tr.offset = offs;
+ tr.index = index;
tr.trainerclass = i;
tr.fullDisplayName = tcname;
int dataType = rom[offs] & 0xFF;
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen2RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen2RomHandler.java
index e0ac1d9..7bc9f13 100755
--- a/src/com/sneed/pkrandom/romhandlers/Gen2RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen2RomHandler.java
@@ -1147,12 +1147,15 @@ public class Gen2RomHandler extends AbstractGBCRomHandler {
List<String> tcnames = this.getTrainerClassNames();
List<Trainer> allTrainers = new ArrayList<>();
+ int index = 0;
for (int i = 0; i < traineramount; i++) {
int offs = pointers[i];
int limit = trainerclasslimits[i];
for (int trnum = 0; trnum < limit; trnum++) {
+ index++;
Trainer tr = new Trainer();
tr.offset = offs;
+ tr.index = index;
tr.trainerclass = i;
String name = readVariableLengthString(offs, false);
tr.name = name;
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen3RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen3RomHandler.java
index 5f6b3ff..387db02 100755
--- a/src/com/sneed/pkrandom/romhandlers/Gen3RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen3RomHandler.java
@@ -1816,6 +1816,7 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
int trOffset = baseOffset + i * entryLen;
Trainer tr = new Trainer();
tr.offset = trOffset;
+ tr.index = i;
int trainerclass = rom[trOffset + 1] & 0xFF;
tr.trainerclass = (rom[trOffset + 2] & 0x80) > 0 ? 1 : 0;
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java
index 88950fe..2613a4e 100755
--- a/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java
@@ -2811,7 +2811,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
Trainer tr = new Trainer();
tr.poketype = trainer[0] & 0xFF;
tr.trainerclass = trainer[1] & 0xFF;
- tr.offset = i;
+ tr.index = i;
int numPokes = trainer[3] & 0xFF;
int pokeOffs = 0;
tr.fullDisplayName = tclasses.get(tr.trainerclass) + " " + tnames.get(i - 1);
@@ -2925,7 +2925,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
// If we set this flag for partner trainers (e.g., Cheryl), then the double wild battles
// will turn into trainer battles with glitchy trainers.
boolean excludedPartnerTrainer = romEntry.romType != Gen4Constants.Type_HGSS &&
- Gen4Constants.partnerTrainerIndices.contains(tr.offset);
+ Gen4Constants.partnerTrainerIndices.contains(tr.index);
if (trainer[16] == 0 && !excludedPartnerTrainer) {
trainer[16] |= 3;
}
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java
index 8c1d125..2743583 100755
--- a/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java
@@ -1403,7 +1403,7 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
byte[] trpoke = trpokes.files.get(i);
Trainer tr = new Trainer();
tr.poketype = trainer[0] & 0xFF;
- tr.offset = i;
+ tr.index = i;
tr.trainerclass = trainer[1] & 0xFF;
int numPokes = trainer[3] & 0xFF;
int pokeOffs = 0;
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen6RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen6RomHandler.java
index 37a54b3..9783679 100644
--- a/src/com/sneed/pkrandom/romhandlers/Gen6RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen6RomHandler.java
@@ -1874,7 +1874,7 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
byte[] trpoke = trpokes.files.get(i).get(0);
Trainer tr = new Trainer();
tr.poketype = isORAS ? readWord(trainer,0) : trainer[0] & 0xFF;
- tr.offset = i;
+ tr.index = i;
tr.trainerclass = isORAS ? readWord(trainer,2) : trainer[1] & 0xFF;
int offset = isORAS ? 6 : 2;
int battleType = trainer[offset] & 0xFF;
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen7RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen7RomHandler.java
index 06ca05f..d41116e 100644
--- a/src/com/sneed/pkrandom/romhandlers/Gen7RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen7RomHandler.java
@@ -1587,7 +1587,7 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
byte[] trpoke = trpokes.files.get(i).get(0);
Trainer tr = new Trainer();
tr.poketype = trainer[13] & 0xFF;
- tr.offset = i;
+ tr.index = i;
tr.trainerclass = trainer[0] & 0xFF;
int battleType = trainer[2] & 0xFF;
int numPokes = trainer[3] & 0xFF;