summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/com/dabomstew/pkrandom/pokemon/TrainerPokemon.java6
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java71
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java6
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java38
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java35
-rw-r--r--src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java32
-rw-r--r--src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java36
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/RomHandler.java2
8 files changed, 183 insertions, 43 deletions
diff --git a/src/com/dabomstew/pkrandom/pokemon/TrainerPokemon.java b/src/com/dabomstew/pkrandom/pokemon/TrainerPokemon.java
index 7ba3a4a..b0c7816 100755
--- a/src/com/dabomstew/pkrandom/pokemon/TrainerPokemon.java
+++ b/src/com/dabomstew/pkrandom/pokemon/TrainerPokemon.java
@@ -38,12 +38,12 @@ public class TrainerPokemon {
public int heldItem = 0;
public boolean hasMegaStone;
public boolean hasZCrystal;
- public int ability;
+ public int abilitySlot;
public int forme;
public String formeSuffix = "";
public int absolutePokeNumber = 0;
- public int mysteryFlag;
+ public int forcedGenderFlag;
public byte nature;
public byte hpEVs;
public byte atkEVs;
@@ -88,7 +88,7 @@ public class TrainerPokemon {
tpk.AILevel = AILevel;
tpk.heldItem = heldItem;
- tpk.ability = ability;
+ tpk.abilitySlot = abilitySlot;
tpk.forme = forme;
tpk.formeSuffix = formeSuffix;
tpk.absolutePokeNumber = absolutePokeNumber;
diff --git a/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java
index eab9054..7e6a27c 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/AbstractRomHandler.java
@@ -1636,6 +1636,7 @@ public abstract class AbstractRomHandler implements RomHandler {
tp.absolutePokeNumber = newPK.number;
tp.pokemon = newPK;
setFormeForTrainerPokemon(tp, newPK);
+ tp.abilitySlot = getRandomAbilitySlot(newPK);
}
else { // pure random when trainer not in pool
newPK =
@@ -1653,6 +1654,7 @@ public abstract class AbstractRomHandler implements RomHandler {
tp.absolutePokeNumber = newPK.number;
tp.pokemon = newPK;
setFormeForTrainerPokemon(tp, newPK);
+ tp.abilitySlot = getRandomAbilitySlot(newPK);
}
} else {
newPK =
@@ -1673,6 +1675,7 @@ public abstract class AbstractRomHandler implements RomHandler {
tp.absolutePokeNumber = newPK.number;
tp.pokemon = newPK;
setFormeForTrainerPokemon(tp, newPK);
+ tp.abilitySlot = getRandomAbilitySlot(newPK);
}
if (swapThisMegaEvo) {
@@ -1841,6 +1844,7 @@ public abstract class AbstractRomHandler implements RomHandler {
tp.absolutePokeNumber = newPK.number;
tp.pokemon = newPK;
setFormeForTrainerPokemon(tp, newPK);
+ tp.abilitySlot = getRandomAbilitySlot(newPK);
if (swapThisMegaEvo) {
tp.heldItem = newPK
@@ -1902,6 +1906,7 @@ public abstract class AbstractRomHandler implements RomHandler {
tp.absolutePokeNumber = newPK.number;
tp.pokemon = newPK;
setFormeForTrainerPokemon(tp, newPK);
+ tp.abilitySlot = getRandomAbilitySlot(newPK);
if (swapThisMegaEvo) {
tp.heldItem = newPK
@@ -2011,6 +2016,7 @@ public abstract class AbstractRomHandler implements RomHandler {
tp.pokemon = newPokemon;
tp.absolutePokeNumber = newPokemon.number;
setFormeForTrainerPokemon(tp, newPokemon);
+ tp.abilitySlot = getValidAbilitySlotFromOriginal(newPokemon, tp.abilitySlot);
tp.resetMoves = true;
}
}
@@ -2112,6 +2118,25 @@ public abstract class AbstractRomHandler implements RomHandler {
this.setTrainers(currentTrainers, true);
}
+ public int getRandomAbilitySlot(Pokemon pokemon) {
+ List<Integer> abilitiesList = Arrays.asList(pokemon.ability1, pokemon.ability2, pokemon.ability3);
+ int slot = random.nextInt(this.abilitiesPerPokemon());
+ while (abilitiesList.get(slot) == 0) {
+ slot = random.nextInt(this.abilitiesPerPokemon());
+ }
+ return slot + 1;
+ }
+
+ public int getValidAbilitySlotFromOriginal(Pokemon pokemon, int originalAbilitySlot) {
+ // This is used in cases where one Trainer Pokemon evolves into another. If the unevolved Pokemon
+ // is using slot 2, but the evolved Pokemon doesn't actually have a second ability, then we
+ // want the evolved Pokemon to use slot 1 for safety's sake.
+ if (originalAbilitySlot == 2 && pokemon.ability2 == 0) {
+ return 1;
+ }
+ return originalAbilitySlot;
+ }
+
// MOVE DATA
// All randomizers don't touch move ID 165 (Struggle)
// They also have other exclusions where necessary to stop things glitching.
@@ -5239,39 +5264,41 @@ public abstract class AbstractRomHandler implements RomHandler {
// The rival's starter is index 1
Pokemon rivalStarter = starters.get(1);
int timesEvolves = numEvolutions(rivalStarter, 2);
+ // Yellow does not have abilities
+ int abilitySlot = 0;
// Apply evolutions as appropriate
if (timesEvolves == 0) {
for (int j = 1; j <= 3; j++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-0", rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-0", rivalStarter, abilitySlot);
}
for (int j = 4; j <= 7; j++) {
for (int i = 0; i < 3; i++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, rivalStarter, abilitySlot);
}
}
} else if (timesEvolves == 1) {
for (int j = 1; j <= 3; j++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-0", rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-0", rivalStarter, abilitySlot);
}
rivalStarter = pickRandomEvolutionOf(rivalStarter, false);
for (int j = 4; j <= 7; j++) {
for (int i = 0; i < 3; i++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, rivalStarter, abilitySlot);
}
}
} else if (timesEvolves == 2) {
for (int j = 1; j <= 2; j++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-" + 0, rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + 0, rivalStarter, abilitySlot);
}
rivalStarter = pickRandomEvolutionOf(rivalStarter, true);
- changeStarterWithTag(currentTrainers, prefix + "3-0", rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + "3-0", rivalStarter, abilitySlot);
for (int i = 0; i < 3; i++) {
- changeStarterWithTag(currentTrainers, prefix + "4-" + i, rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + "4-" + i, rivalStarter, abilitySlot);
}
rivalStarter = pickRandomEvolutionOf(rivalStarter, false);
for (int j = 5; j <= 7; j++) {
for (int i = 0; i < 3; i++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, rivalStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, rivalStarter, abilitySlot);
}
}
}
@@ -5283,11 +5310,16 @@ public abstract class AbstractRomHandler implements RomHandler {
int starterToUse = (i + pokemonOffset) % 3;
Pokemon thisStarter = starters.get(starterToUse);
int timesEvolves = numEvolutions(thisStarter, 2);
+ int abilitySlot = getRandomAbilitySlot(thisStarter);
+ while (abilitySlot == 3) {
+ // Since starters never have hidden abilities, the rival's starter shouldn't either
+ abilitySlot = getRandomAbilitySlot(thisStarter);
+ }
// If a fully evolved pokemon, use throughout
// Otherwise split by evolutions as appropriate
if (timesEvolves == 0) {
for (int j = 1; j <= highestRivalNum; j++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter, abilitySlot);
}
} else if (timesEvolves == 1) {
int j = 1;
@@ -5295,11 +5327,12 @@ public abstract class AbstractRomHandler implements RomHandler {
if (getLevelOfStarter(currentTrainers, prefix + j + "-" + i) >= 30) {
break;
}
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter, abilitySlot);
}
thisStarter = pickRandomEvolutionOf(thisStarter, false);
+ int evolvedAbilitySlot = getValidAbilitySlotFromOriginal(thisStarter, abilitySlot);
for (; j <= highestRivalNum; j++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter, evolvedAbilitySlot);
}
} else if (timesEvolves == 2) {
int j = 1;
@@ -5307,18 +5340,20 @@ public abstract class AbstractRomHandler implements RomHandler {
if (getLevelOfStarter(currentTrainers, prefix + j + "-" + i) >= 16) {
break;
}
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter, abilitySlot);
}
thisStarter = pickRandomEvolutionOf(thisStarter, true);
+ int evolvedAbilitySlot = getValidAbilitySlotFromOriginal(thisStarter, abilitySlot);
for (; j <= highestRivalNum; j++) {
if (getLevelOfStarter(currentTrainers, prefix + j + "-" + i) >= 36) {
break;
}
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter, evolvedAbilitySlot);
}
thisStarter = pickRandomEvolutionOf(thisStarter, false);
+ evolvedAbilitySlot = getValidAbilitySlotFromOriginal(thisStarter, abilitySlot);
for (; j <= highestRivalNum; j++) {
- changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter);
+ changeStarterWithTag(currentTrainers, prefix + j + "-" + i, thisStarter, evolvedAbilitySlot);
}
}
}
@@ -5367,7 +5402,7 @@ public abstract class AbstractRomHandler implements RomHandler {
return 0;
}
- private void changeStarterWithTag(List<Trainer> currentTrainers, String tag, Pokemon starter) {
+ private void changeStarterWithTag(List<Trainer> currentTrainers, String tag, Pokemon starter, int abilitySlot) {
for (Trainer t : currentTrainers) {
if (t.tag != null && t.tag.equals(tag)) {
@@ -5392,6 +5427,7 @@ public abstract class AbstractRomHandler implements RomHandler {
bestPoke.absolutePokeNumber = starter.number;
setFormeForTrainerPokemon(bestPoke,starter);
bestPoke.resetMoves = true;
+ bestPoke.abilitySlot = abilitySlot;
}
}
@@ -6061,6 +6097,11 @@ public abstract class AbstractRomHandler implements RomHandler {
}
@Override
+ public int getAbilityForTrainerPokemon(TrainerPokemon tp) {
+ return 0;
+ }
+
+ @Override
public boolean hasTimeBasedEncounters() {
// DEFAULT: no
return false;
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java
index 8cc2556..3994e42 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java
@@ -2727,6 +2727,12 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
}
@Override
+ public int getAbilityForTrainerPokemon(TrainerPokemon tp) {
+ // In Gen 3, Trainer Pokemon *always* use the first Ability, no matter what
+ return tp.pokemon.ability1;
+ }
+
+ @Override
public boolean hasMegaEvolutions() {
return false;
}
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java
index 9126f63..a785237 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java
@@ -2098,7 +2098,12 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
tpk.level = level;
tpk.pokemon = pokes[species];
tpk.AILevel = ailevel;
- tpk.ability = (trpoke[pokeOffs + 1] >>> 4) & 0xF;
+ int abilitySlot = (trpoke[pokeOffs + 1] >>> 4) & 0xF;
+ if (abilitySlot == 0) {
+ // All Gen 4 games represent the first ability as ability 0.
+ abilitySlot = 1;
+ }
+ tpk.abilitySlot = abilitySlot;
tpk.forme = formnum;
tpk.formeSuffix = Gen4Constants.getFormeSuffixByBaseForme(species,formnum);
tpk.absolutePokeNumber = Gen4Constants.getAbsolutePokeNumByBaseForme(species,formnum);
@@ -2202,7 +2207,13 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
Iterator<TrainerPokemon> tpokes = tr.pokemon.iterator();
for (int poke = 0; poke < numPokes; poke++) {
TrainerPokemon tp = tpokes.next();
+ int ability = tp.abilitySlot << 4;
+ if (tp.abilitySlot == 1) {
+ // All Gen 4 games represent the first ability as ability 0.
+ ability = 0;
+ }
writeWord(trpoke, pokeOffs, tp.AILevel);
+ writeWord(trpoke, pokeOffs + 1, ability);
writeWord(trpoke, pokeOffs + 2, tp.level);
writeWord(trpoke, pokeOffs + 4, tp.pokemon.number);
trpoke[pokeOffs + 5] |= (tp.forme << 2);
@@ -3656,6 +3667,23 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
@Override
+ public int getAbilityForTrainerPokemon(TrainerPokemon tp) {
+ // In Gen 4, alt formes for Trainer Pokemon use the base forme's ability
+ Pokemon pkmn = tp.pokemon;
+ while (pkmn.baseForme != null) {
+ pkmn = pkmn.baseForme;
+ }
+
+ if (romEntry.romType == Gen4Constants.Type_DP || romEntry.romType == Gen4Constants.Type_Plat) {
+ // In DPPt, Trainer Pokemon *always* use the first Ability, no matter what
+ return pkmn.ability1;
+ } else {
+ // In HGSS, Trainer Pokemon can specify which ability they want to use.
+ return tp.abilitySlot == 2 ? pkmn.ability2 : pkmn.ability1;
+ }
+ }
+
+ @Override
public boolean hasMegaEvolutions() {
return false;
}
@@ -4361,13 +4389,15 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
if (byType.get(Type.NORMAL) == Effectiveness.NEUTRAL) {
items.add(Gen4Constants.chilanBerry);
}
- if (tp.ability == Abilities.levitate) {
+
+ int ability = this.getAbilityForTrainerPokemon(tp);
+ if (ability == Abilities.levitate) {
items.removeAll(Arrays.asList(Gen4Constants.shucaBerry));
}
if (!consumableOnly) {
- if (Gen4Constants.abilityBoostingItems.containsKey(tp.ability)) {
- items.addAll(Gen4Constants.abilityBoostingItems.get(tp.ability));
+ if (Gen4Constants.abilityBoostingItems.containsKey(ability)) {
+ items.addAll(Gen4Constants.abilityBoostingItems.get(ability));
}
if (tp.pokemon.primaryType == Type.POISON || tp.pokemon.secondaryType == Type.POISON) {
items.add(Gen4Constants.blackSludge);
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java
index a77c967..f1f84df 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java
@@ -1224,8 +1224,8 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
tpk.pokemon = pokes[species];
tpk.AILevel = ailevel;
int abilityAndFlag = trpoke[pokeOffs + 1];
- tpk.ability = (abilityAndFlag >>> 4) & 0xF;
- tpk.mysteryFlag = (abilityAndFlag & 0xF);
+ tpk.abilitySlot = (abilityAndFlag >>> 4) & 0xF;
+ tpk.forcedGenderFlag = (abilityAndFlag & 0xF);
tpk.forme = formnum;
tpk.formeSuffix = Gen5Constants.getFormeSuffixByBaseForme(species,formnum);
tpk.absolutePokeNumber = Gen5Constants.getAbsolutePokeNumByBaseForme(species,formnum);
@@ -1353,8 +1353,9 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
Iterator<TrainerPokemon> tpokes = tr.pokemon.iterator();
for (int poke = 0; poke < numPokes; poke++) {
TrainerPokemon tp = tpokes.next();
+ byte abilityAndFlag = (byte)((tp.abilitySlot << 4) | tp.forcedGenderFlag);
trpoke[pokeOffs] = (byte) tp.AILevel;
- // no gender or ability info, so no byte 1
+ trpoke[pokeOffs + 1] = abilityAndFlag;
writeWord(trpoke, pokeOffs + 2, tp.level);
writeWord(trpoke, pokeOffs + 4, tp.pokemon.number);
writeWord(trpoke, pokeOffs + 6, tp.forme);
@@ -2882,6 +2883,26 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
}
@Override
+ public int getAbilityForTrainerPokemon(TrainerPokemon tp) {
+ // Before randomizing Trainer Pokemon, one possible value for abilitySlot is 0,
+ // which represents "Either Ability 1 or 2". During randomization, we make sure to
+ // to set abilitySlot to some non-zero value, but if you call this method without
+ // randomization, then you'll hit this case.
+ if (tp.abilitySlot < 1 || tp.abilitySlot > 3) {
+ return 0;
+ }
+
+ // In Gen 5, alt formes for Trainer Pokemon use the base forme's ability
+ Pokemon pkmn = tp.pokemon;
+ while (pkmn.baseForme != null) {
+ pkmn = pkmn.baseForme;
+ }
+
+ List<Integer> abilityList = Arrays.asList(pkmn.ability1, pkmn.ability2, pkmn.ability3);
+ return abilityList.get(tp.abilitySlot - 1);
+ }
+
+ @Override
public boolean hasMegaEvolutions() {
return false;
}
@@ -3518,15 +3539,17 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
if (byType.get(Type.NORMAL) == Effectiveness.NEUTRAL) {
items.add(Gen4Constants.chilanBerry);
}
- if (tp.ability == Abilities.levitate) {
+
+ int ability = this.getAbilityForTrainerPokemon(tp);
+ if (ability == Abilities.levitate) {
items.removeAll(Arrays.asList(Gen4Constants.shucaBerry));
} else if (byType.get(Type.GROUND) == Effectiveness.DOUBLE || byType.get(Type.GROUND) == Effectiveness.QUADRUPLE) {
items.add(Gen5Constants.airBalloon);
}
if (!consumableOnly) {
- if (Gen5Constants.abilityBoostingItems.containsKey(tp.ability)) {
- items.addAll(Gen5Constants.abilityBoostingItems.get(tp.ability));
+ if (Gen5Constants.abilityBoostingItems.containsKey(ability)) {
+ items.addAll(Gen5Constants.abilityBoostingItems.get(ability));
}
if (tp.pokemon.primaryType == Type.POISON || tp.pokemon.secondaryType == Type.POISON) {
items.add(Gen4Constants.blackSludge);
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java
index 876604b..75f7c01 100644
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java
@@ -350,6 +350,9 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
pkmn.ability1 = stats[Gen6Constants.bsAbility1Offset] & 0xFF;
pkmn.ability2 = stats[Gen6Constants.bsAbility2Offset] & 0xFF;
pkmn.ability3 = stats[Gen6Constants.bsAbility3Offset] & 0xFF;
+ if (pkmn.ability1 == pkmn.ability2) {
+ pkmn.ability2 = 0;
+ }
// Held Items?
int item1 = FileFunctions.read2ByteInt(stats, Gen6Constants.bsCommonHeldItemOffset);
@@ -1723,8 +1726,8 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
tpk.pokemon = pokes[species];
tpk.AILevel = trainerAILevel;
int abilityAndFlag = trpoke[pokeOffs + 1];
- tpk.ability = (abilityAndFlag >>> 4) & 0xF;
- tpk.mysteryFlag = (abilityAndFlag & 0xF);
+ tpk.abilitySlot = (abilityAndFlag >>> 4) & 0xF;
+ tpk.forcedGenderFlag = (abilityAndFlag & 0xF);
tpk.forme = formnum;
tpk.formeSuffix = Gen6Constants.getFormeSuffixByBaseForme(species,formnum);
tpk.absolutePokeNumber = absolutePokeNumByBaseForme
@@ -1820,8 +1823,9 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
Iterator<TrainerPokemon> tpokes = tr.pokemon.iterator();
for (int poke = 0; poke < numPokes; poke++) {
TrainerPokemon tp = tpokes.next();
+ byte abilityAndFlag = (byte)((tp.abilitySlot << 4) | tp.forcedGenderFlag);
trpoke[pokeOffs] = (byte) tp.AILevel;
- // no gender or ability info, so no byte 1
+ trpoke[pokeOffs + 1] = abilityAndFlag;
writeWord(trpoke, pokeOffs + 2, tp.level);
writeWord(trpoke, pokeOffs + 4, tp.pokemon.number);
writeWord(trpoke, pokeOffs + 6, tp.forme);
@@ -3024,6 +3028,20 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
}
@Override
+ public int getAbilityForTrainerPokemon(TrainerPokemon tp) {
+ // Before randomizing Trainer Pokemon, one possible value for abilitySlot is 0,
+ // which represents "Either Ability 1 or 2". During randomization, we make sure to
+ // to set abilitySlot to some non-zero value, but if you call this method without
+ // randomization, then you'll hit this case.
+ if (tp.abilitySlot < 1 || tp.abilitySlot > 3) {
+ return 0;
+ }
+
+ List<Integer> abilityList = Arrays.asList(tp.pokemon.ability1, tp.pokemon.ability2, tp.pokemon.ability3);
+ return abilityList.get(tp.abilitySlot - 1);
+ }
+
+ @Override
public boolean hasMegaEvolutions() {
return true;
}
@@ -3606,15 +3624,17 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
if (byType.get(Type.NORMAL) == Effectiveness.NEUTRAL) {
items.add(Gen4Constants.chilanBerry);
}
- if (tp.ability == Abilities.levitate) {
+
+ int ability = this.getAbilityForTrainerPokemon(tp);
+ if (ability == Abilities.levitate) {
items.removeAll(Arrays.asList(Gen4Constants.shucaBerry));
} else if (byType.get(Type.GROUND) == Effectiveness.DOUBLE || byType.get(Type.GROUND) == Effectiveness.QUADRUPLE) {
items.add(Gen5Constants.airBalloon);
}
if (!consumableOnly) {
- if (Gen6Constants.abilityBoostingItems.containsKey(tp.ability)) {
- items.addAll(Gen6Constants.abilityBoostingItems.get(tp.ability));
+ if (Gen6Constants.abilityBoostingItems.containsKey(ability)) {
+ items.addAll(Gen6Constants.abilityBoostingItems.get(ability));
}
if (tp.pokemon.primaryType == Type.POISON || tp.pokemon.secondaryType == Type.POISON) {
items.add(Gen4Constants.blackSludge);
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java
index 2762f51..4a134b2 100644
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen7RomHandler.java
@@ -381,6 +381,9 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
pkmn.ability1 = stats[Gen7Constants.bsAbility1Offset] & 0xFF;
pkmn.ability2 = stats[Gen7Constants.bsAbility2Offset] & 0xFF;
pkmn.ability3 = stats[Gen7Constants.bsAbility3Offset] & 0xFF;
+ if (pkmn.ability1 == pkmn.ability2) {
+ pkmn.ability2 = 0;
+ }
pkmn.callRate = stats[Gen7Constants.bsCallRateOffset] & 0xFF;
@@ -1467,8 +1470,8 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
int species = readWord(trpoke, pokeOffs + 16);
int formnum = readWord(trpoke, pokeOffs + 18);
TrainerPokemon tpk = new TrainerPokemon();
- tpk.ability = (abilityAndFlag >>> 4) & 0xF;
- tpk.mysteryFlag = (abilityAndFlag & 0xF);
+ tpk.abilitySlot = (abilityAndFlag >>> 4) & 0xF;
+ tpk.forcedGenderFlag = (abilityAndFlag & 0xF);
tpk.nature = trpoke[pokeOffs + 1];
tpk.hpEVs = trpoke[pokeOffs + 2];
tpk.atkEVs = trpoke[pokeOffs + 3];
@@ -1487,7 +1490,6 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
}
tpk.pokemon = pokes[species];
tpk.AILevel = trainerAILevel;
- tpk.ability = trpoke[pokeOffs + 1] & 0xFF;
tpk.forme = formnum;
tpk.formeSuffix = Gen7Constants.getFormeSuffixByBaseForme(species,formnum);
tpk.absolutePokeNumber = absolutePokeNumByBaseForme
@@ -1563,7 +1565,7 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
Iterator<TrainerPokemon> tpokes = tr.pokemon.iterator();
for (int poke = 0; poke < numPokes; poke++) {
TrainerPokemon tp = tpokes.next();
- byte abilityAndFlag = (byte)((tp.ability << 4) | tp.mysteryFlag);
+ byte abilityAndFlag = (byte)((tp.abilitySlot << 4) | tp.forcedGenderFlag);
trpoke[pokeOffs] = abilityAndFlag;
trpoke[pokeOffs + 1] = tp.nature;
trpoke[pokeOffs + 2] = tp.hpEVs;
@@ -2704,6 +2706,20 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
}
@Override
+ public int getAbilityForTrainerPokemon(TrainerPokemon tp) {
+ // Before randomizing Trainer Pokemon, one possible value for abilitySlot is 0,
+ // which represents "Either Ability 1 or 2". During randomization, we make sure to
+ // to set abilitySlot to some non-zero value, but if you call this method without
+ // randomization, then you'll hit this case.
+ if (tp.abilitySlot < 1 || tp.abilitySlot > 3) {
+ return 0;
+ }
+
+ List<Integer> abilityList = Arrays.asList(tp.pokemon.ability1, tp.pokemon.ability2, tp.pokemon.ability3);
+ return abilityList.get(tp.abilitySlot - 1);
+ }
+
+ @Override
public boolean hasMegaEvolutions() {
return true;
}
@@ -3256,18 +3272,20 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
if (byType.get(Type.NORMAL) == Effectiveness.NEUTRAL) {
items.add(Gen4Constants.chilanBerry);
}
- if (tp.ability == Abilities.levitate) {
+
+ int ability = this.getAbilityForTrainerPokemon(tp);
+ if (ability == Abilities.levitate) {
items.removeAll(Arrays.asList(Gen4Constants.shucaBerry));
} else if (byType.get(Type.GROUND) == Effectiveness.DOUBLE || byType.get(Type.GROUND) == Effectiveness.QUADRUPLE) {
items.add(Gen5Constants.airBalloon);
}
- if (Gen7Constants.consumableAbilityBoostingItems.containsKey(tp.ability)) {
- items.add(Gen7Constants.consumableAbilityBoostingItems.get(tp.ability));
+ if (Gen7Constants.consumableAbilityBoostingItems.containsKey(ability)) {
+ items.add(Gen7Constants.consumableAbilityBoostingItems.get(ability));
}
if (!consumableOnly) {
- if (Gen7Constants.abilityBoostingItems.containsKey(tp.ability)) {
- items.addAll(Gen7Constants.abilityBoostingItems.get(tp.ability));
+ if (Gen7Constants.abilityBoostingItems.containsKey(ability)) {
+ items.addAll(Gen7Constants.abilityBoostingItems.get(ability));
}
if (tp.pokemon.primaryType == Type.POISON || tp.pokemon.secondaryType == Type.POISON) {
items.add(Gen4Constants.blackSludge);
diff --git a/src/com/dabomstew/pkrandom/romhandlers/RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/RomHandler.java
index 1266fff..81ecca0 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/RomHandler.java
@@ -169,6 +169,8 @@ public interface RomHandler {
List<Integer> getUselessAbilities();
+ int getAbilityForTrainerPokemon(TrainerPokemon tp);
+
boolean hasMegaEvolutions();
// Randomizer: wild pokemon