Add support to Gen 3+ to randomize held items for trainer's pokes

This adds two list of items per Gen, one for all [1] consumable held items and one for all [1] held items. This adds the options to add items from either of these lists to boss trainers, important trainers, and/or regular trainers. There is a disabled UI element for future work on "sensible" items, which would use a smaller pool of items (e.g. include the Yache berry in the pool only if the Pokemon is weak to ice).

There had been a smaller list of items used for the Totem pokemon in Gen 7; this has been combined with this new code.

[1] We exclude held items that affect only things for the player (e.g. amulet coin, macho brace ), affect only one species of Pokemon (e.g. light ball, lucky punch), or affect only one move (e.g. douse drive, flying memory).
This commit is contained in:
spaceonaut 2021-04-18 20:38:22 -04:00
parent 539536dbf1
commit e20756f85d
23 changed files with 703 additions and 153 deletions

5
.gitignore vendored
View File

@ -38,4 +38,7 @@ gen5r_race.rnqs
.classpath
.settings/org.eclipse.jdt.core.prefs
util/files
util/log
util/log
out/
.idea/
*.iml

View File

@ -348,6 +348,13 @@ public class Randomizer {
trainersChanged = true;
}
if (settings.isRandomizeHeldItemsForBossTrainerPokemon()
|| settings.isRandomizeHeldItemsForImportantTrainerPokemon()
|| settings.isRandomizeHeldItemsForRegularTrainerPokemon()) {
romHandler.randomizeTrainerHeldItems(settings);
trainersChanged = true;
}
if (trainersChanged) {
maybeLogTrainerChanges(log);
} else {
@ -1081,11 +1088,12 @@ public class Randomizer {
}
log.print(" - ");
boolean first = true;
String[] itemNames = romHandler.getItemNames();
for (TrainerPokemon tpk : t.pokemon) {
if (!first) {
log.print(", ");
}
log.print(tpk.toString());
log.printf(tpk.toString(), itemNames[tpk.heldItem]);
first = false;
}
log.println();

View File

@ -49,7 +49,7 @@ public class Settings {
public static final int VERSION = Version.VERSION;
public static final int LENGTH_OF_SETTINGS_DATA = 48;
public static final int LENGTH_OF_SETTINGS_DATA = 49;
private CustomNamesSet customNames;
@ -176,6 +176,12 @@ public class Settings {
private int additionalBossTrainerPokemon = 0;
private int additionalImportantTrainerPokemon = 0;
private int additionalRegularTrainerPokemon = 0;
private boolean randomizeHeldItemsForBossTrainerPokemon;
private boolean randomizeHeldItemsForImportantTrainerPokemon;
private boolean randomizeHeldItemsForRegularTrainerPokemon;
private boolean consumableItemsOnlyForTrainerPokemon;
private boolean sensibleItemsOnlyForTrainerPokemon;
private boolean highestLevelOnlyGetsItemsForTrainerPokemon;
private boolean doubleBattleMode;
private boolean shinyChance;
@ -473,8 +479,6 @@ public class Settings {
swapTrainerMegaEvos,
shinyChance));
// @ 28 pokemon restrictions
try {
if (currentRestrictions != null) {
@ -485,17 +489,15 @@ public class Settings {
} catch (IOException e) {
e.printStackTrace(); // better than nothing
}
// @ 31 misc tweaks
// @ 32 misc tweaks
try {
writeFullInt(out, currentMiscTweaks);
} catch (IOException e) {
e.printStackTrace(); // better than nothing
}
// @ 35 trainer pokemon level modifier
// @ 36 trainer pokemon level modifier
out.write((trainersLevelModified ? 0x80 : 0) | (trainersLevelModifier+50));
out.write(makeByteSelected(shopItemsMod == ShopItemsMod.RANDOM, shopItemsMod == ShopItemsMod.SHUFFLE,
@ -513,6 +515,7 @@ public class Settings {
allowTrainerAlternateFormes,
allowWildAltFormes));
// 40
out.write((doubleBattleMode ? 0x1 : 0) |
(additionalBossTrainerPokemon << 1) |
(additionalImportantTrainerPokemon << 4) |
@ -547,6 +550,14 @@ public class Settings {
out.write((staticLevelModified ? 0x80 : 0) | (staticLevelModifier+50));
// 48 trainer pokemon held items.
out.write(makeByteSelected(randomizeHeldItemsForBossTrainerPokemon,
randomizeHeldItemsForImportantTrainerPokemon,
randomizeHeldItemsForRegularTrainerPokemon,
consumableItemsOnlyForTrainerPokemon,
sensibleItemsOnlyForTrainerPokemon,
highestLevelOnlyGetsItemsForTrainerPokemon));
try {
byte[] romName = this.romName.getBytes("US-ASCII");
out.write(romName.length);
@ -754,7 +765,6 @@ public class Settings {
settings.setSwapTrainerMegaEvos(restoreState(data[27], 5));
settings.setShinyChance(restoreState(data[27], 6));
// gen restrictions
int genLimit = FileFunctions.readFullInt(data, 28);
GenRestrictions restrictions = null;
@ -818,6 +828,13 @@ public class Settings {
settings.setStaticLevelModified(restoreState(data[47],7));
settings.setStaticLevelModifier((data[47] & 0x7F) - 50);
settings.setRandomizeHeldItemsForBossTrainerPokemon(restoreState(data[48], 0));
settings.setRandomizeHeldItemsForImportantTrainerPokemon(restoreState(data[48], 1));
settings.setRandomizeHeldItemsForRegularTrainerPokemon(restoreState(data[48], 2));
settings.setConsumableItemsOnlyForTrainers(restoreState(data[48], 3));
settings.setSensibleItemsOnlyForTrainers(restoreState(data[48], 4));
settings.setHighestLevelGetsItemsForTrainers(restoreState(data[48], 5));
int romNameLength = data[LENGTH_OF_SETTINGS_DATA] & 0xFF;
String romName = new String(data, LENGTH_OF_SETTINGS_DATA + 1, romNameLength, "US-ASCII");
settings.setRomName(romName);
@ -1596,6 +1613,54 @@ public class Settings {
this.additionalRegularTrainerPokemon = additional;
}
public boolean isRandomizeHeldItemsForBossTrainerPokemon() {
return randomizeHeldItemsForBossTrainerPokemon;
}
public void setRandomizeHeldItemsForBossTrainerPokemon(boolean bossTrainers) {
this.randomizeHeldItemsForBossTrainerPokemon = bossTrainers;
}
public boolean isRandomizeHeldItemsForImportantTrainerPokemon() {
return randomizeHeldItemsForImportantTrainerPokemon;
}
public void setRandomizeHeldItemsForImportantTrainerPokemon(boolean importantTrainers) {
this.randomizeHeldItemsForImportantTrainerPokemon = importantTrainers;
}
public boolean isRandomizeHeldItemsForRegularTrainerPokemon() {
return randomizeHeldItemsForRegularTrainerPokemon;
}
public void setRandomizeHeldItemsForRegularTrainerPokemon(boolean regularTrainers) {
this.randomizeHeldItemsForRegularTrainerPokemon = regularTrainers;
}
public boolean isConsumableItemsOnlyForTrainers() {
return consumableItemsOnlyForTrainerPokemon;
}
public void setConsumableItemsOnlyForTrainers(boolean consumableOnly) {
this.consumableItemsOnlyForTrainerPokemon = consumableOnly;
}
public boolean isSensibleItemsOnlyForTrainers() {
return sensibleItemsOnlyForTrainerPokemon;
}
public void setSensibleItemsOnlyForTrainers(boolean sensibleOnly) {
this.sensibleItemsOnlyForTrainerPokemon = sensibleOnly;
}
public boolean isHighestLevelGetsItemsForTrainers() {
return highestLevelOnlyGetsItemsForTrainerPokemon;
}
public void setHighestLevelGetsItemsForTrainers(boolean highestOnly) {
this.highestLevelOnlyGetsItemsForTrainerPokemon = highestOnly;
}
public boolean isDoubleBattleMode() {
return doubleBattleMode;
}

View File

@ -200,6 +200,44 @@ public class Gen3Constants {
public static final int luckyEggIndex = 0xC5;
// https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_III)
// Berries that can be eaten in battle listed. They are in numeric order and roughly categorized.
public static final int
// status effect berries
cheriBerry = 0x85, chestoBerry = 0x86, pechaBerry = 0x87, rawstBerry = 0x88, aspearBerry = 0x89,
leppaBerry = 0x8a, oranBerry = 0x8b, persimBerry = 0x8c, lumBerry = 0x8d, sitrusBerry = 0x8e,
// Restore 1/8 HP when below 50% but may cause confusion
figyBerry = 0x8f, wikiBerry = 0x90, magoBerry = 0x91, aguavBerry = 0x92, iapapaBerry = 0x93,
// Increase stat (or other buff) when below 25%
liechiBerry = 0xa8, ganlonBerry = 0xa9, salacBerry = 0xaa, petayaBerry = 0xab, apicotBerry = 0xac,
lansatBerry = 0xad, starfBerry = 0xae;
// Other consumable held items
public static final int berryJuice = 0x2c, whiteHerb = 0xb4, mentalHerb = 0xb9;
// non-consumable held items with in-battle NPC effect (not specific to one pokemon family)
public static final int brightPowder = 0x0b3, quickClaw = 0x0b7, choiceBand = 0x0ba, kingsRock = 0x0bb,
silverPowder = 0x0bc, focusBand = 0x0c4, scopeLens = 0x0c6, metalCoat = 0x0c7, leftovers = 0x0c8,
softSand = 0x0cb, hardStone = 0x0cc, miracleSeed = 0x0cd, blackGlasses = 0x0ce, blackBelt = 0x0cf,
magnet = 0x0d0, mysticWater = 0x0d1, sharpBeak = 0x0d2, poisonBarb = 0x0d3, neverMeltIce = 0x0d4,
spellTag = 0x0d5, twistedSpoon = 0x0d6, charcoal = 0x0d7, dragonFang = 0x0d8, silkScarf = 0x0d9,
shellBell = 0x0db, seaIncense = 0x0dc, laxIncense = 0x0de;
public static final List<Integer> consumableHeldItems = Arrays.asList(
cheriBerry, chestoBerry, pechaBerry, rawstBerry, aspearBerry, leppaBerry, oranBerry, persimBerry,
lumBerry, sitrusBerry, figyBerry, wikiBerry, magoBerry, aguavBerry, iapapaBerry, liechiBerry,
ganlonBerry, salacBerry, petayaBerry, apicotBerry, lansatBerry, starfBerry, berryJuice, whiteHerb,
mentalHerb);
public static final List<Integer> allHeldItems = setupAllHeldItems();
private static List<Integer> setupAllHeldItems() {
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(brightPowder, quickClaw, choiceBand, kingsRock, silverPowder, focusBand,
scopeLens, metalCoat, leftovers, softSand, hardStone, miracleSeed, blackGlasses, blackBelt, magnet,
mysticWater, sharpBeak, poisonBarb, neverMeltIce, spellTag, twistedSpoon, charcoal, dragonFang,
silkScarf, shellBell, seaIncense, laxIncense));
list.addAll(consumableHeldItems);
return list;
}
private static Type[] constructTypeTable() {
Type[] table = new Type[256];

View File

@ -95,8 +95,74 @@ public class Gen4Constants {
public static final int highestAbilityIndex = 123;
// https://projectpokemon.org/home/docs/gen-4/list-of-items-by-index-number-r23/
// Berries that can be eaten in battle listed. They are in numeric order and roughly categorized.
public static final int
// status effect berries
cheriBerry = 0x95, chestoBerry = 0x96, pechaBerry = 0x97, rawstBerry = 0x98, aspearBerry = 0x99,
leppaBerry = 0x9a, oranBerry = 0x9b, persimBerry = 0x9c, lumBerry = 0x9d, sitrusBerry = 0x9e,
// Restore 1/8 HP when below 50% but may cause confusion
figyBerry = 0x9f, wikiBerry = 0xa0, magoBerry = 0xa1, aguavBerry = 0xa2, iapapaBerry = 0xa3,
// Reduce damage from supereffective damage
occaBerry = 0xb8, passhoBerry = 0xb9, wacanBerry = 0xba, rindoBerry = 0xbb, yacheBerry = 0xbc,
chopleBerry = 0xbd, kebiaBerry = 0xbe, shucaBerry = 0xbf, cobaBerry = 0xc0, payapaBerry = 0xc1,
tangaBerry = 0xc2, chartiBerry = 0xc3, kasibBerry = 0xc4, habanBerry = 0xc5, colburBerry = 0xc6,
babiriBerry = 0xc7, chilanBerry = 0xc8,
// Increase stat (or other buff) when below 25%
liechiBerry = 0xc9, ganlonBerry = 0xca, salacBerry = 0xcb, petayaBerry = 0xcc, apicotBerry = 0xcd,
lansatBerry = 0xce, starfBerry = 0xcf, enigmaBerry = 0xd0, micleBerry = 0xd1, custapBerry = 0xd2,
// retaliate berries
jabocaBerry = 0xd3, rowapBerry = 0xd4;
// Other consumable held items
public static final int berryJuice = 0x2b, whiteHerb = 0xd6, mentalHerb = 0xdb, powerHerb = 0x10f,
focusSash = 0x113;
// non-consumable held items with in-battle NPC effect (not specific to one pokemon family)
public static final int brightPowder = 0x0d5, quickClaw = 0x0d9, choiceBand = 0x0dc, kingsRock = 0x0dd,
silverPowder = 0x0de, focusBand = 0x0e6, scopeLens = 0x0e8, metalCoat = 0x0e9, leftovers = 0x0ea,
softSand = 0x0ed, hardStone = 0x0ee, miracleSeed = 0x0ef, blackGlasses = 0x0f0, blackBelt = 0x0f1,
magnet = 0x0f2, mysticWater = 0x0f3, sharpBeak = 0x0f4, poisonBarb = 0x0f5, neverMeltIce = 0x0f6,
spellTag = 0x0f7, twistedSpoon = 0x0f8, charcoal = 0x0f9, dragonFang = 0x0fa, silkScarf = 0x0fb,
shellBell = 0x0fd, seaIncense = 0x0fe, laxIncense = 0x0ff, wideLens = 0x109, muscleBand = 0x10a,
wiseGlasses = 0x10b, expertBelt = 0x10c, lightClay = 0x10d, lifeOrb = 0x10e, toxicOrb = 0x110,
flameOrb = 0x111, quickPowder = 0x112, zoomLens = 0x114, metronome = 0x115, ironBall = 0x116,
laggingTail = 0x117, destinyKnot = 0x118, blackSludge = 0x119, icyRock = 0x11a, smoothRock = 0x11b,
heatRock = 0x11c, dampRock = 0x11d, gripClaw = 0x11e, choiceScarf = 0x11f, stickyBarb = 0x120,
shedShell = 0x127, bigRoot = 0x128, choiceSpecs = 0x129, flamePlate = 0x12a, splashPlate = 0x12b,
zapPlate = 0x12c, meadowPlate = 0x12d, iciclePlate = 0x12e, fistPlate = 0x12f, toxicPlate = 0x130,
earthPlate = 0x131, skyPlate = 0x132, mindPlate = 0x133, insectPlate = 0x134, stonePlate = 0x135,
spookyPlate = 0x136, dracoPlate = 0x137, dreadPlate = 0x138, ironPlate = 0x139, oddIncense = 0x13a,
rockIncense = 0x13b, fullIncense = 0x13c, waveIncense = 0x13d, roseIncense = 0x13e, pureIncense = 0x140,
razorClaw = 0x146, razorFang = 0x147;
public static final List<Integer> consumableHeldItems = Arrays.asList(
cheriBerry, chestoBerry, pechaBerry, rawstBerry, aspearBerry, leppaBerry, oranBerry, persimBerry,
lumBerry, sitrusBerry, figyBerry, wikiBerry, magoBerry, aguavBerry, iapapaBerry, occaBerry, passhoBerry,
wacanBerry, rindoBerry, yacheBerry, chopleBerry, kebiaBerry, shucaBerry, cobaBerry, payapaBerry,
tangaBerry, chartiBerry, kasibBerry, habanBerry, colburBerry, babiriBerry, chilanBerry, liechiBerry,
ganlonBerry, salacBerry, petayaBerry, apicotBerry, lansatBerry, starfBerry, enigmaBerry, micleBerry,
custapBerry, jabocaBerry, rowapBerry, berryJuice, whiteHerb, mentalHerb, powerHerb, focusSash);
public static final List<Integer> allHeldItems = setupAllHeldItems();
private static List<Integer> setupAllHeldItems() {
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(brightPowder, quickClaw, choiceBand, kingsRock, silverPowder, focusBand,
scopeLens, metalCoat, leftovers, softSand, hardStone, miracleSeed, blackGlasses, blackBelt, magnet,
mysticWater, sharpBeak, poisonBarb, neverMeltIce, spellTag, twistedSpoon, charcoal, dragonFang,
silkScarf, shellBell, seaIncense, laxIncense, wideLens, muscleBand, wiseGlasses, expertBelt, lightClay,
lifeOrb, toxicOrb, flameOrb, quickPowder, zoomLens, metronome, ironBall, laggingTail, destinyKnot,
blackSludge, icyRock, smoothRock, heatRock, dampRock, gripClaw, choiceScarf, stickyBarb, shedShell,
bigRoot, choiceSpecs, flamePlate, splashPlate, zapPlate, meadowPlate, iciclePlate, fistPlate,
toxicPlate, earthPlate, skyPlate, mindPlate, insectPlate, stonePlate, spookyPlate, dracoPlate,
dreadPlate, ironPlate, oddIncense, rockIncense, fullIncense, waveIncense, roseIncense, pureIncense,
razorClaw, razorFang));
list.addAll(consumableHeldItems);
return list;
}
public static final Map<Integer,List<Integer>> abilityVariations = setupAbilityVariations();
private static Map<Integer,List<Integer>> setupAbilityVariations() {
Map<Integer,List<Integer>> map = new HashMap<>();
map.put(15,Arrays.asList(15,72)); // Insomnia/Vital Spirit

View File

@ -339,6 +339,42 @@ public class Gen5Constants {
public static final String introGraphicPrefix = "5A0000010000001700000001000000", bw1IntroCryPrefix = "0021009101910291", bw2IntroCryLocator = "3D020000F8B51C1C";
// https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_V)
// Held items we randomize from Gen 5 are a superset of the held items from Gen 4. Thus, we list only the
// new ones here.
// New consumable held items.
public static final int airBalloon = 0x21d, redCard = 0x21e, absorbBulb = 0x221, cellBattery = 0x222,
ejectButton = 0x223, fireGem = 0x224, waterGem = 0x225, electricGem = 0x226, grassGem = 0x227,
iceGem = 0x228, fightingGem = 0x229, poisonGem = 0x22a, groundGem = 0x22b, flyingGem = 0x22c,
psychicGem = 0x22d, bugGem = 0x22e, rockGem = 0x22f, ghostGem = 0x230, dragonGem = 0x231,
darkGem = 0x232, steelGem = 0x233, normalGem = 0x234;
// New non-consumable held items with in-battle NPC effect (not specific to one pokemon family or one move)
public static final int eviolite = 0x21a, floatStone = 0x21b, rockyHelmet = 0x21c, ringTarget = 0x21f,
bindingBand = 0x220;
public static final List<Integer> consumableHeldItems = setupAllConsumableItems();
private static List<Integer> setupAllConsumableItems() {
List<Integer> list = new ArrayList<>();
list.addAll(Gen4Constants.consumableHeldItems);
list.addAll(Arrays.asList(airBalloon, redCard, absorbBulb, cellBattery, ejectButton, fireGem, waterGem,
electricGem, grassGem, iceGem, fightingGem, poisonGem, groundGem, flyingGem, psychicGem, bugGem,
rockGem, ghostGem, dragonGem, darkGem, steelGem, normalGem));
return list;
}
public static final List<Integer> allHeldItems = setupAllHeldItems();
private static List<Integer> setupAllHeldItems() {
List<Integer> list = new ArrayList<>();
list.addAll(Gen4Constants.allHeldItems);
list.addAll(Arrays.asList(airBalloon, redCard, absorbBulb, cellBattery, ejectButton, fireGem, waterGem,
electricGem, grassGem, iceGem, fightingGem, poisonGem, groundGem, flyingGem, psychicGem, bugGem,
rockGem, ghostGem, dragonGem, darkGem, steelGem, normalGem));
list.addAll(Arrays.asList(eviolite, floatStone, rockyHelmet, ringTarget, bindingBand));
return list;
}
private static Type[] constructTypeTable() {
Type[] table = new Type[256];
table[0x00] = Type.NORMAL;

View File

@ -237,6 +237,34 @@ public class Gen6Constants {
public static final int[] rayquazaScriptOffsetsORAS = new int[]{ 3334, 14734 }, rayquazaCodeOffsetsORAS = new int[]{ 136, 292, 576 };
public static final String nationalDexFunctionLocator = "080094E5010000E21080BDE8170F122F", xyGetDexFlagFunctionLocator = "000055E30100A0030A00000A";
// https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_VI)
// Held items we randomize from Gen 6 are a superset of the held items from Gen 5. Thus, we list only the
// new ones here.
// New consumable held items.
public static final int weaknessPolicy = 0x27f, luminousMoss = 0x288, snowball = 0x289, roseliBerry = 0x2ae,
keeBerry = 0x2af, marangaBerry = 0x2b0, fairyGem = 0x02cb;
// New non-consumable held items with in-battle NPC effect (not specific to one pokemon family or one move)
public static final int assaultVest = 0x280, pixiePlate = 0x284, safetyGoggles = 0x28a;
public static final List<Integer> consumableHeldItems = setupAllConsumableItems();
private static List<Integer> setupAllConsumableItems() {
List<Integer> list = new ArrayList<>();
list.addAll(Gen5Constants.consumableHeldItems);
list.addAll(Arrays.asList(weaknessPolicy, luminousMoss, snowball, roseliBerry, keeBerry, marangaBerry, fairyGem));
return list;
}
public static final List<Integer> allHeldItems = setupAllHeldItems();
private static List<Integer> setupAllHeldItems() {
List<Integer> list = new ArrayList<>();
list.addAll(Gen5Constants.allHeldItems);
list.addAll(Arrays.asList(weaknessPolicy, snowball, roseliBerry, keeBerry, marangaBerry, fairyGem));
list.addAll(Arrays.asList(assaultVest, pixiePlate, safetyGoggles));
return list;
}
public static String getIngameTradesPrefix(int romType) {
if (romType == Type_XY) {
return ingameTradesPrefixXY;
@ -367,6 +395,13 @@ public class Gen6Constants {
return shopItemsLocatorXY;
}
public static boolean isMegaStone(int itemIndex) {
// These values come from https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_VI)
return (itemIndex >= 0x0290 && itemIndex <= 0x02AD) ||
(itemIndex >= 0x02F0 && itemIndex <= 0x02FC) ||
(itemIndex >= 0x02FF && itemIndex <= 0x0302);
}
private static Type[] constructTypeTable() {
Type[] table = new Type[256];
table[0x00] = Type.NORMAL;

View File

@ -187,6 +187,44 @@ public class Gen7Constants {
}
}
// https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_VII)
// Held items we randomize from Gen 7 are a superset of the held items from Gen 6. Thus, we list only the
// new ones here.
// New consumable held items.
public static final int adrenalineOrb = 0x34e, electricSeed = 0x371, psychicSeed = 0x372,
mistySeed = 0x373, grassySeed = 0x374;
// New non-consumable held items with in-battle NPC effect (not specific to one pokemon family or one move)
public static final int terrainExtender = 0x36F, protectivePads = 0x370;
public static final List<Integer> consumableHeldItems = setupAllConsumableItems();
private static List<Integer> setupAllConsumableItems() {
List<Integer> list = new ArrayList<>();
list.addAll(Gen6Constants.consumableHeldItems);
list.addAll(Arrays.asList(adrenalineOrb, electricSeed, psychicSeed, mistySeed, grassySeed));
return list;
}
public static final List<Integer> allHeldItems = setupAllHeldItems();
private static List<Integer> setupAllHeldItems() {
// We intentionally do not include Z Crystals in this list. Adding Z-Crystals to random trainers should
// probably require its own setting if desired.
List<Integer> list = new ArrayList<>();
list.addAll(Gen6Constants.allHeldItems);
list.addAll(Arrays.asList(adrenalineOrb, electricSeed, psychicSeed, mistySeed, grassySeed));
list.addAll(Arrays.asList(terrainExtender, protectivePads));
return list;
}
public static boolean isZCrystal(int itemIndex) {
// From https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_VII)
return (itemIndex >= 0x308 && itemIndex <= 0x31A) ||
(itemIndex >= 0x31E && itemIndex <= 0x344) ||
(itemIndex >= 0x399 && itemIndex <= 0x3a4);
}
public static List<String> getShopNames(int romType) {
List<String> shopNames = new ArrayList<>();
shopNames.add("Primary 0 Trials");
@ -745,47 +783,6 @@ public class Gen7Constants {
}
}
public static List<Integer> validConsumableHeldItems = Arrays.asList(
0x95,
0x96,
0x97,
0x98,
0x99,
0x9A,
0x9B,
0x9C,
0x9D,
0x9E,
0x9F,
0xA0,
0xA1,
0xA2,
0xA3,
0xC8,
0xC9,
0xCA,
0xCB,
0xCC,
0xCD,
0xCE,
0xCF,
0xD0,
0xD1,
0xD2,
0xD3,
0xD4,
0xD6,
0x113,
0x21D,
0x221,
0x222,
0x27F,
0x288,
0x289,
0x2AF,
0x2B0
);
private static final List<Integer> requiredFieldTMsSM = Arrays.asList(
80, 49, 5, 83, 64, 62, 100, 31, 46, 88, 57, 41, 59, 73, 53, 61, 28, 39, 55, 86, 30, 93, 81, 84, 74, 85, 72,
3, 3, 13, 36, 91, 79, 24, 97, 50, 99, 35, 2, 26, 6, 6

View File

@ -583,4 +583,18 @@ GUI.tmFollowEvolutionsCheckBox.toolTipText=<html>When this is selected and TM co
GUI.mtFollowEvolutionsCheckBox.text=Follow Evolutions
GUI.mtFollowEvolutionsCheckBox.toolTipText=<html>When this is selected and move tutor compatibility is randomized, evolutions of a Pokemon will inherit that Pokemon's move tutor compatibilities.<br />Additionally, when a Pokemon evolves, each move will have:<br /><b>Random (prefer same type)</b>: A 90% chance of becoming learnable if the Pokemon just gained its type through evolution, a 10% chance otherwise.<br/><b>Random (completely)</b>: A 25% chance of becoming learnable regardless of type.
GUI.stpFixMusicAllCheckBox.text=Fix Music
GUI.stpFixMusicAllCheckBox.toolTipText=<html>Fixes the music for all Static Pokemon encounters so that even when randomized, encounters that should have special music will play the correct song.<br />Note that in Gen 4/5, if special music is assigned to a Pokemon then it will <b>always</b> play when battling that Pokemon, even if you just find it normally in the wild.
GUI.stpFixMusicAllCheckBox.toolTipText=<html>Fixes the music for all Static Pokemon encounters so that even when randomized, encounters that should have special music will play the correct song.<br />Note that in Gen 4/5, if special music is assigned to a Pokemon then it will <b>always</b> play when battling that Pokemon, even if you just find it normally in the wild.
GUI.tpHeldItemsLabel.text=Add Held Items to...
GUI.tpBossTrainersItemsCheckBox.text=Boss Trainers
GUI.tpBossTrainersItemsCheckBox.toolTipText=<html>Check this to add or replace held items for the Pokemon of "Boss" Trainers.<br />Boss Trainers include Gym Leaders, Kahunas, Team Leaders, Elite Four, and Champions.
GUI.tpImportantTrainersItemsCheckBox.text=Important Trainers
GUI.tpImportantTrainersItemsCheckBox.toolTipText=<html>Check this to add or replace held items for the Pokemon of "Important" Trainers.<br />Important Trainers include Rivals/Friends, Team Admins, and other important story battles (such as Colress in BW2 and Sycamore in XY).
GUI.tpRegularTrainersItemsCheckBox.text=Regular Trainers
GUI.tpRegularTrainersItemsCheckBox.toolTipText=<html>Check this to add or replace held items for the Pokemon of regular Trainers.<br />Regular Trainers include all trainers that don't qualify as "Boss" or "Important" Trainers.
GUI.tpConsumableItemsOnlyCheckBox.text=Consumable Only
GUI.tpConsumableItemsOnlyCheckBox.tooltip=<html>Items will be chosen randomly from all single-use held items that a Pokemon can eat/use on its own.<br />This is mostly berries, with a few other items like Focus Sash and White Herb.</html>
GUI.tpSensibleItemsCheckBox.text=Sensible Items
GUI.tpSensibleItemsCheckBox.tooltip=<html><b>Not implemented yet.</b><br />Items will be chosen randomly from a subset of the held items that "make sense" for a given Pokemon.<br />For example, Silk Scarf won't be an option for a given Pokemon unless it knows at least one normal move.<br />Another example is that a Yache berry will only be an option on Pokemon that are weak or double weak to ice.</html>
GUI.tpHighestLevelGetsItemCheckBox.text=Highest Level Only
GUI.tpHighestLevelGetsItemCheckBox.tooltip=<html>If this option is selected, a held item will be given only to a trainer's highest level Pokemon (or one of them, if there are multiple at that level).<br />If this is unchecked, all of a Trainer's Pokemon will be given items.</html>

View File

@ -2,7 +2,7 @@
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.dabomstew.pkrandom.newgui.NewRandomizerGUI">
<grid id="27dc6" binding="mainPanel" layout-manager="GridBagLayout">
<constraints>
<xy x="7" y="20" width="1084" height="816"/>
<xy x="7" y="20" width="1084" height="831"/>
</constraints>
<properties/>
<border type="none">
@ -1492,7 +1492,7 @@
<children>
<component id="ddab7" class="javax.swing.JRadioButton" binding="tpUnchangedRadioButton" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.1" weighty="0.0"/>
</constraints>
<properties>
@ -1501,12 +1501,6 @@
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpUnchangedRadioButton.toolTipText"/>
</properties>
</component>
<vspacer id="2342a">
<constraints>
<grid row="11" column="1" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
</vspacer>
<hspacer id="b875b">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
@ -1521,7 +1515,7 @@
</vspacer>
<component id="2fe72" class="javax.swing.JRadioButton" binding="tpRandomRadioButton" default-binding="true">
<constraints>
<grid row="2" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="2" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1532,7 +1526,7 @@
</component>
<component id="cd865" class="javax.swing.JRadioButton" binding="tpRandomEvenDistributionRadioButton" default-binding="true">
<constraints>
<grid row="4" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="4" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1543,7 +1537,7 @@
</component>
<component id="bd6d2" class="javax.swing.JRadioButton" binding="tpRandomEvenDistributionMainRadioButton">
<constraints>
<grid row="5" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="5" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1554,7 +1548,7 @@
</component>
<component id="c6902" class="javax.swing.JCheckBox" binding="tpRivalCarriesStarterCheckBox">
<constraints>
<grid row="1" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.1" weighty="0.0"/>
</constraints>
<properties>
@ -1565,7 +1559,7 @@
</component>
<component id="22cfb" class="javax.swing.JCheckBox" binding="tpSimilarStrengthCheckBox">
<constraints>
<grid row="2" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="2" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1576,7 +1570,7 @@
</component>
<component id="e225c" class="javax.swing.JCheckBox" binding="tpRandomizeTrainerNamesCheckBox">
<constraints>
<grid row="1" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="6" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.1" weighty="0.0"/>
</constraints>
<properties>
@ -1587,7 +1581,7 @@
</component>
<component id="16a2b" class="javax.swing.JCheckBox" binding="tpRandomizeTrainerClassNamesCheckBox">
<constraints>
<grid row="2" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="2" column="6" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1598,7 +1592,7 @@
</component>
<component id="d6ea3" class="javax.swing.JCheckBox" binding="tpForceFullyEvolvedAtCheckBox">
<constraints>
<grid row="4" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="4" column="6" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1609,7 +1603,7 @@
</component>
<component id="63823" class="javax.swing.JSlider" binding="tpForceFullyEvolvedAtSlider">
<constraints>
<grid row="5" column="5" row-span="2" col-span="1" vsize-policy="0" hsize-policy="6" anchor="9" fill="1" indent="0" use-parent-layout="false"/>
<grid row="5" column="6" row-span="2" col-span="1" vsize-policy="0" hsize-policy="6" anchor="9" fill="1" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1627,7 +1621,7 @@
</component>
<component id="670de" class="javax.swing.JSlider" binding="tpPercentageLevelModifierSlider" default-binding="true">
<constraints>
<grid row="8" column="5" row-span="2" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
<grid row="8" column="6" row-span="2" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1645,7 +1639,7 @@
</component>
<component id="8428b" class="javax.swing.JCheckBox" binding="tpPercentageLevelModifierCheckBox" default-binding="true">
<constraints>
<grid row="7" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="7" column="6" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1656,13 +1650,13 @@
</component>
<hspacer id="41124">
<constraints>
<grid row="0" column="6" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="7" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
</hspacer>
<component id="40ee1" class="javax.swing.JRadioButton" binding="tpTypeThemedRadioButton">
<constraints>
<grid row="3" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="3" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1673,7 +1667,7 @@
</component>
<component id="5ff08" class="javax.swing.JCheckBox" binding="tpWeightTypesCheckBox">
<constraints>
<grid row="3" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="3" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1684,7 +1678,7 @@
</component>
<component id="acf1a" class="javax.swing.JCheckBox" binding="tpDontUseLegendariesCheckBox" default-binding="true">
<constraints>
<grid row="4" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="4" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1694,7 +1688,7 @@
</component>
<component id="d0471" class="javax.swing.JCheckBox" binding="tpNoEarlyWonderGuardCheckBox">
<constraints>
<grid row="5" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="5" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1705,7 +1699,7 @@
</component>
<component id="be65d" class="javax.swing.JCheckBox" binding="tpAllowAlternateFormesCheckBox">
<constraints>
<grid row="6" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="6" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1716,7 +1710,7 @@
</component>
<component id="af4d1" class="javax.swing.JCheckBox" binding="tpSwapMegaEvosCheckBox">
<constraints>
<grid row="7" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="7" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1727,7 +1721,7 @@
</component>
<component id="feec4" class="javax.swing.JCheckBox" binding="tpDoubleBattleModeCheckBox">
<constraints>
<grid row="7" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="7" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1738,7 +1732,7 @@
</component>
<component id="b62cd" class="javax.swing.JLabel" binding="tpAdditionalPokemonForLabel">
<constraints>
<grid row="8" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="10" fill="0" indent="0" use-parent-layout="false"/>
<grid row="8" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="0" anchor="10" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1747,7 +1741,7 @@
</component>
<component id="8f956" class="javax.swing.JCheckBox" binding="tpBossTrainersCheckBox">
<constraints>
<grid row="9" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="9" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1758,7 +1752,7 @@
</component>
<component id="6d5aa" class="javax.swing.JCheckBox" binding="tpImportantTrainersCheckBox">
<constraints>
<grid row="9" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="9" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1769,7 +1763,7 @@
</component>
<component id="39903" class="javax.swing.JCheckBox" binding="tpRegularTrainersCheckBox">
<constraints>
<grid row="9" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="9" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1780,7 +1774,7 @@
</component>
<component id="181e" class="javax.swing.JSpinner" binding="tpBossTrainersSpinner">
<constraints>
<grid row="10" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="10" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag top="0" left="4" bottom="0" right="0" weightx="0.0" weighty="0.0" ipadx="10"/>
</constraints>
<properties>
@ -1789,7 +1783,7 @@
</component>
<component id="e7a99" class="javax.swing.JSpinner" binding="tpImportantTrainersSpinner">
<constraints>
<grid row="10" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="10" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag top="0" left="4" bottom="0" right="0" weightx="0.0" weighty="0.0" ipadx="10"/>
</constraints>
<properties>
@ -1798,7 +1792,7 @@
</component>
<component id="da8e4" class="javax.swing.JSpinner" binding="tpRegularTrainersSpinner">
<constraints>
<grid row="10" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="10" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag top="0" left="4" bottom="0" right="0" weightx="0.0" weighty="0.0" ipadx="10"/>
</constraints>
<properties>
@ -1807,7 +1801,7 @@
</component>
<component id="34a10" class="javax.swing.JCheckBox" binding="tpRandomShinyTrainerPokemonCheckBox">
<constraints>
<grid row="8" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
<grid row="8" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
@ -1816,6 +1810,87 @@
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpRandomShinyTrainerPokemonCheckBox.toolTipText"/>
</properties>
</component>
<component id="2918f" class="javax.swing.JLabel" binding="tpHeldItemsLabel">
<constraints>
<grid row="11" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<text resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpHeldItemsLabel.text"/>
</properties>
</component>
<component id="dad16" class="javax.swing.JCheckBox" binding="tpBossTrainersItemsCheckBox">
<constraints>
<grid row="12" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<enabled value="false"/>
<text resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpBossTrainersItemsCheckBox.text"/>
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpBossTrainersItemsCheckBox.toolTipText"/>
</properties>
</component>
<component id="d7d93" class="javax.swing.JCheckBox" binding="tpImportantTrainersItemsCheckBox">
<constraints>
<grid row="12" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<enabled value="false"/>
<text resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpImportantTrainersItemsCheckBox.text"/>
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpImportantTrainersItemsCheckBox.toolTipText"/>
</properties>
</component>
<component id="7fddd" class="javax.swing.JCheckBox" binding="tpRegularTrainersItemsCheckBox">
<constraints>
<grid row="12" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<enabled value="false"/>
<text resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpRegularTrainersItemsCheckBox.text"/>
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpRegularTrainersItemsCheckBox.toolTipText"/>
</properties>
</component>
<component id="31e9a" class="javax.swing.JCheckBox" binding="tpConsumableItemsOnlyCheckBox">
<constraints>
<grid row="13" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<enabled value="false"/>
<text resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpConsumableItemsOnlyCheckBox.text"/>
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpConsumableItemsOnlyCheckBox.tooltip"/>
</properties>
</component>
<component id="79d6a" class="javax.swing.JCheckBox" binding="tpSensibleItemsCheckBox">
<constraints>
<grid row="13" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<enabled value="false"/>
<text resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpSensibleItemsCheckBox.text"/>
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpSensibleItemsCheckBox.tooltip"/>
</properties>
</component>
<component id="f3c52" class="javax.swing.JCheckBox" binding="tpHighestLevelGetsItemCheckBox">
<constraints>
<grid row="13" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<enabled value="false"/>
<text resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpHighestLevelGetsItemCheckBox.text"/>
<toolTipText resource-bundle="com/dabomstew/pkrandom/newgui/Bundle" key="GUI.tpHighestLevelGetsItemCheckBox.tooltip"/>
</properties>
</component>
<vspacer id="2342a">
<constraints>
<grid row="14" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
</vspacer>
</children>
</grid>
<hspacer id="66d2">

View File

@ -281,6 +281,13 @@ public class NewRandomizerGUI {
private JSlider stpPercentageLevelModifierSlider;
private JCheckBox stpFixMusicCheckBox;
private JCheckBox miscFasterHPAndEXPBarsCheckBox;
private JCheckBox tpBossTrainersItemsCheckBox;
private JCheckBox tpImportantTrainersItemsCheckBox;
private JCheckBox tpRegularTrainersItemsCheckBox;
private JLabel tpHeldItemsLabel;
private JCheckBox tpConsumableItemsOnlyCheckBox;
private JCheckBox tpSensibleItemsCheckBox;
private JCheckBox tpHighestLevelGetsItemCheckBox;
private static JFrame frame;
@ -491,6 +498,9 @@ public class NewRandomizerGUI {
tpBossTrainersCheckBox.addActionListener(e -> enableOrDisableSubControls());
tpImportantTrainersCheckBox.addActionListener(e -> enableOrDisableSubControls());
tpRegularTrainersCheckBox.addActionListener(e -> enableOrDisableSubControls());
tpBossTrainersItemsCheckBox.addActionListener(e -> enableOrDisableSubControls());
tpImportantTrainersItemsCheckBox.addActionListener(e -> enableOrDisableSubControls());
tpRegularTrainersItemsCheckBox.addActionListener(e -> enableOrDisableSubControls());
totpUnchangedRadioButton.addActionListener(e -> enableOrDisableSubControls());
totpRandomRadioButton.addActionListener(e -> enableOrDisableSubControls());
totpRandomSimilarStrengthRadioButton.addActionListener(e -> enableOrDisableSubControls());
@ -1362,6 +1372,13 @@ public class NewRandomizerGUI {
tpImportantTrainersSpinner.setValue(settings.getAdditionalImportantTrainerPokemon() > 0 ? settings.getAdditionalImportantTrainerPokemon() : 1);
tpRegularTrainersCheckBox.setSelected(settings.getAdditionalRegularTrainerPokemon() > 0);
tpRegularTrainersSpinner.setValue(settings.getAdditionalRegularTrainerPokemon() > 0 ? settings.getAdditionalRegularTrainerPokemon() : 1);
tpBossTrainersItemsCheckBox.setSelected(settings.isRandomizeHeldItemsForBossTrainerPokemon());
tpImportantTrainersItemsCheckBox.setSelected(settings.isRandomizeHeldItemsForImportantTrainerPokemon());
tpRegularTrainersItemsCheckBox.setSelected(settings.isRandomizeHeldItemsForRegularTrainerPokemon());
tpConsumableItemsOnlyCheckBox.setSelected(settings.isConsumableItemsOnlyForTrainers());
tpSensibleItemsCheckBox.setSelected(settings.isSensibleItemsOnlyForTrainers());
tpHighestLevelGetsItemCheckBox.setSelected(settings.isHighestLevelGetsItemsForTrainers());
tpRandomShinyTrainerPokemonCheckBox.setSelected(settings.isShinyChance());
totpUnchangedRadioButton.setSelected(settings.getTotemPokemonMod() == Settings.TotemPokemonMod.UNCHANGED);
@ -1581,6 +1598,12 @@ public class NewRandomizerGUI {
settings.setAdditionalImportantTrainerPokemon(tpImportantTrainersCheckBox.isVisible() && tpImportantTrainersCheckBox.isSelected() ? (int)tpImportantTrainersSpinner.getValue() : 0);
settings.setAdditionalRegularTrainerPokemon(tpRegularTrainersCheckBox.isVisible() && tpRegularTrainersCheckBox.isSelected() ? (int)tpRegularTrainersSpinner.getValue() : 0);
settings.setShinyChance(tpRandomShinyTrainerPokemonCheckBox.isVisible() && tpRandomShinyTrainerPokemonCheckBox.isSelected());
settings.setRandomizeHeldItemsForBossTrainerPokemon(tpBossTrainersItemsCheckBox.isVisible() && tpBossTrainersItemsCheckBox.isSelected());
settings.setRandomizeHeldItemsForImportantTrainerPokemon(tpImportantTrainersItemsCheckBox.isVisible() && tpImportantTrainersItemsCheckBox.isSelected());
settings.setRandomizeHeldItemsForRegularTrainerPokemon(tpRegularTrainersItemsCheckBox.isVisible() && tpRegularTrainersItemsCheckBox.isSelected());
settings.setConsumableItemsOnlyForTrainers(tpConsumableItemsOnlyCheckBox.isVisible() && tpConsumableItemsOnlyCheckBox.isSelected());
settings.setSensibleItemsOnlyForTrainers(tpSensibleItemsCheckBox.isVisible() && tpSensibleItemsCheckBox.isSelected());
settings.setHighestLevelGetsItemsForTrainers(tpHighestLevelGetsItemCheckBox.isVisible() && tpHighestLevelGetsItemCheckBox.isSelected());
settings.setTotemPokemonMod(totpUnchangedRadioButton.isSelected(), totpRandomRadioButton.isSelected(), totpRandomSimilarStrengthRadioButton.isSelected());
settings.setAllyPokemonMod(totpAllyUnchangedRadioButton.isSelected(), totpAllyRandomRadioButton.isSelected(), totpAllyRandomSimilarStrengthRadioButton.isSelected());
@ -2120,6 +2143,25 @@ public class NewRandomizerGUI {
tpRegularTrainersSpinner.setEnabled(false);
tpRegularTrainersSpinner.setValue(1);
tpAdditionalPokemonForLabel.setVisible(true);
tpHeldItemsLabel.setVisible(true);
tpBossTrainersItemsCheckBox.setVisible(true);
tpBossTrainersItemsCheckBox.setEnabled(false);
tpBossTrainersItemsCheckBox.setSelected(false);
tpImportantTrainersItemsCheckBox.setVisible(true);
tpImportantTrainersItemsCheckBox.setEnabled(false);
tpImportantTrainersItemsCheckBox.setSelected(false);
tpRegularTrainersItemsCheckBox.setVisible(true);
tpRegularTrainersItemsCheckBox.setEnabled(false);
tpRegularTrainersItemsCheckBox.setSelected(false);
tpConsumableItemsOnlyCheckBox.setVisible(true);
tpConsumableItemsOnlyCheckBox.setEnabled(false);
tpConsumableItemsOnlyCheckBox.setSelected(false);
tpSensibleItemsCheckBox.setVisible(true);
tpSensibleItemsCheckBox.setEnabled(false);
tpSensibleItemsCheckBox.setSelected(false);
tpHighestLevelGetsItemCheckBox.setVisible(true);
tpHighestLevelGetsItemCheckBox.setEnabled(false);
tpHighestLevelGetsItemCheckBox.setSelected(false);
tpRandomShinyTrainerPokemonCheckBox.setVisible(true);
tpRandomShinyTrainerPokemonCheckBox.setEnabled(false);
totpPanel.setVisible(true);
@ -2584,6 +2626,21 @@ public class NewRandomizerGUI {
tpRegularTrainersCheckBox.setEnabled(false);
tpRegularTrainersSpinner.setVisible(additionalPokemonAvailable);
boolean trainersHeldItemSupport = pokemonGeneration >= 3;
tpHeldItemsLabel.setVisible(trainersHeldItemSupport);
tpBossTrainersItemsCheckBox.setVisible(trainersHeldItemSupport);
tpBossTrainersItemsCheckBox.setEnabled(false);
tpImportantTrainersItemsCheckBox.setVisible(trainersHeldItemSupport);
tpImportantTrainersItemsCheckBox.setEnabled(false);
tpRegularTrainersItemsCheckBox.setVisible(trainersHeldItemSupport);
tpRegularTrainersItemsCheckBox.setEnabled(false);
tpConsumableItemsOnlyCheckBox.setVisible(trainersHeldItemSupport);
tpConsumableItemsOnlyCheckBox.setEnabled(false);
tpSensibleItemsCheckBox.setVisible(trainersHeldItemSupport);
tpSensibleItemsCheckBox.setEnabled(false);
tpHighestLevelGetsItemCheckBox.setVisible(trainersHeldItemSupport);
tpHighestLevelGetsItemCheckBox.setEnabled(false);
tpRandomizeTrainerNamesCheckBox.setEnabled(true);
tpRandomizeTrainerClassNamesCheckBox.setEnabled(true);
tpNoEarlyWonderGuardCheckBox.setVisible(pokemonGeneration >= 3);
@ -2956,6 +3013,18 @@ public class NewRandomizerGUI {
tpImportantTrainersCheckBox.setSelected(false);
tpRegularTrainersCheckBox.setEnabled(false);
tpRegularTrainersCheckBox.setSelected(false);
tpBossTrainersItemsCheckBox.setEnabled(false);
tpBossTrainersItemsCheckBox.setSelected(false);
tpImportantTrainersItemsCheckBox.setEnabled(false);
tpImportantTrainersItemsCheckBox.setSelected(false);
tpRegularTrainersItemsCheckBox.setEnabled(false);
tpRegularTrainersItemsCheckBox.setSelected(false);
tpConsumableItemsOnlyCheckBox.setEnabled(false);
tpConsumableItemsOnlyCheckBox.setSelected(false);
tpSensibleItemsCheckBox.setEnabled(false);
tpSensibleItemsCheckBox.setSelected(false);
tpHighestLevelGetsItemCheckBox.setEnabled(false);
tpHighestLevelGetsItemCheckBox.setSelected(false);
} else {
tpSimilarStrengthCheckBox.setEnabled(true);
tpDontUseLegendariesCheckBox.setEnabled(true);
@ -2971,6 +3040,9 @@ public class NewRandomizerGUI {
tpBossTrainersCheckBox.setEnabled(tpBossTrainersCheckBox.isVisible());
tpImportantTrainersCheckBox.setEnabled(tpImportantTrainersCheckBox.isVisible());
tpRegularTrainersCheckBox.setEnabled(tpRegularTrainersCheckBox.isVisible());
tpBossTrainersItemsCheckBox.setEnabled(tpBossTrainersItemsCheckBox.isVisible());
tpImportantTrainersItemsCheckBox.setEnabled(tpImportantTrainersItemsCheckBox.isVisible());
tpRegularTrainersItemsCheckBox.setEnabled(tpRegularTrainersItemsCheckBox.isVisible());
}
if (tpForceFullyEvolvedAtCheckBox.isSelected()) {
@ -3008,6 +3080,17 @@ public class NewRandomizerGUI {
tpRegularTrainersSpinner.setValue(1);
}
if (tpBossTrainersItemsCheckBox.isSelected() || tpImportantTrainersItemsCheckBox.isSelected() ||
tpRegularTrainersItemsCheckBox.isSelected()) {
tpConsumableItemsOnlyCheckBox.setEnabled(true);
tpSensibleItemsCheckBox.setEnabled(false); // not implemented yet
tpHighestLevelGetsItemCheckBox.setEnabled(true);
} else {
tpConsumableItemsOnlyCheckBox.setEnabled(false);
tpSensibleItemsCheckBox.setEnabled(false);
tpHighestLevelGetsItemCheckBox.setEnabled(false);
}
if (!spUnchangedRadioButton.isSelected() || !this.tpUnchangedRadioButton.isSelected()) {
tpRivalCarriesStarterCheckBox.setEnabled(true);
} else {

View File

@ -44,6 +44,7 @@ public class TotemPokemon extends StaticEncounter {
@Override
public String toString() {
// The %s will be formatted to include the held item.
String ret = pkmn.fullName() + "@%s Lv" + level + "\n Aura: " + aura.toString() + "\n";
int i = 1;
for (StaticEncounter ally: allies.values()) {

View File

@ -32,6 +32,7 @@ public class Trainer implements Comparable<Trainer> {
public List<TrainerPokemon> pokemon = new ArrayList<>();
public String tag;
public boolean importantTrainer;
// This value has some flags about the trainer's pokemon (e.g. if they have items or custom moves)
public int poketype;
public String name;
public int trainerclass;
@ -103,4 +104,23 @@ public class Trainer implements Comparable<Trainer> {
public boolean skipImportant() {
return ((tag != null) && (tag.startsWith("RIVAL1-") || tag.startsWith("FRIEND1-") || tag.endsWith("NOTSTRONG")));
}
public void setPokemonHaveItems(boolean haveItems) {
if (haveItems) {
this.poketype |= 2;
} else {
// https://stackoverflow.com/a/1073328
this.poketype = poketype & ~2;
}
}
public boolean pokemonHaveItems() {
// This flag seems consistent for all gens
return (this.poketype & 2) == 2;
}
public boolean pokemonHaveCustomMoves() {
// This flag seems consistent for all gens
return (this.poketype & 1) == 1;
}
}

View File

@ -36,6 +36,8 @@ public class TrainerPokemon {
public int AILevel;
public int heldItem = 0;
public boolean hasMegaStone;
public boolean hasZCrystal;
public int ability;
public int forme;
public String formeSuffix = "";
@ -54,7 +56,13 @@ public class TrainerPokemon {
public boolean resetMoves = false;
public String toString() {
return pokemon.name + formeSuffix + " Lv" + level;
String s = pokemon.name + formeSuffix;
if (heldItem != 0) {
// This can be filled in with the actual name when written to the log.
s += "@%s";
}
s+= " Lv" + level;
return s;
}
public boolean canMegaEvolve() {

View File

@ -31,7 +31,6 @@ package com.dabomstew.pkrandom.romhandlers;
import java.io.PrintStream;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import com.dabomstew.pkrandom.*;
import com.dabomstew.pkrandom.constants.*;
@ -1925,6 +1924,67 @@ public abstract class AbstractRomHandler implements RomHandler {
this.setTrainers(currentTrainers, false);
}
@Override
public void randomizeTrainerHeldItems(Settings settings) {
boolean giveToBossPokemon = settings.isRandomizeHeldItemsForBossTrainerPokemon();
boolean giveToImportantPokemon = settings.isRandomizeHeldItemsForBossTrainerPokemon();
boolean giveToRegularPokemon = settings.isRandomizeHeldItemsForBossTrainerPokemon();
boolean highestLevelOnly = settings.isHighestLevelGetsItemsForTrainers();
List<Trainer> currentTrainers = this.getTrainers();
for (Trainer t : currentTrainers) {
if (!giveToRegularPokemon && (!t.isImportant() && !t.isBoss())) {
continue;
}
if (!giveToImportantPokemon && t.isImportant()) {
continue;
}
if (!giveToBossPokemon && t.isBoss()) {
continue;
}
t.setPokemonHaveItems(true);
if (highestLevelOnly) {
int maxLevel = -1;
TrainerPokemon highestLevelPoke = null;
for (TrainerPokemon tp : t.pokemon) {
if (tp.level > maxLevel) {
highestLevelPoke = tp;
maxLevel = tp.level;
}
}
if (highestLevelPoke == null) {
continue; // should never happen - trainer had zero pokes
}
randomizeHeldItem(highestLevelPoke, settings);
} else {
for (TrainerPokemon tp : t.pokemon) {
randomizeHeldItem(tp, settings);
}
}
}
this.setTrainers(currentTrainers, false);
}
private void randomizeHeldItem(TrainerPokemon tp, Settings settings) {
boolean sensibleItemsOnly = settings.isSensibleItemsOnlyForTrainers();
boolean consumableItemsOnly = settings.isConsumableItemsOnlyForTrainers();
boolean swapMegaEvolutions = settings.isSwapTrainerMegaEvos()
if (tp.hasZCrystal) {
return; // Don't overwrite existing Z Crystals.
}
if (tp.hasMegaStone && swapMegaEvolutions) {
return; // Don't overwrite mega stones if another setting handled that.
}
List<Integer> toChooseFrom;
if (sensibleItemsOnly) {
toChooseFrom = getSensibleHeldItemsFor(tp, consumableItemsOnly);
} else if (consumableItemsOnly) {
toChooseFrom = getAllConsumableHeldItems();
} else {
toChooseFrom = getAllHeldItems();
}
tp.heldItem = toChooseFrom.get(random.nextInt(toChooseFrom.size()));
}
@Override
public void rivalCarriesStarter() {
checkPokemonRestrictions();
@ -5759,7 +5819,8 @@ public abstract class AbstractRomHandler implements RomHandler {
if (randomizeHeldItems) {
if (old.heldItem != 0) {
newTotem.heldItem = randomHeldItem();
List<Integer> consumableList = getAllConsumableHeldItems();
newTotem.heldItem = consumableList.get(this.random.nextInt(consumableList.size()));
}
}
@ -6002,7 +6063,7 @@ public abstract class AbstractRomHandler implements RomHandler {
@Override
public List<Integer> getGameBreakingMoves() {
// Sonicboom & drage
// Sonicboom & Dragon Rage
return Arrays.asList(49, 82);
}
@ -6054,4 +6115,19 @@ public abstract class AbstractRomHandler implements RomHandler {
public void applyMiscTweak(MiscTweak tweak) {
// default: do nothing
}
@Override
public List<Integer> getSensibleHeldItemsFor(TrainerPokemon tp, boolean consumableOnly) {
return Arrays.asList(0);
}
@Override
public List<Integer> getAllConsumableHeldItems() {
return Arrays.asList(0);
}
@Override
public List<Integer> getAllHeldItems() {
return Arrays.asList(0);
}
}

View File

@ -1565,11 +1565,6 @@ public class Gen1RomHandler extends AbstractGBCRomHandler {
return new ArrayList<>();
}
@Override
public int randomHeldItem() {
return 0;
}
private List<String> getTrainerClassesForText() {
int[] offsets = romEntry.arrayEntries.get("TrainerClassNamesOffsets");
List<String> tcNames = new ArrayList<>();

View File

@ -935,11 +935,11 @@ public class Gen2RomHandler extends AbstractGBCRomHandler {
rom[offs] = (byte) tp.level;
rom[offs + 1] = (byte) tp.pokemon.number;
offs += 2;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
rom[offs] = (byte) tp.heldItem;
offs++;
}
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
if (tp.resetMoves) {
int[] pokeMoves = RomFunctions.getMovesAtLevel(tp.pokemon.number, movesets, tp.level);
for (int m = 0; m < 4; m++) {
@ -1546,11 +1546,6 @@ public class Gen2RomHandler extends AbstractGBCRomHandler {
return new ArrayList<>();
}
@Override
public int randomHeldItem() {
return 0;
}
@Override
public boolean canChangeTrainerText() {
return romEntry.getValue("CanChangeTrainerText") > 0;

View File

@ -1501,7 +1501,7 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
Iterator<TrainerPokemon> pokes = tr.pokemon.iterator();
// Write out Pokemon data!
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
// custom moves, blocks of 16 bytes
for (int poke = 0; poke < newPokeCount; poke++) {
TrainerPokemon tp = pokes.next();
@ -1509,7 +1509,7 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
writeWord(pointerToPokes + poke * 16 + 2, tp.level);
writeWord(pointerToPokes + poke * 16 + 4, pokedexToInternal[tp.pokemon.number]);
int movesStart;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
writeWord(pointerToPokes + poke * 16 + 6, tp.heldItem);
movesStart = 8;
} else {
@ -1535,7 +1535,7 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
writeWord(pointerToPokes + poke * 8, tp.AILevel);
writeWord(pointerToPokes + poke * 8 + 2, tp.level);
writeWord(pointerToPokes + poke * 8 + 4, pokedexToInternal[tp.pokemon.number]);
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
writeWord(pointerToPokes + poke * 8 + 6, tp.heldItem);
} else {
writeWord(pointerToPokes + poke * 8 + 6, 0);
@ -2472,11 +2472,6 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
return new ArrayList<>();
}
@Override
public int randomHeldItem() {
return 0;
}
@Override
public boolean canChangeTrainerText() {
return true;
@ -3326,4 +3321,14 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
// Make image, 4bpp
return GFXFunctions.drawTiledImage(trueFrontSprite, convPalette, 64, 64, 4);
}
@Override
public List<Integer> getAllHeldItems() {
return Gen3Constants.allHeldItems;
}
@Override
public List<Integer> getAllConsumableHeldItems() {
return Gen3Constants.consumableHeldItems;
}
}

View File

@ -2104,11 +2104,11 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
tpk.formeSuffix = Gen4Constants.getFormeSuffixByBaseForme(species,formnum);
tpk.absolutePokeNumber = Gen4Constants.getAbsolutePokeNumByBaseForme(species,formnum);
pokeOffs += 6;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
tpk.heldItem = readWord(trpoke, pokeOffs);
pokeOffs += 2;
}
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
int attack1 = readWord(trpoke, pokeOffs);
int attack2 = readWord(trpoke, pokeOffs + 2);
int attack3 = readWord(trpoke, pokeOffs + 4);
@ -2194,10 +2194,10 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
if (romEntry.romType != Gen4Constants.Type_DP) {
bytesNeeded += 2 * numPokes;
}
if ((tr.poketype & 1) == 1) {
bytesNeeded += 8 * numPokes;
if (tr.pokemonHaveCustomMoves()) {
bytesNeeded += 8 * numPokes; // 2 bytes * 4 moves
}
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
bytesNeeded += 2 * numPokes;
}
byte[] trpoke = new byte[bytesNeeded];
@ -2210,11 +2210,11 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
writeWord(trpoke, pokeOffs + 4, tp.pokemon.number);
trpoke[pokeOffs + 5] |= (tp.forme << 2);
pokeOffs += 6;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
writeWord(trpoke, pokeOffs, tp.heldItem);
pokeOffs += 2;
}
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
if (tp.resetMoves) {
int[] pokeMoves = RomFunctions.getMovesAtLevel(tp.absolutePokeNumber, movesets, tp.level);
for (int m = 0; m < 4; m++) {
@ -3401,11 +3401,6 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
.collect(Collectors.toList());
}
@Override
public int randomHeldItem() {
return 0;
}
@Override
public boolean canChangeTrainerText() {
return true;
@ -4243,4 +4238,14 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
throw new RandomizerIOException(e);
}
}
@Override
public List<Integer> getAllConsumableHeldItems() {
return Gen4Constants.consumableHeldItems;
}
@Override
public List<Integer> getAllHeldItems() {
return Gen4Constants.allHeldItems;
}
}

View File

@ -1228,11 +1228,11 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
tpk.formeSuffix = Gen5Constants.getFormeSuffixByBaseForme(species,formnum);
tpk.absolutePokeNumber = Gen5Constants.getAbsolutePokeNumByBaseForme(species,formnum);
pokeOffs += 8;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
tpk.heldItem = readWord(trpoke, pokeOffs);
pokeOffs += 2;
}
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
int attack1 = readWord(trpoke, pokeOffs);
int attack2 = readWord(trpoke, pokeOffs + 2);
int attack3 = readWord(trpoke, pokeOffs + 4);
@ -1256,7 +1256,7 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
int currentFile = 1;
for (int trno = 0; trno < 17; trno++) {
Trainer tr = new Trainer();
tr.poketype = 3;
tr.poketype = 3; // have held items and custom moves
tr.offset = 0;
int pokemonNum = 6;
if (trno < 2) {
@ -1340,10 +1340,10 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
}
int bytesNeeded = 8 * numPokes;
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
bytesNeeded += 8 * numPokes;
}
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
bytesNeeded += 2 * numPokes;
}
byte[] trpoke = new byte[bytesNeeded];
@ -1358,11 +1358,11 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
writeWord(trpoke, pokeOffs + 6, tp.forme);
// no form info, so no byte 6/7
pokeOffs += 8;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
writeWord(trpoke, pokeOffs, tp.heldItem);
pokeOffs += 2;
}
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
if (tp.resetMoves) {
int[] pokeMoves = RomFunctions.getMovesAtLevel(tp.absolutePokeNumber, movesets, tp.level);
for (int m = 0; m < 4; m++) {
@ -3354,11 +3354,6 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
return Gen5Constants.getMainGameShops(romEntry.romType);
}
@Override
public int randomHeldItem() {
return 0;
}
@Override
public BufferedImage getMascotImage() {
try {
@ -3408,4 +3403,14 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
throw new RandomizerIOException(e);
}
}
@Override
public List<Integer> getAllHeldItems() {
return Gen5Constants.allHeldItems;
}
@Override
public List<Integer> getAllConsumableHeldItems() {
return Gen5Constants.consumableHeldItems;
}
}

View File

@ -1733,11 +1733,12 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
.getOrDefault(species,dummyAbsolutePokeNums)
.getOrDefault(formnum,species);
pokeOffs += 8;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
tpk.heldItem = readWord(trpoke, pokeOffs);
pokeOffs += 2;
tpk.hasMegaStone = Gen6Constants.isMegaStone(tpk.heldItem);
}
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
int attack1 = readWord(trpoke, pokeOffs);
int attack2 = readWord(trpoke, pokeOffs + 2);
int attack3 = readWord(trpoke, pokeOffs + 4);
@ -1810,10 +1811,10 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
}
int bytesNeeded = 8 * numPokes;
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
bytesNeeded += 8 * numPokes;
}
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
bytesNeeded += 2 * numPokes;
}
byte[] trpoke = new byte[bytesNeeded];
@ -1827,11 +1828,11 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
writeWord(trpoke, pokeOffs + 4, tp.pokemon.number);
writeWord(trpoke, pokeOffs + 6, tp.forme);
pokeOffs += 8;
if ((tr.poketype & 2) == 2) {
if (tr.pokemonHaveItems()) {
writeWord(trpoke, pokeOffs, tp.heldItem);
pokeOffs += 2;
}
if ((tr.poketype & 1) == 1) {
if (tr.pokemonHaveCustomMoves()) {
if (tp.resetMoves) {
int[] pokeMoves = RomFunctions.getMovesAtLevel(tp.absolutePokeNumber, movesets, tp.level);
for (int m = 0; m < 4; m++) {
@ -3443,11 +3444,6 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
return Gen6Constants.getMainGameShops(romEntry.romType);
}
@Override
public int randomHeldItem() {
return 0;
}
@Override
public BufferedImage getMascotImage() {
try {
@ -3495,4 +3491,14 @@ public class Gen6RomHandler extends Abstract3DSRomHandler {
throw new RandomizerIOException(e);
}
}
@Override
public List<Integer> getAllHeldItems() {
return Gen6Constants.allHeldItems;
}
@Override
public List<Integer> getAllConsumableHeldItems() {
return Gen6Constants.consumableHeldItems;
}
}

View File

@ -27,6 +27,7 @@ import com.dabomstew.pkrandom.FileFunctions;
import com.dabomstew.pkrandom.MiscTweak;
import com.dabomstew.pkrandom.RomFunctions;
import com.dabomstew.pkrandom.Settings;
import com.dabomstew.pkrandom.constants.Gen6Constants;
import com.dabomstew.pkrandom.constants.Gen7Constants;
import com.dabomstew.pkrandom.constants.GlobalConstants;
import com.dabomstew.pkrandom.constants.Species;
@ -1497,6 +1498,8 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
.getOrDefault(formnum,species);
pokeOffs += 20;
tpk.heldItem = readWord(trpoke, pokeOffs);
tpk.hasMegaStone = Gen6Constants.isMegaStone(tpk.heldItem);
tpk.hasZCrystal = Gen7Constants.isZCrystal(tpk.heldItem);
pokeOffs += 4;
int attack1 = readWord(trpoke, pokeOffs);
int attack2 = readWord(trpoke, pokeOffs + 2);
@ -3138,11 +3141,6 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
return Gen7Constants.getMainGameShops(romEntry.romType);
}
@Override
public int randomHeldItem() {
return Gen7Constants.validConsumableHeldItems.get(this.random.nextInt(Gen7Constants.validConsumableHeldItems.size()));
}
@Override
public BufferedImage getMascotImage() {
try {
@ -3188,4 +3186,14 @@ public class Gen7RomHandler extends Abstract3DSRomHandler {
encounterTables = new ArrayList<>();
}
}
@Override
public List<Integer> getAllConsumableHeldItems() {
return Gen7Constants.consumableHeldItems;
}
@Override
public List<Integer> getAllHeldItems() {
return Gen7Constants.allHeldItems;
}
}

View File

@ -201,6 +201,14 @@ public interface RomHandler {
void typeThemeTrainerPokes(Settings settings);
void randomizeTrainerHeldItems(Settings settings);
List<Integer> getSensibleHeldItemsFor(TrainerPokemon tp, boolean consumableOnly);
List<Integer> getAllConsumableHeldItems();
List<Integer> getAllHeldItems();
void rivalCarriesStarter();
void forceFullyEvolvedTrainerPokes(Settings settings);
@ -495,8 +503,6 @@ public interface RomHandler {
List<Integer> getMainGameShops();
int randomHeldItem();
// stats stuff
void minimumCatchRate(int rateNonLegendary, int rateLegendary);