diff options
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
|